aboutsummaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-07-28 11:09:23 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-07-28 11:09:23 +0000
commitf73363f1dd94996356cefbf24388f561891acf0b (patch)
treee3c31248bdb36eaec5fd833490d4278162dba2a0 /source
parent160ee69dd7ae18978f4068116777639ea98dc951 (diff)
Notes
Diffstat (limited to 'source')
-rw-r--r--source/API/CMakeLists.txt74
-rw-r--r--source/API/SBAddress.cpp18
-rw-r--r--source/API/SBAttachInfo.cpp9
-rw-r--r--source/API/SBBreakpointName.cpp10
-rw-r--r--source/API/SBCommandInterpreter.cpp21
-rw-r--r--source/API/SBDebugger.cpp70
-rw-r--r--source/API/SBEvent.cpp4
-rw-r--r--source/API/SBFrame.cpp2
-rw-r--r--source/API/SBHostOS.cpp53
-rw-r--r--source/API/SBInstruction.cpp30
-rw-r--r--source/API/SBInstructionList.cpp4
-rw-r--r--source/API/SBLaunchInfo.cpp51
-rw-r--r--source/API/SBModule.cpp63
-rw-r--r--source/API/SBModuleSpec.cpp13
-rw-r--r--source/API/SBPlatform.cpp61
-rw-r--r--source/API/SBProcess.cpp58
-rw-r--r--source/API/SBQueueItem.cpp3
-rw-r--r--source/API/SBStream.cpp9
-rw-r--r--source/API/SBTarget.cpp96
-rw-r--r--source/API/SBThread.cpp248
-rw-r--r--source/API/SBThreadPlan.cpp3
-rw-r--r--source/API/SBType.cpp6
-rw-r--r--source/API/SBTypeCategory.cpp12
-rw-r--r--source/API/SBValue.cpp43
-rw-r--r--source/API/SystemInitializerFull.cpp49
-rw-r--r--source/API/SystemInitializerFull.h38
-rw-r--r--source/Breakpoint/Breakpoint.cpp133
-rw-r--r--source/Breakpoint/BreakpointID.cpp7
-rw-r--r--source/Breakpoint/BreakpointIDList.cpp23
-rw-r--r--source/Breakpoint/BreakpointList.cpp12
-rw-r--r--source/Breakpoint/BreakpointLocation.cpp38
-rw-r--r--source/Breakpoint/BreakpointLocationList.cpp33
-rw-r--r--source/Breakpoint/BreakpointOptions.cpp30
-rw-r--r--source/Breakpoint/BreakpointResolver.cpp10
-rw-r--r--source/Breakpoint/BreakpointResolverAddress.cpp15
-rw-r--r--source/Breakpoint/BreakpointResolverFileLine.cpp67
-rw-r--r--source/Breakpoint/BreakpointResolverName.cpp17
-rw-r--r--source/Breakpoint/BreakpointSiteList.cpp17
-rw-r--r--source/Breakpoint/Watchpoint.cpp16
-rw-r--r--source/Breakpoint/WatchpointList.cpp6
-rw-r--r--source/Breakpoint/WatchpointOptions.cpp3
-rw-r--r--source/Commands/CMakeLists.txt3
-rw-r--r--source/Commands/CommandCompletions.cpp204
-rw-r--r--source/Commands/CommandObjectApropos.cpp6
-rw-r--r--source/Commands/CommandObjectArgs.cpp234
-rw-r--r--source/Commands/CommandObjectArgs.h52
-rw-r--r--source/Commands/CommandObjectBreakpoint.cpp77
-rw-r--r--source/Commands/CommandObjectBreakpointCommand.cpp35
-rw-r--r--source/Commands/CommandObjectCommands.cpp117
-rw-r--r--source/Commands/CommandObjectDisassemble.cpp33
-rw-r--r--source/Commands/CommandObjectExpression.cpp195
-rw-r--r--source/Commands/CommandObjectExpression.h4
-rw-r--r--source/Commands/CommandObjectFrame.cpp57
-rw-r--r--source/Commands/CommandObjectHelp.cpp39
-rw-r--r--source/Commands/CommandObjectHelp.h5
-rw-r--r--source/Commands/CommandObjectLog.cpp7
-rw-r--r--source/Commands/CommandObjectMemory.cpp51
-rw-r--r--source/Commands/CommandObjectMultiword.cpp70
-rw-r--r--source/Commands/CommandObjectPlatform.cpp115
-rw-r--r--source/Commands/CommandObjectPlugin.cpp17
-rw-r--r--source/Commands/CommandObjectProcess.cpp99
-rw-r--r--source/Commands/CommandObjectQuit.cpp45
-rw-r--r--source/Commands/CommandObjectRegister.cpp29
-rw-r--r--source/Commands/CommandObjectSettings.cpp210
-rw-r--r--source/Commands/CommandObjectSource.cpp132
-rw-r--r--source/Commands/CommandObjectStats.cpp107
-rw-r--r--source/Commands/CommandObjectStats.h25
-rw-r--r--source/Commands/CommandObjectSyntax.cpp103
-rw-r--r--source/Commands/CommandObjectSyntax.h37
-rw-r--r--source/Commands/CommandObjectTarget.cpp245
-rw-r--r--source/Commands/CommandObjectThread.cpp83
-rw-r--r--source/Commands/CommandObjectType.cpp87
-rw-r--r--source/Commands/CommandObjectWatchpoint.cpp72
-rw-r--r--source/Commands/CommandObjectWatchpointCommand.cpp36
-rw-r--r--source/Core/Address.cpp103
-rw-r--r--source/Core/AddressResolverName.cpp5
-rw-r--r--source/Core/Broadcaster.cpp5
-rw-r--r--source/Core/CMakeLists.txt2
-rw-r--r--source/Core/Communication.cpp23
-rw-r--r--source/Core/Debugger.cpp194
-rw-r--r--source/Core/Disassembler.cpp102
-rw-r--r--source/Core/DumpDataExtractor.cpp24
-rw-r--r--source/Core/DumpRegisterValue.cpp79
-rw-r--r--source/Core/DynamicLoader.cpp21
-rw-r--r--source/Core/EmulateInstruction.cpp3
-rw-r--r--source/Core/Event.cpp16
-rw-r--r--source/Core/FileLineResolver.cpp4
-rw-r--r--source/Core/FileSpecList.cpp36
-rw-r--r--source/Core/FormatEntity.cpp99
-rw-r--r--source/Core/IOHandler.cpp175
-rw-r--r--source/Core/Listener.cpp12
-rw-r--r--source/Core/Mangled.cpp118
-rw-r--r--source/Core/Module.cpp239
-rw-r--r--source/Core/ModuleList.cpp131
-rw-r--r--source/Core/Opcode.cpp4
-rw-r--r--source/Core/PluginManager.cpp38
-rw-r--r--source/Core/RegisterValue.cpp77
-rw-r--r--source/Core/Scalar.cpp499
-rw-r--r--source/Core/Section.cpp30
-rw-r--r--source/Core/SourceManager.cpp29
-rw-r--r--source/Core/Value.cpp51
-rw-r--r--source/Core/ValueObject.cpp230
-rw-r--r--source/Core/ValueObjectCast.cpp6
-rw-r--r--source/Core/ValueObjectChild.cpp4
-rw-r--r--source/Core/ValueObjectDynamicValue.cpp45
-rw-r--r--source/Core/ValueObjectList.cpp4
-rw-r--r--source/Core/ValueObjectMemory.cpp27
-rw-r--r--source/Core/ValueObjectSyntheticFilter.cpp21
-rw-r--r--source/Core/ValueObjectVariable.cpp85
-rw-r--r--source/DataFormatters/FormatManager.cpp7
-rw-r--r--source/DataFormatters/StringPrinter.cpp26
-rw-r--r--source/DataFormatters/TypeFormat.cpp12
-rw-r--r--source/DataFormatters/ValueObjectPrinter.cpp52
-rw-r--r--source/DataFormatters/VectorType.cpp5
-rw-r--r--source/Expression/CMakeLists.txt1
-rw-r--r--source/Expression/DWARFExpression.cpp376
-rw-r--r--source/Expression/DiagnosticManager.cpp5
-rw-r--r--source/Expression/ExpressionSourceCode.cpp8
-rw-r--r--source/Expression/ExpressionVariable.cpp15
-rw-r--r--source/Expression/FunctionCaller.cpp20
-rw-r--r--source/Expression/IRDynamicChecks.cpp26
-rw-r--r--source/Expression/IRExecutionUnit.cpp74
-rw-r--r--source/Expression/IRInterpreter.cpp12
-rw-r--r--source/Expression/IRMemoryMap.cpp49
-rw-r--r--source/Expression/LLVMUserExpression.cpp5
-rw-r--r--source/Expression/Materializer.cpp21
-rw-r--r--source/Expression/REPL.cpp28
-rw-r--r--source/Expression/UserExpression.cpp11
-rw-r--r--source/Host/CMakeLists.txt54
-rw-r--r--source/Host/android/HostInfoAndroid.cpp11
-rw-r--r--source/Host/common/Editline.cpp118
-rw-r--r--source/Host/common/File.cpp14
-rw-r--r--source/Host/common/Host.cpp42
-rw-r--r--source/Host/common/HostInfoBase.cpp259
-rw-r--r--source/Host/common/MainLoop.cpp21
-rw-r--r--source/Host/common/MonitoringProcessLauncher.cpp52
-rw-r--r--source/Host/common/NativeBreakpointList.cpp4
-rw-r--r--source/Host/common/NativeProcessProtocol.cpp97
-rw-r--r--source/Host/common/NativeRegisterContext.cpp14
-rw-r--r--source/Host/common/NativeThreadProtocol.cpp33
-rw-r--r--source/Host/common/PseudoTerminal.cpp101
-rw-r--r--source/Host/common/Socket.cpp24
-rw-r--r--source/Host/common/SoftwareBreakpoint.cpp17
-rw-r--r--source/Host/common/Symbols.cpp42
-rw-r--r--source/Host/common/TCPSocket.cpp4
-rw-r--r--source/Host/common/TaskPool.cpp9
-rw-r--r--source/Host/common/Terminal.cpp26
-rw-r--r--source/Host/common/UDPSocket.cpp4
-rw-r--r--source/Host/common/XML.cpp16
-rw-r--r--source/Host/freebsd/Host.cpp23
-rw-r--r--source/Host/freebsd/HostInfoFreeBSD.cpp15
-rw-r--r--source/Host/linux/Host.cpp67
-rw-r--r--source/Host/linux/HostInfoLinux.cpp56
-rw-r--r--source/Host/macosx/Symbols.cpp184
-rw-r--r--source/Host/macosx/cfcpp/CFCMutableDictionary.cpp20
-rw-r--r--source/Host/macosx/cfcpp/CFCString.cpp11
-rw-r--r--source/Host/macosx/objcxx/CMakeLists.txt20
-rw-r--r--source/Host/macosx/objcxx/Host.mm (renamed from source/Host/macosx/Host.mm)364
-rw-r--r--source/Host/macosx/objcxx/HostInfoMacOSX.mm (renamed from source/Host/macosx/HostInfoMacOSX.mm)97
-rw-r--r--source/Host/macosx/objcxx/HostThreadMacOSX.mm (renamed from source/Host/macosx/HostThreadMacOSX.mm)0
-rw-r--r--source/Host/netbsd/Host.cpp20
-rw-r--r--source/Host/netbsd/HostInfoNetBSD.cpp20
-rw-r--r--source/Host/openbsd/Host.cpp13
-rw-r--r--source/Host/posix/ConnectionFileDescriptorPosix.cpp91
-rw-r--r--source/Host/posix/FileSystem.cpp7
-rw-r--r--source/Host/posix/HostInfoPosix.cpp64
-rw-r--r--source/Host/posix/HostThreadPosix.cpp5
-rw-r--r--source/Host/posix/PipePosix.cpp14
-rw-r--r--source/Host/posix/ProcessLauncherPosixFork.cpp54
-rw-r--r--source/Host/windows/ConnectionGenericFileWindows.cpp44
-rw-r--r--source/Host/windows/EditLineWin.cpp8
-rw-r--r--source/Host/windows/FileSystem.cpp2
-rw-r--r--source/Host/windows/Host.cpp36
-rw-r--r--source/Host/windows/HostInfoWindows.cpp51
-rw-r--r--source/Host/windows/HostProcessWindows.cpp6
-rw-r--r--source/Host/windows/PipeWindows.cpp27
-rw-r--r--source/Host/windows/ProcessLauncherWindows.cpp21
-rw-r--r--source/Initialization/CMakeLists.txt6
-rw-r--r--source/Initialization/SystemInitializerCommon.cpp20
-rw-r--r--source/Interpreter/Args.cpp1500
-rw-r--r--source/Interpreter/CMakeLists.txt2
-rw-r--r--source/Interpreter/CommandAlias.cpp41
-rw-r--r--source/Interpreter/CommandInterpreter.cpp401
-rw-r--r--source/Interpreter/CommandObject.cpp123
-rw-r--r--source/Interpreter/CommandObjectRegexCommand.cpp91
-rw-r--r--source/Interpreter/CommandObjectScript.cpp6
-rw-r--r--source/Interpreter/CommandObjectScript.h2
-rw-r--r--source/Interpreter/CommandReturnObject.cpp8
-rw-r--r--source/Interpreter/OptionArgParser.cpp253
-rw-r--r--source/Interpreter/OptionGroupBoolean.cpp4
-rw-r--r--source/Interpreter/OptionGroupFormat.cpp21
-rw-r--r--source/Interpreter/OptionGroupPlatform.cpp30
-rw-r--r--source/Interpreter/OptionGroupValueObjectDisplay.cpp9
-rw-r--r--source/Interpreter/OptionGroupVariable.cpp8
-rw-r--r--source/Interpreter/OptionGroupWatchpoint.cpp6
-rw-r--r--source/Interpreter/OptionValue.cpp19
-rw-r--r--source/Interpreter/OptionValueArch.cpp16
-rw-r--r--source/Interpreter/OptionValueArgs.cpp2
-rw-r--r--source/Interpreter/OptionValueArray.cpp2
-rw-r--r--source/Interpreter/OptionValueBoolean.cpp21
-rw-r--r--source/Interpreter/OptionValueChar.cpp4
-rw-r--r--source/Interpreter/OptionValueDictionary.cpp10
-rw-r--r--source/Interpreter/OptionValueEnumeration.cpp20
-rw-r--r--source/Interpreter/OptionValueFileSpec.cpp29
-rw-r--r--source/Interpreter/OptionValueFileSpecLIst.cpp2
-rw-r--r--source/Interpreter/OptionValueFormat.cpp4
-rw-r--r--source/Interpreter/OptionValueFormatEntity.cpp18
-rw-r--r--source/Interpreter/OptionValueLanguage.cpp2
-rw-r--r--source/Interpreter/OptionValuePathMappings.cpp2
-rw-r--r--source/Interpreter/OptionValueProperties.cpp46
-rw-r--r--source/Interpreter/OptionValueSInt64.cpp3
-rw-r--r--source/Interpreter/OptionValueString.cpp2
-rw-r--r--source/Interpreter/OptionValueUUID.cpp36
-rw-r--r--source/Interpreter/Options.cpp686
-rw-r--r--source/Interpreter/Property.cpp55
-rw-r--r--source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp16
-rw-r--r--source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp21
-rw-r--r--source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp21
-rw-r--r--source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp4
-rw-r--r--source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp29
-rw-r--r--source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp4
-rw-r--r--source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp51
-rw-r--r--source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp8
-rw-r--r--source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp33
-rw-r--r--source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp45
-rw-r--r--source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp1167
-rw-r--r--source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h2
-rw-r--r--source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp21
-rw-r--r--source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp54
-rw-r--r--source/Plugins/Architecture/Arm/ArchitectureArm.cpp69
-rw-r--r--source/Plugins/Architecture/Arm/ArchitectureArm.h2
-rw-r--r--source/Plugins/Architecture/CMakeLists.txt1
-rw-r--r--source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp69
-rw-r--r--source/Plugins/Architecture/PPC64/ArchitecturePPC64.h44
-rw-r--r--source/Plugins/Architecture/PPC64/CMakeLists.txt11
-rw-r--r--source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp302
-rw-r--r--source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h60
-rw-r--r--source/Plugins/DynamicLoader/CMakeLists.txt5
-rw-r--r--source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp296
-rw-r--r--source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h6
-rw-r--r--source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp38
-rw-r--r--source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp20
-rw-r--r--source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h19
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp173
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp62
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp220
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h13
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp36
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h17
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp204
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h19
-rw-r--r--source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp18
-rw-r--r--source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp12
-rw-r--r--source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h31
-rw-r--r--source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h25
-rw-r--r--source/Plugins/ExpressionParser/Clang/CMakeLists.txt2
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp62
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangASTSource.h66
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp97
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h81
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp82
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h16
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h42
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp6
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h12
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangHost.cpp142
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangHost.h26
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp38
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp9
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h18
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp164
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangUserExpression.h22
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h12
-rw-r--r--source/Plugins/ExpressionParser/Clang/IRForTarget.cpp62
-rw-r--r--source/Plugins/ExpressionParser/Clang/IRForTarget.h105
-rw-r--r--source/Plugins/ExpressionParser/Go/GoParser.cpp10
-rw-r--r--source/Plugins/ExpressionParser/Go/GoUserExpression.cpp20
-rw-r--r--source/Plugins/ExpressionParser/Go/GoUserExpression.h14
-rw-r--r--source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp566
-rw-r--r--source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp28
-rw-r--r--source/Plugins/Instruction/CMakeLists.txt1
-rw-r--r--source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp23
-rw-r--r--source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp11
-rw-r--r--source/Plugins/Instruction/PPC64/CMakeLists.txt11
-rw-r--r--source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp406
-rw-r--r--source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h97
-rw-r--r--source/Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.cpp4
-rw-r--r--source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp7
-rw-r--r--source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp4
-rw-r--r--source/Plugins/JITLoader/GDB/CMakeLists.txt2
-rw-r--r--source/Plugins/Language/CPlusPlus/BlockPointer.cpp5
-rw-r--r--source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp46
-rw-r--r--source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp36
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxx.cpp14
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxList.cpp8
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxMap.cpp4
-rw-r--r--source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp29
-rw-r--r--source/Plugins/Language/ObjC/Cocoa.cpp119
-rw-r--r--source/Plugins/Language/ObjC/Cocoa.h3
-rw-r--r--source/Plugins/Language/ObjC/NSDictionary.cpp24
-rw-r--r--source/Plugins/Language/ObjC/NSError.cpp11
-rw-r--r--source/Plugins/Language/ObjC/NSException.cpp11
-rw-r--r--source/Plugins/Language/ObjC/NSSet.cpp33
-rw-r--r--source/Plugins/Language/ObjC/NSString.cpp7
-rw-r--r--source/Plugins/Language/ObjC/ObjCLanguage.cpp23
-rw-r--r--source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp78
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp3
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp38
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp16
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h2
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp198
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h3
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp545
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp54
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp14
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp34
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp207
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp2
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp68
-rw-r--r--source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp45
-rw-r--r--source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp11
-rw-r--r--source/Plugins/ObjectFile/ELF/ELFHeader.cpp7
-rw-r--r--source/Plugins/ObjectFile/ELF/ELFHeader.h39
-rw-r--r--source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp560
-rw-r--r--source/Plugins/ObjectFile/ELF/ObjectFileELF.h21
-rw-r--r--source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp13
-rw-r--r--source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp1942
-rw-r--r--source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h25
-rw-r--r--source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp18
-rw-r--r--source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp7
-rw-r--r--source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp90
-rw-r--r--source/Plugins/Platform/Android/AdbClient.cpp4
-rw-r--r--source/Plugins/Platform/Android/PlatformAndroid.cpp29
-rw-r--r--source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp13
-rw-r--r--source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp37
-rw-r--r--source/Plugins/Platform/Linux/PlatformLinux.cpp35
-rw-r--r--source/Plugins/Platform/MacOSX/CMakeLists.txt4
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp16
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h4
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp33
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp33
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformDarwin.cpp297
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformDarwin.h9
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp154
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h4
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp19
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp4
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp8
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp107
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h4
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp4
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp41
-rw-r--r--source/Plugins/Platform/MacOSX/objcxx/CMakeLists.txt17
-rw-r--r--source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h (renamed from source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.h)2
-rw-r--r--source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm (renamed from source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm)23
-rw-r--r--source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp136
-rw-r--r--source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp20
-rw-r--r--source/Plugins/Platform/POSIX/PlatformPOSIX.cpp481
-rw-r--r--source/Plugins/Platform/POSIX/PlatformPOSIX.h13
-rw-r--r--source/Plugins/Platform/Windows/PlatformWindows.cpp76
-rw-r--r--source/Plugins/Platform/Windows/PlatformWindows.h2
-rw-r--r--source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp45
-rw-r--r--source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h5
-rw-r--r--source/Plugins/Process/CMakeLists.txt2
-rw-r--r--source/Plugins/Process/Darwin/CFString.cpp11
-rw-r--r--source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp58
-rw-r--r--source/Plugins/Process/Darwin/MachException.cpp35
-rw-r--r--source/Plugins/Process/Darwin/NativeProcessDarwin.cpp163
-rw-r--r--source/Plugins/Process/Darwin/NativeProcessDarwin.h22
-rw-r--r--source/Plugins/Process/Darwin/NativeThreadDarwin.cpp54
-rw-r--r--source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp69
-rw-r--r--source/Plugins/Process/FreeBSD/CMakeLists.txt4
-rw-r--r--source/Plugins/Process/FreeBSD/FreeBSDThread.cpp69
-rw-r--r--source/Plugins/Process/FreeBSD/FreeBSDThread.h2
-rw-r--r--source/Plugins/Process/FreeBSD/POSIXStopInfo.h6
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp35
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessMonitor.cpp138
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessMonitor.h23
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h4
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp2
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp8
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp6
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp32
-rw-r--r--source/Plugins/Process/Linux/CMakeLists.txt4
-rw-r--r--source/Plugins/Process/Linux/NativeProcessLinux.cpp384
-rw-r--r--source/Plugins/Process/Linux/NativeProcessLinux.h20
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp44
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h4
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp21
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h4
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp9
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp17
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h4
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp10
-rwxr-xr-xsource/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp42
-rw-r--r--source/Plugins/Process/Linux/NativeThreadLinux.cpp8
-rw-r--r--source/Plugins/Process/Linux/ProcessorTrace.h2
-rw-r--r--source/Plugins/Process/Linux/SingleStepCheck.cpp6
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp67
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp57
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp18
-rw-r--r--source/Plugins/Process/NetBSD/CMakeLists.txt4
-rw-r--r--source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp61
-rw-r--r--source/Plugins/Process/NetBSD/NativeProcessNetBSD.h6
-rw-r--r--source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp17
-rw-r--r--source/Plugins/Process/POSIX/CMakeLists.txt3
-rw-r--r--source/Plugins/Process/POSIX/CrashReason.cpp3
-rw-r--r--source/Plugins/Process/Utility/CMakeLists.txt3
-rw-r--r--source/Plugins/Process/Utility/DynamicRegisterInfo.cpp94
-rw-r--r--source/Plugins/Process/Utility/DynamicRegisterInfo.h23
-rw-r--r--source/Plugins/Process/Utility/HistoryThread.h6
-rw-r--r--source/Plugins/Process/Utility/InstructionUtils.h3
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwinConstants.h26
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp21
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp25
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp24
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp12
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLLDB.cpp329
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp14
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMemory.cpp6
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp15
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp15
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp17
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp15
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp14
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp8
-rw-r--r--source/Plugins/Process/Utility/RegisterInfoInterface.h2
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_ppc64.h331
-rw-r--r--source/Plugins/Process/Utility/StopInfoMachException.cpp57
-rw-r--r--source/Plugins/Process/Utility/ThreadMemory.cpp2
-rw-r--r--source/Plugins/Process/Utility/UnwindLLDB.cpp147
-rw-r--r--source/Plugins/Process/Utility/UnwindLLDB.h1
-rw-r--r--source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp8
-rw-r--r--source/Plugins/Process/Utility/lldb-ppc64-register-enums.h139
-rw-r--r--source/Plugins/Process/Windows/Common/CMakeLists.txt3
-rw-r--r--source/Plugins/Process/Windows/Common/DebuggerThread.cpp62
-rw-r--r--source/Plugins/Process/Windows/Common/ProcessWindows.cpp196
-rw-r--r--source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp74
-rw-r--r--source/Plugins/Process/Windows/Common/TargetThreadWindows.h7
-rw-r--r--source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp61
-rw-r--r--source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp29
-rw-r--r--source/Plugins/Process/elf-core/CMakeLists.txt2
-rw-r--r--source/Plugins/Process/elf-core/ProcessElfCore.cpp55
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp2
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp4
-rw-r--r--source/Plugins/Process/elf-core/ThreadElfCore.cpp31
-rw-r--r--source/Plugins/Process/elf-core/ThreadElfCore.h2
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp59
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h5
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp203
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h9
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp322
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h21
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp2
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h4
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp85
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp116
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp55
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp140
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp784
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.h17
-rw-r--r--source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp46
-rw-r--r--source/Plugins/Process/mach-core/CMakeLists.txt2
-rw-r--r--source/Plugins/Process/mach-core/ProcessMachCore.cpp136
-rw-r--r--source/Plugins/Process/mach-core/ThreadMachCore.cpp12
-rw-r--r--source/Plugins/Process/minidump/CMakeLists.txt2
-rw-r--r--source/Plugins/Process/minidump/MinidumpParser.cpp206
-rw-r--r--source/Plugins/Process/minidump/MinidumpParser.h14
-rw-r--r--source/Plugins/Process/minidump/MinidumpTypes.cpp46
-rw-r--r--source/Plugins/Process/minidump/MinidumpTypes.h15
-rw-r--r--source/Plugins/Process/minidump/ProcessMinidump.cpp102
-rw-r--r--source/Plugins/Process/minidump/ProcessMinidump.h2
-rw-r--r--source/Plugins/ScriptInterpreter/CMakeLists.txt4
-rw-r--r--source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp2
-rw-r--r--source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h2
-rw-r--r--source/Plugins/ScriptInterpreter/Python/CMakeLists.txt13
-rw-r--r--source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp124
-rw-r--r--source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp31
-rw-r--r--source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp565
-rw-r--r--source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h25
-rw-r--r--source/Plugins/ScriptInterpreter/Python/lldb-python.h5
-rw-r--r--source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp291
-rw-r--r--source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp177
-rw-r--r--source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h64
-rw-r--r--source/Plugins/SymbolFile/DWARF/CMakeLists.txt8
-rw-r--r--source/Plugins/SymbolFile/DWARF/DIERef.cpp11
-rw-r--r--source/Plugins/SymbolFile/DWARF/DIERef.h12
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp903
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp55
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp7
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp3
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h1
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp1
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp9
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFAttribute.h8
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp193
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h157
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp1058
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h223
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp205
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDIE.h171
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp10
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp57
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp4
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp300
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h25
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp266
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h70
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp245
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h5
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp255
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h40
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp146
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h95
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp4
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp4
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp10
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDefines.h2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp20
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFFormValue.h12
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp68
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFIndex.h69
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp755
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFUnit.h252
-rw-r--r--source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp272
-rw-r--r--source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h83
-rw-r--r--source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp116
-rw-r--r--source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h26
-rw-r--r--source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp488
-rw-r--r--source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h75
-rw-r--r--source/Plugins/SymbolFile/DWARF/NameToDIE.cpp1
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp1442
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h89
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp149
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h10
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp12
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h14
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp4
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h2
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp2
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h2
-rw-r--r--source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp5
-rw-r--r--source/Plugins/SymbolFile/PDB/CMakeLists.txt1
-rw-r--r--source/Plugins/SymbolFile/PDB/PDBASTParser.cpp341
-rw-r--r--source/Plugins/SymbolFile/PDB/PDBASTParser.h10
-rw-r--r--source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp585
-rw-r--r--source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h45
-rw-r--r--source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp1277
-rw-r--r--source/Plugins/SymbolFile/PDB/SymbolFilePDB.h65
-rw-r--r--source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp30
-rw-r--r--source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp16
-rw-r--r--source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp83
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp27
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp22
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp27
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp24
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp73
-rw-r--r--source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp67
-rw-r--r--source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp29
-rw-r--r--source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp126
-rw-r--r--source/Symbol/ArmUnwindInfo.cpp15
-rw-r--r--source/Symbol/Block.cpp3
-rw-r--r--source/Symbol/CMakeLists.txt1
-rw-r--r--source/Symbol/ClangASTContext.cpp418
-rw-r--r--source/Symbol/ClangASTImporter.cpp12
-rw-r--r--source/Symbol/CompactUnwindInfo.cpp92
-rw-r--r--source/Symbol/CompileUnit.cpp95
-rw-r--r--source/Symbol/CompilerType.cpp27
-rw-r--r--source/Symbol/DWARFCallFrameInfo.cpp207
-rw-r--r--source/Symbol/Declaration.cpp2
-rw-r--r--source/Symbol/FuncUnwinders.cpp36
-rw-r--r--source/Symbol/Function.cpp25
-rw-r--r--source/Symbol/GoASTContext.cpp21
-rw-r--r--source/Symbol/LineEntry.cpp22
-rw-r--r--source/Symbol/LineTable.cpp76
-rw-r--r--source/Symbol/ObjectFile.cpp195
-rw-r--r--source/Symbol/Symbol.cpp59
-rw-r--r--source/Symbol/SymbolContext.cpp92
-rw-r--r--source/Symbol/SymbolFile.cpp24
-rw-r--r--source/Symbol/SymbolVendor.cpp44
-rw-r--r--source/Symbol/Symtab.cpp117
-rw-r--r--source/Symbol/Type.cpp49
-rw-r--r--source/Symbol/TypeList.cpp37
-rw-r--r--source/Symbol/TypeMap.cpp36
-rw-r--r--source/Symbol/UnwindPlan.cpp6
-rw-r--r--source/Symbol/UnwindTable.cpp17
-rw-r--r--source/Symbol/Variable.cpp37
-rw-r--r--source/Target/ABI.cpp21
-rw-r--r--source/Target/CMakeLists.txt2
-rw-r--r--source/Target/ExecutionContext.cpp20
-rw-r--r--source/Target/Memory.cpp36
-rw-r--r--source/Target/ModuleCache.cpp5
-rw-r--r--source/Target/ObjCLanguageRuntime.cpp16
-rw-r--r--source/Target/PathMappingList.cpp101
-rw-r--r--source/Target/Platform.cpp222
-rw-r--r--source/Target/Process.cpp894
-rw-r--r--source/Target/ProcessInfo.cpp21
-rw-r--r--source/Target/ProcessLaunchInfo.cpp42
-rw-r--r--source/Target/RegisterContext.cpp24
-rw-r--r--source/Target/SectionLoadHistory.cpp17
-rw-r--r--source/Target/SectionLoadList.cpp16
-rw-r--r--source/Target/StackFrame.cpp154
-rw-r--r--source/Target/StackFrameList.cpp138
-rw-r--r--source/Target/StackID.cpp11
-rw-r--r--source/Target/StopInfo.cpp169
-rw-r--r--source/Target/Target.cpp334
-rw-r--r--source/Target/TargetList.cpp45
-rw-r--r--source/Target/Thread.cpp204
-rw-r--r--source/Target/ThreadList.cpp162
-rw-r--r--source/Target/ThreadPlan.cpp4
-rw-r--r--source/Target/ThreadPlanBase.cpp37
-rw-r--r--source/Target/ThreadPlanCallFunction.cpp52
-rw-r--r--source/Target/ThreadPlanCallOnFunctionExit.cpp29
-rw-r--r--source/Target/ThreadPlanCallUserExpression.cpp4
-rw-r--r--source/Target/ThreadPlanPython.cpp3
-rw-r--r--source/Target/ThreadPlanRunToAddress.cpp3
-rw-r--r--source/Target/ThreadPlanShouldStopHere.cpp12
-rw-r--r--source/Target/ThreadPlanStepInRange.cpp86
-rw-r--r--source/Target/ThreadPlanStepInstruction.cpp24
-rw-r--r--source/Target/ThreadPlanStepOut.cpp55
-rw-r--r--source/Target/ThreadPlanStepOverBreakpoint.cpp93
-rw-r--r--source/Target/ThreadPlanStepOverRange.cpp107
-rw-r--r--source/Target/ThreadPlanStepRange.cpp47
-rw-r--r--source/Target/ThreadPlanStepThrough.cpp32
-rw-r--r--source/Target/ThreadPlanStepUntil.cpp44
-rw-r--r--source/Target/ThreadPlanTracer.cpp4
-rw-r--r--source/Target/UnixSignals.cpp9
-rw-r--r--source/Utility/ArchSpec.cpp101
-rw-r--r--source/Utility/Args.cpp726
-rw-r--r--source/Utility/CMakeLists.txt4
-rw-r--r--source/Utility/CompletionRequest.cpp59
-rw-r--r--source/Utility/ConstString.cpp32
-rw-r--r--source/Utility/DataBufferHeap.cpp21
-rw-r--r--source/Utility/DataEncoder.cpp78
-rw-r--r--source/Utility/DataExtractor.cpp268
-rw-r--r--source/Utility/Environment.cpp50
-rw-r--r--source/Utility/FastDemangle.cpp126
-rw-r--r--source/Utility/FileSpec.cpp698
-rw-r--r--source/Utility/History.cpp24
-rw-r--r--source/Utility/JSON.cpp6
-rw-r--r--source/Utility/Log.cpp21
-rw-r--r--source/Utility/PPC64_DWARF_Registers.h127
-rw-r--r--source/Utility/RegularExpression.cpp43
-rw-r--r--source/Utility/SelectHelper.cpp9
-rw-r--r--source/Utility/SharingPtr.cpp8
-rw-r--r--source/Utility/Status.cpp41
-rw-r--r--source/Utility/Stream.cpp25
-rw-r--r--source/Utility/StringExtractor.cpp23
-rw-r--r--source/Utility/StringExtractorGDBRemote.cpp15
-rw-r--r--source/Utility/StringExtractorGDBRemote.h204
-rw-r--r--source/Utility/StructuredData.cpp7
-rw-r--r--source/Utility/TildeExpressionResolver.cpp5
-rw-r--r--source/Utility/UUID.cpp172
-rw-r--r--source/Utility/VASprintf.cpp4
658 files changed, 26267 insertions, 25054 deletions
diff --git a/source/API/CMakeLists.txt b/source/API/CMakeLists.txt
index c96e59be5a44..be9d4115cecc 100644
--- a/source/API/CMakeLists.txt
+++ b/source/API/CMakeLists.txt
@@ -2,16 +2,6 @@ if ( CMAKE_SYSTEM_NAME MATCHES "Windows" )
add_definitions( -DEXPORT_LIBLLDB )
endif()
-option(LLDB_BUILD_FRAMEWORK "Build the Darwin LLDB.framework" Off)
-
-if(LLDB_BUILD_FRAMEWORK AND CMAKE_VERSION VERSION_LESS 3.7)
- message(FATAL_ERROR "LLDB_BUILD_FRAMEWORK is not supported on CMake < 3.7")
-endif()
-
-if (LLDB_BUILD_FRAMEWORK AND NOT APPLE)
- message(FATAL_ERROR "LLDB.framework cannot be generated unless targeting Apple platforms.")
-endif()
-
get_property(LLDB_ALL_PLUGINS GLOBAL PROPERTY LLDB_PLUGINS)
add_lldb_library(liblldb SHARED
@@ -101,13 +91,14 @@ add_lldb_library(liblldb SHARED
Support
)
-if (LLVM_ENABLE_WERROR)
- if (MSVC)
- set_property(SOURCE ${LLDB_WRAP_PYTHON} APPEND_STRING PROPERTY COMPILE_FLAGS " /W0")
- else()
- set_property(SOURCE ${LLDB_WRAP_PYTHON} APPEND_STRING PROPERTY COMPILE_FLAGS " -w")
- endif()
+add_dependencies(lldb-suite liblldb)
+
+if (MSVC)
+ set_property(SOURCE ${LLDB_WRAP_PYTHON} APPEND_STRING PROPERTY COMPILE_FLAGS " /W0")
+else()
+ set_property(SOURCE ${LLDB_WRAP_PYTHON} APPEND_STRING PROPERTY COMPILE_FLAGS " -w")
endif()
+
set_source_files_properties(${LLDB_WRAP_PYTHON} PROPERTIES GENERATED 1)
if (CLANG_CL)
set_property(SOURCE ${LLDB_WRAP_PYTHON} APPEND_STRING
@@ -119,15 +110,10 @@ if (LLVM_COMPILER_IS_GCC_COMPATIBLE AND
PROPERTY COMPILE_FLAGS " -Wno-sequence-point -Wno-cast-qual")
endif ()
-target_link_libraries(liblldb PRIVATE
- lldbPluginScriptInterpreterNone
- lldbPluginScriptInterpreterPython
- )
-
set_target_properties(liblldb
PROPERTIES
VERSION ${LLDB_VERSION}
- )
+)
if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows")
if (NOT LLDB_EXPORT_ALL_SYMBOLS)
@@ -154,51 +140,9 @@ else()
set_target_properties(liblldb
PROPERTIES
OUTPUT_NAME lldb
- )
+ )
endif()
if (LLDB_WRAP_PYTHON)
add_dependencies(liblldb swig_wrapper)
endif()
-
-if(LLDB_BUILD_FRAMEWORK)
- file(GLOB public_headers ${LLDB_SOURCE_DIR}/include/lldb/API/*.h
- ${LLDB_SOURCE_DIR}/include/lldb/lldb-*.h)
- file(GLOB root_public_headers ${LLDB_SOURCE_DIR}/include/lldb/lldb-*.h)
- file(GLOB root_private_headers ${LLDB_SOURCE_DIR}/include/lldb/lldb-private*.h)
- list(REMOVE_ITEM root_public_headers ${root_private_headers})
-
- foreach(header ${public_headers} ${root_public_headers} ${LLDB_SOURCE_DIR}/include/lldb/Utility/SharingPtr.h)
- get_filename_component(basename ${header} NAME)
- add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/FrameworkHeaders/${basename}
- DEPENDS ${header}
- COMMAND ${CMAKE_COMMAND} -E copy ${header} ${CMAKE_CURRENT_BINARY_DIR}/FrameworkHeaders/${basename})
- list(APPEND framework_headers ${CMAKE_CURRENT_BINARY_DIR}/FrameworkHeaders/${basename})
- endforeach()
-
- add_custom_target(lldb-framework-headers DEPENDS ${framework_headers}
- COMMAND ${LLDB_SOURCE_DIR}/scripts/framework-header-fix.sh ${CMAKE_CURRENT_BINARY_DIR}/FrameworkHeaders ${LLDB_VERSION})
- add_dependencies(liblldb lldb-framework-headers)
-
- set_target_properties(liblldb PROPERTIES
- OUTPUT_NAME LLDB
- FRAMEWORK On
- FRAMEWORK_VERSION ${LLDB_FRAMEWORK_VERSION}
- LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LLDB_FRAMEWORK_INSTALL_DIR}
- PUBLIC_HEADER "${framework_headers}")
-
- if(NOT IOS)
- add_custom_command(TARGET liblldb POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/FrameworkHeaders $<TARGET_FILE_DIR:liblldb>/Headers
- COMMAND ${CMAKE_COMMAND} -E create_symlink Versions/Current/Headers ${CMAKE_BINARY_DIR}/${LLDB_FRAMEWORK_INSTALL_DIR}/LLDB.framework/Headers
- COMMAND ${CMAKE_COMMAND} -E create_symlink ${LLDB_FRAMEWORK_VERSION} ${CMAKE_BINARY_DIR}/${LLDB_FRAMEWORK_INSTALL_DIR}/LLDB.framework/Versions/Current
- COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/clang/${LLDB_VERSION} $<TARGET_FILE_DIR:liblldb>/Resources/Clang
- )
- else()
- add_custom_command(TARGET liblldb POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/FrameworkHeaders $<TARGET_FILE_DIR:liblldb>/Headers
- )
- endif()
-
-endif()
-
diff --git a/source/API/SBAddress.cpp b/source/API/SBAddress.cpp
index a3493d7c743f..d12197e66ddd 100644
--- a/source/API/SBAddress.cpp
+++ b/source/API/SBAddress.cpp
@@ -120,10 +120,9 @@ void SBAddress::SetLoadAddress(lldb::addr_t load_addr, lldb::SBTarget &target) {
else
m_opaque_ap->Clear();
- // Check if we weren't were able to resolve a section offset address.
- // If we weren't it is ok, the load address might be a location on the
- // stack or heap, so we should just have an address with no section and
- // a valid offset
+ // Check if we weren't were able to resolve a section offset address. If we
+ // weren't it is ok, the load address might be a location on the stack or
+ // heap, so we should just have an address with no section and a valid offset
if (!m_opaque_ap->IsValid())
m_opaque_ap->SetOffset(load_addr);
}
@@ -163,9 +162,8 @@ Address &SBAddress::ref() {
}
const Address &SBAddress::ref() const {
- // This object should already have checked with "IsValid()"
- // prior to calling this function. In case you didn't we will assert
- // and die to let you know.
+ // This object should already have checked with "IsValid()" prior to calling
+ // this function. In case you didn't we will assert and die to let you know.
assert(m_opaque_ap.get());
return *m_opaque_ap;
}
@@ -242,9 +240,3 @@ SBLineEntry SBAddress::GetLineEntry() {
}
return sb_line_entry;
}
-
-AddressClass SBAddress::GetAddressClass() {
- if (m_opaque_ap->IsValid())
- return m_opaque_ap->GetAddressClass();
- return eAddressClassInvalid;
-}
diff --git a/source/API/SBAttachInfo.cpp b/source/API/SBAttachInfo.cpp
index e6500c468ec5..d6cb212dedf8 100644
--- a/source/API/SBAttachInfo.cpp
+++ b/source/API/SBAttachInfo.cpp
@@ -26,14 +26,16 @@ SBAttachInfo::SBAttachInfo(lldb::pid_t pid)
SBAttachInfo::SBAttachInfo(const char *path, bool wait_for)
: m_opaque_sp(new ProcessAttachInfo()) {
if (path && path[0])
- m_opaque_sp->GetExecutableFile().SetFile(path, false);
+ m_opaque_sp->GetExecutableFile().SetFile(path, false,
+ FileSpec::Style::native);
m_opaque_sp->SetWaitForLaunch(wait_for);
}
SBAttachInfo::SBAttachInfo(const char *path, bool wait_for, bool async)
: m_opaque_sp(new ProcessAttachInfo()) {
if (path && path[0])
- m_opaque_sp->GetExecutableFile().SetFile(path, false);
+ m_opaque_sp->GetExecutableFile().SetFile(path, false,
+ FileSpec::Style::native);
m_opaque_sp->SetWaitForLaunch(wait_for);
m_opaque_sp->SetAsync(async);
}
@@ -77,7 +79,8 @@ void SBAttachInfo::SetProcessPluginName(const char *plugin_name) {
void SBAttachInfo::SetExecutable(const char *path) {
if (path && path[0])
- m_opaque_sp->GetExecutableFile().SetFile(path, false);
+ m_opaque_sp->GetExecutableFile().SetFile(path, false,
+ FileSpec::Style::native);
else
m_opaque_sp->GetExecutableFile().Clear();
}
diff --git a/source/API/SBBreakpointName.cpp b/source/API/SBBreakpointName.cpp
index 2205280b9e5f..a6742e3b89ec 100644
--- a/source/API/SBBreakpointName.cpp
+++ b/source/API/SBBreakpointName.cpp
@@ -52,8 +52,8 @@ public:
bool operator==(const SBBreakpointNameImpl &rhs);
bool operator!=(const SBBreakpointNameImpl &rhs);
- // For now we take a simple approach and only keep the name, and relook
- // up the location when we need it.
+ // For now we take a simple approach and only keep the name, and relook up
+ // the location when we need it.
TargetSP GetTarget() const {
return m_target_wp.lock();
@@ -115,8 +115,7 @@ SBBreakpointName::SBBreakpointName() {}
SBBreakpointName::SBBreakpointName(SBTarget &sb_target, const char *name)
{
m_impl_up.reset(new SBBreakpointNameImpl(sb_target, name));
- // Call FindBreakpointName here to make sure the name is valid, reset if
- // not:
+ // Call FindBreakpointName here to make sure the name is valid, reset if not:
BreakpointName *bp_name = GetBreakpointName();
if (!bp_name)
m_impl_up.reset();
@@ -133,8 +132,7 @@ SBBreakpointName::SBBreakpointName(SBBreakpoint &sb_bkpt, const char *name)
m_impl_up.reset(new SBBreakpointNameImpl(target.shared_from_this(), name));
- // Call FindBreakpointName here to make sure the name is valid, reset if
- // not:
+ // Call FindBreakpointName here to make sure the name is valid, reset if not:
BreakpointName *bp_name = GetBreakpointName();
if (!bp_name) {
m_impl_up.reset();
diff --git a/source/API/SBCommandInterpreter.cpp b/source/API/SBCommandInterpreter.cpp
index c9bb8f65fa2e..cbb514abb6fe 100644
--- a/source/API/SBCommandInterpreter.cpp
+++ b/source/API/SBCommandInterpreter.cpp
@@ -272,8 +272,8 @@ int SBCommandInterpreter::HandleCompletion(
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.
+ // Sanity check the arguments that are passed in: cursor & last_char have to
+ // be within the current_line.
if (current_line == nullptr || cursor == nullptr || last_char == nullptr)
return 0;
@@ -379,6 +379,23 @@ void SBCommandInterpreter::SetPromptOnQuit(bool b) {
m_opaque_ptr->SetPromptOnQuit(b);
}
+void SBCommandInterpreter::AllowExitCodeOnQuit(bool allow) {
+ if (m_opaque_ptr)
+ m_opaque_ptr->AllowExitCodeOnQuit(allow);
+}
+
+bool SBCommandInterpreter::HasCustomQuitExitCode() {
+ bool exited = false;
+ if (m_opaque_ptr)
+ m_opaque_ptr->GetQuitExitCode(exited);
+ return exited;
+}
+
+int SBCommandInterpreter::GetQuitStatus() {
+ bool exited = false;
+ return (m_opaque_ptr ? m_opaque_ptr->GetQuitExitCode(exited) : 0);
+}
+
void SBCommandInterpreter::ResolveCommand(const char *command_line,
SBCommandReturnObject &result) {
result.Clear();
diff --git a/source/API/SBDebugger.cpp b/source/API/SBDebugger.cpp
index d3294dab582d..a651141003a4 100644
--- a/source/API/SBDebugger.cpp
+++ b/source/API/SBDebugger.cpp
@@ -11,6 +11,9 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
+
+#include "SystemInitializerFull.h"
+
#include "lldb/API/SBDebugger.h"
#include "lldb/lldb-private.h"
@@ -35,7 +38,6 @@
#include "lldb/API/SBTypeNameSpecifier.h"
#include "lldb/API/SBTypeSummary.h"
#include "lldb/API/SBTypeSynthetic.h"
-#include "lldb/API/SystemInitializerFull.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/PluginManager.h"
@@ -43,12 +45,14 @@
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/DataFormatters/DataVisualization.h"
+#include "lldb/Host/XML.h"
#include "lldb/Initialization/SystemLifetimeManager.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionGroupPlatform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/TargetList.h"
+#include "lldb/Utility/Args.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
@@ -166,14 +170,10 @@ SBDebugger SBDebugger::Create(bool source_init_files,
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.
+ // 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 std::recursive_mutex g_mutex;
std::lock_guard<std::recursive_mutex> guard(g_mutex);
@@ -218,10 +218,10 @@ void SBDebugger::Destroy(SBDebugger &debugger) {
}
void SBDebugger::MemoryPressureDetected() {
- // Since this function can be call asynchronously, we allow it to be
- // non-mandatory. We have seen deadlocks with this function when called
- // so we need to safeguard against this until we can determine what is
- // causing the deadlocks.
+ // Since this function can be call asynchronously, we allow it to be non-
+ // mandatory. We have seen deadlocks with this function when called so we
+ // need to safeguard against this until we can determine what is causing the
+ // deadlocks.
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
const bool mandatory = false;
@@ -254,9 +254,9 @@ void SBDebugger::SkipAppInitFiles(bool b) {
m_opaque_sp->GetCommandInterpreter().SkipAppInitFiles(b);
}
-// Shouldn't really be settable after initialization as this could cause lots of
-// problems; don't want users
-// trying to switch modes in the middle of a debugging session.
+// Shouldn't really be settable after initialization as this could cause lots
+// of problems; don't want users trying to switch modes in the middle of a
+// debugging session.
void SBDebugger::SetInputFileHandle(FILE *fh, bool transfer_ownership) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
@@ -479,8 +479,8 @@ bool SBDebugger::SetDefaultArchitecture(const char *arch_name) {
ScriptLanguage
SBDebugger::GetScriptingLanguage(const char *script_language_name) {
if (!script_language_name) return eScriptLanguageDefault;
- return Args::StringToScriptLanguage(llvm::StringRef(script_language_name),
- eScriptLanguageDefault, nullptr);
+ return OptionArgParser::ToScriptLanguage(
+ llvm::StringRef(script_language_name), eScriptLanguageDefault, nullptr);
}
const char *SBDebugger::GetVersionString() {
@@ -491,6 +491,38 @@ const char *SBDebugger::StateAsCString(StateType state) {
return lldb_private::StateAsCString(state);
}
+static void AddBoolConfigEntry(StructuredData::Dictionary &dict,
+ llvm::StringRef name, bool value,
+ llvm::StringRef description) {
+ auto entry_up = llvm::make_unique<StructuredData::Dictionary>();
+ entry_up->AddBooleanItem("value", value);
+ entry_up->AddStringItem("description", description);
+ dict.AddItem(name, std::move(entry_up));
+}
+
+static void AddLLVMTargets(StructuredData::Dictionary &dict) {
+ auto array_up = llvm::make_unique<StructuredData::Array>();
+#define LLVM_TARGET(target) \
+ array_up->AddItem(llvm::make_unique<StructuredData::String>(#target));
+#include "llvm/Config/Targets.def"
+ auto entry_up = llvm::make_unique<StructuredData::Dictionary>();
+ entry_up->AddItem("value", std::move(array_up));
+ entry_up->AddStringItem("description", "A list of configured LLVM targets.");
+ dict.AddItem("targets", std::move(entry_up));
+}
+
+SBStructuredData SBDebugger::GetBuildConfiguration() {
+ auto config_up = llvm::make_unique<StructuredData::Dictionary>();
+ AddBoolConfigEntry(
+ *config_up, "xml", XMLDocument::XMLEnabled(),
+ "A boolean value that indicates if XML support is enabled in LLDB");
+ AddLLVMTargets(*config_up);
+
+ SBStructuredData data;
+ data.m_impl_up->SetObjectSP(std::move(config_up));
+ return data;
+}
+
bool SBDebugger::StateIsRunningState(StateType state) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
diff --git a/source/API/SBEvent.cpp b/source/API/SBEvent.cpp
index 17a16ffd0481..65eb71c09285 100644
--- a/source/API/SBEvent.cpp
+++ b/source/API/SBEvent.cpp
@@ -146,8 +146,8 @@ void SBEvent::reset(Event *event_ptr) {
}
bool SBEvent::IsValid() const {
- // Do NOT use m_opaque_ptr directly!!! Must use the SBEvent::get()
- // accessor. See comments in SBEvent::get()....
+ // Do NOT use m_opaque_ptr directly!!! Must use the SBEvent::get() accessor.
+ // See comments in SBEvent::get()....
return SBEvent::get() != NULL;
}
diff --git a/source/API/SBFrame.cpp b/source/API/SBFrame.cpp
index 684a707dda94..5762a75f33d6 100644
--- a/source/API/SBFrame.cpp
+++ b/source/API/SBFrame.cpp
@@ -419,7 +419,7 @@ addr_t SBFrame::GetPC() const {
frame = exe_ctx.GetFramePtr();
if (frame) {
addr = frame->GetFrameCodeAddress().GetOpcodeLoadAddress(
- target, eAddressClassCode);
+ target, AddressClass::eCode);
} else {
if (log)
log->Printf("SBFrame::GetPC () => error: could not reconstruct frame "
diff --git a/source/API/SBHostOS.cpp b/source/API/SBHostOS.cpp
index 90b75a6ecd7b..e56951df43be 100644
--- a/source/API/SBHostOS.cpp
+++ b/source/API/SBHostOS.cpp
@@ -7,6 +7,10 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLDB_DISABLE_PYTHON
+#include "Plugins/ScriptInterpreter/Python/lldb-python.h"
+#endif
+
#include "lldb/API/SBHostOS.h"
#include "lldb/API/SBError.h"
#include "lldb/Host/Host.h"
@@ -17,6 +21,11 @@
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
+#include "Plugins/ExpressionParser/Clang/ClangHost.h"
+#ifndef LLDB_DISABLE_PYTHON
+#include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h"
+#endif
+
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Path.h"
@@ -30,19 +39,45 @@ SBFileSpec SBHostOS::GetProgramFileSpec() {
}
SBFileSpec SBHostOS::GetLLDBPythonPath() {
- SBFileSpec sb_lldb_python_filespec;
- FileSpec lldb_python_spec;
- if (HostInfo::GetLLDBPath(ePathTypePythonDir, lldb_python_spec)) {
- sb_lldb_python_filespec.SetFileSpec(lldb_python_spec);
- }
- return sb_lldb_python_filespec;
+ return GetLLDBPath(ePathTypePythonDir);
}
SBFileSpec SBHostOS::GetLLDBPath(lldb::PathType path_type) {
- SBFileSpec sb_fspec;
FileSpec fspec;
- if (HostInfo::GetLLDBPath(path_type, fspec))
- sb_fspec.SetFileSpec(fspec);
+ switch (path_type) {
+ case ePathTypeLLDBShlibDir:
+ fspec = HostInfo::GetShlibDir();
+ break;
+ case ePathTypeSupportExecutableDir:
+ fspec = HostInfo::GetSupportExeDir();
+ break;
+ case ePathTypeHeaderDir:
+ fspec = HostInfo::GetHeaderDir();
+ break;
+ case ePathTypePythonDir:
+#ifndef LLDB_DISABLE_PYTHON
+ fspec = ScriptInterpreterPython::GetPythonDir();
+#endif
+ break;
+ case ePathTypeLLDBSystemPlugins:
+ fspec = HostInfo::GetSystemPluginDir();
+ break;
+ case ePathTypeLLDBUserPlugins:
+ fspec = HostInfo::GetUserPluginDir();
+ break;
+ case ePathTypeLLDBTempSystemDir:
+ fspec = HostInfo::GetProcessTempDir();
+ break;
+ case ePathTypeGlobalLLDBTempSystemDir:
+ fspec = HostInfo::GetGlobalTempDir();
+ break;
+ case ePathTypeClangDir:
+ fspec = GetClangResourceDir();
+ break;
+ }
+
+ SBFileSpec sb_fspec;
+ sb_fspec.SetFileSpec(fspec);
return sb_fspec;
}
diff --git a/source/API/SBInstruction.cpp b/source/API/SBInstruction.cpp
index 1cca8db2afe8..462f08288092 100644
--- a/source/API/SBInstruction.cpp
+++ b/source/API/SBInstruction.cpp
@@ -27,12 +27,11 @@
#include "lldb/Utility/DataExtractor.h"
//----------------------------------------------------------------------
-// We recently fixed a leak in one of the Instruction subclasses where
-// the instruction will only hold a weak reference to the disassembler
-// to avoid a cycle that was keeping both objects alive (leak) and we
-// need the InstructionImpl class to make sure our public API behaves
-// as users would expect. Calls in our public API allow clients to do
-// things like:
+// We recently fixed a leak in one of the Instruction subclasses where the
+// instruction will only hold a weak reference to the disassembler to avoid a
+// cycle that was keeping both objects alive (leak) and we need the
+// InstructionImpl class to make sure our public API behaves as users would
+// expect. Calls in our public API allow clients to do things like:
//
// 1 lldb::SBInstruction inst;
// 2 inst = target.ReadInstructions(pc, 1).GetInstructionAtIndex(0)
@@ -40,12 +39,12 @@
// 4 ...
//
// There was a temporary lldb::DisassemblerSP object created in the
-// SBInstructionList that was returned by lldb.target.ReadInstructions()
-// that will go away after line 2 but the "inst" object should be able
-// to still answer questions about itself. So we make sure that any
-// SBInstruction objects that are given out have a strong reference to
-// the disassembler and the instruction so that the object can live and
-// successfully respond to all queries.
+// SBInstructionList that was returned by lldb.target.ReadInstructions() that
+// will go away after line 2 but the "inst" object should be able to still
+// answer questions about itself. So we make sure that any SBInstruction
+// objects that are given out have a strong reference to the disassembler and
+// the instruction so that the object can live and successfully respond to all
+// queries.
//----------------------------------------------------------------------
class InstructionImpl {
public:
@@ -275,10 +274,3 @@ bool SBInstruction::TestEmulation(lldb::SBStream &output_stream,
return inst_sp->TestEmulation(output_stream.get(), test_file);
return false;
}
-
-lldb::AddressClass SBInstruction::GetAddressClass() {
- lldb::InstructionSP inst_sp(GetOpaque());
- if (inst_sp)
- return inst_sp->GetAddressClass();
- return eAddressClassInvalid;
-}
diff --git a/source/API/SBInstructionList.cpp b/source/API/SBInstructionList.cpp
index 3edb9eae98c1..29e0c96075fd 100644
--- a/source/API/SBInstructionList.cpp
+++ b/source/API/SBInstructionList.cpp
@@ -92,8 +92,8 @@ bool SBInstructionList::GetDescription(lldb::SBStream &description) {
if (m_opaque_sp) {
size_t num_instructions = GetSize();
if (num_instructions) {
- // Call the ref() to make sure a stream is created if one deesn't
- // exist already inside description...
+ // Call the ref() to make sure a stream is created if one deesn't exist
+ // already inside description...
Stream &sref = description.ref();
const uint32_t max_opcode_byte_size =
m_opaque_sp->GetInstructionList().GetMaxOpcocdeByteSize();
diff --git a/source/API/SBLaunchInfo.cpp b/source/API/SBLaunchInfo.cpp
index 5f5afccee680..aa1759ab3d00 100644
--- a/source/API/SBLaunchInfo.cpp
+++ b/source/API/SBLaunchInfo.cpp
@@ -16,8 +16,26 @@
using namespace lldb;
using namespace lldb_private;
+class lldb_private::SBLaunchInfoImpl : public ProcessLaunchInfo {
+public:
+ SBLaunchInfoImpl()
+ : ProcessLaunchInfo(), m_envp(GetEnvironment().getEnvp()) {}
+
+ const char *const *GetEnvp() const { return m_envp; }
+ void RegenerateEnvp() { m_envp = GetEnvironment().getEnvp(); }
+
+ SBLaunchInfoImpl &operator=(const ProcessLaunchInfo &rhs) {
+ ProcessLaunchInfo::operator=(rhs);
+ RegenerateEnvp();
+ return *this;
+ }
+
+private:
+ Environment::Envp m_envp;
+};
+
SBLaunchInfo::SBLaunchInfo(const char **argv)
- : m_opaque_sp(new ProcessLaunchInfo()) {
+ : m_opaque_sp(new SBLaunchInfoImpl()) {
m_opaque_sp->GetFlags().Reset(eLaunchFlagDebug | eLaunchFlagDisableASLR);
if (argv && argv[0])
m_opaque_sp->GetArguments().SetArguments(argv);
@@ -25,12 +43,14 @@ SBLaunchInfo::SBLaunchInfo(const char **argv)
SBLaunchInfo::~SBLaunchInfo() {}
-lldb_private::ProcessLaunchInfo &SBLaunchInfo::ref() { return *m_opaque_sp; }
-
const lldb_private::ProcessLaunchInfo &SBLaunchInfo::ref() const {
return *m_opaque_sp;
}
+void SBLaunchInfo::set_ref(const ProcessLaunchInfo &info) {
+ *m_opaque_sp = info;
+}
+
lldb::pid_t SBLaunchInfo::GetProcessID() { return m_opaque_sp->GetProcessID(); }
uint32_t SBLaunchInfo::GetUserID() { return m_opaque_sp->GetUserID(); }
@@ -83,23 +103,22 @@ void SBLaunchInfo::SetArguments(const char **argv, bool append) {
}
uint32_t SBLaunchInfo::GetNumEnvironmentEntries() {
- return m_opaque_sp->GetEnvironmentEntries().GetArgumentCount();
+ return m_opaque_sp->GetEnvironment().size();
}
const char *SBLaunchInfo::GetEnvironmentEntryAtIndex(uint32_t idx) {
- return m_opaque_sp->GetEnvironmentEntries().GetArgumentAtIndex(idx);
+ if (idx > GetNumEnvironmentEntries())
+ return nullptr;
+ return m_opaque_sp->GetEnvp()[idx];
}
void SBLaunchInfo::SetEnvironmentEntries(const char **envp, bool append) {
- if (append) {
- if (envp)
- m_opaque_sp->GetEnvironmentEntries().AppendArguments(envp);
- } else {
- if (envp)
- m_opaque_sp->GetEnvironmentEntries().SetArguments(envp);
- else
- m_opaque_sp->GetEnvironmentEntries().Clear();
- }
+ Environment env(envp);
+ if (append)
+ m_opaque_sp->GetEnvironment().insert(env.begin(), env.end());
+ else
+ m_opaque_sp->GetEnvironment() = env;
+ m_opaque_sp->RegenerateEnvp();
}
void SBLaunchInfo::Clear() { m_opaque_sp->Clear(); }
@@ -129,8 +148,8 @@ void SBLaunchInfo::SetProcessPluginName(const char *plugin_name) {
}
const char *SBLaunchInfo::GetShell() {
- // Constify this string so that it is saved in the string pool. Otherwise
- // it would be freed when this function goes out of scope.
+ // Constify this string so that it is saved in the string pool. Otherwise it
+ // would be freed when this function goes out of scope.
ConstString shell(m_opaque_sp->GetShell().GetPath().c_str());
return shell.AsCString();
}
diff --git a/source/API/SBModule.cpp b/source/API/SBModule.cpp
index 17f3dcc5656d..3dd99d5321b4 100644
--- a/source/API/SBModule.cpp
+++ b/source/API/SBModule.cpp
@@ -144,7 +144,7 @@ const uint8_t *SBModule::GetUUIDBytes() const {
const uint8_t *uuid_bytes = NULL;
ModuleSP module_sp(GetSP());
if (module_sp)
- uuid_bytes = (const uint8_t *)module_sp->GetUUID().GetBytes();
+ uuid_bytes = module_sp->GetUUID().GetBytes().data();
if (log) {
if (uuid_bytes) {
@@ -165,11 +165,10 @@ const char *SBModule::GetUUIDString() const {
const char *uuid_cstr = NULL;
ModuleSP module_sp(GetSP());
if (module_sp) {
- // We are going to return a "const char *" value through the public
- // API, so we need to constify it so it gets added permanently the
- // string pool and then we don't need to worry about the lifetime of the
- // string as it will never go away once it has been put into the ConstString
- // string pool
+ // We are going to return a "const char *" value through the public API, so
+ // we need to constify it so it gets added permanently the string pool and
+ // then we don't need to worry about the lifetime of the string as it will
+ // never go away once it has been put into the ConstString string pool
uuid_cstr = ConstString(module_sp->GetUUID().GetAsString()).GetCString();
}
@@ -254,6 +253,17 @@ SBCompileUnit SBModule::GetCompileUnitAtIndex(uint32_t index) {
return sb_cu;
}
+SBSymbolContextList
+SBModule::FindCompileUnits(const SBFileSpec &sb_file_spec) {
+ SBSymbolContextList sb_sc_list;
+ const ModuleSP module_sp(GetSP());
+ if (sb_file_spec.IsValid() && module_sp) {
+ const bool append = true;
+ module_sp->FindCompileUnits(*sb_file_spec, append, *sb_sc_list);
+ }
+ return sb_sc_list;
+}
+
static Symtab *GetUnifiedSymbolTable(const lldb::ModuleSP &module_sp) {
if (module_sp) {
SymbolVendor *symbols = module_sp->GetSymbolVendor();
@@ -368,7 +378,7 @@ SBValueList SBModule::FindGlobalVariables(SBTarget &target, const char *name,
if (name && module_sp) {
VariableList variable_list;
const uint32_t match_count = module_sp->FindGlobalVariables(
- ConstString(name), NULL, false, max_matches, variable_list);
+ ConstString(name), NULL, max_matches, variable_list);
if (match_count > 0) {
for (uint32_t i = 0; i < match_count; ++i) {
@@ -515,9 +525,9 @@ const char *SBModule::GetTriple() {
ModuleSP module_sp(GetSP());
if (module_sp) {
std::string triple(module_sp->GetArchitecture().GetTriple().str());
- // Unique the string so we don't run into ownership issues since
- // the const strings put the string into the string pool once and
- // the strings never comes out
+ // Unique the string so we don't run into ownership issues since the const
+ // strings put the string into the string pool once and the strings never
+ // comes out
ConstString const_triple(triple.c_str());
return const_triple.GetCString();
}
@@ -532,16 +542,29 @@ uint32_t SBModule::GetAddressByteSize() {
}
uint32_t SBModule::GetVersion(uint32_t *versions, uint32_t num_versions) {
- ModuleSP module_sp(GetSP());
- if (module_sp)
- return module_sp->GetVersion(versions, num_versions);
- else {
- if (versions && num_versions) {
- for (uint32_t i = 0; i < num_versions; ++i)
- versions[i] = UINT32_MAX;
- }
- return 0;
- }
+ llvm::VersionTuple version;
+ if (ModuleSP module_sp = GetSP())
+ version = module_sp->GetVersion();
+ uint32_t result = 0;
+ if (!version.empty())
+ ++result;
+ if (version.getMinor())
+ ++result;
+ if(version.getSubminor())
+ ++result;
+
+ if (!versions)
+ return result;
+
+ if (num_versions > 0)
+ versions[0] = version.empty() ? UINT32_MAX : version.getMajor();
+ if (num_versions > 1)
+ versions[1] = version.getMinor().getValueOr(UINT32_MAX);
+ if (num_versions > 2)
+ versions[2] = version.getSubminor().getValueOr(UINT32_MAX);
+ for (uint32_t i = 3; i < num_versions; ++i)
+ versions[i] = UINT32_MAX;
+ return result;
}
lldb::SBFileSpec SBModule::GetSymbolFileSpec() const {
diff --git a/source/API/SBModuleSpec.cpp b/source/API/SBModuleSpec.cpp
index a1c08865c6a4..afabd9ace2b9 100644
--- a/source/API/SBModuleSpec.cpp
+++ b/source/API/SBModuleSpec.cpp
@@ -70,9 +70,9 @@ void SBModuleSpec::SetObjectName(const char *name) {
const char *SBModuleSpec::GetTriple() {
std::string triple(m_opaque_ap->GetArchitecture().GetTriple().str());
- // Unique the string so we don't run into ownership issues since
- // the const strings put the string into the string pool once and
- // the strings never comes out
+ // Unique the string so we don't run into ownership issues since the const
+ // strings put the string into the string pool once and the strings never
+ // comes out
ConstString const_triple(triple.c_str());
return const_triple.GetCString();
}
@@ -82,15 +82,16 @@ void SBModuleSpec::SetTriple(const char *triple) {
}
const uint8_t *SBModuleSpec::GetUUIDBytes() {
- return (const uint8_t *)m_opaque_ap->GetUUID().GetBytes();
+ return m_opaque_ap->GetUUID().GetBytes().data();
}
size_t SBModuleSpec::GetUUIDLength() {
- return m_opaque_ap->GetUUID().GetByteSize();
+ return m_opaque_ap->GetUUID().GetBytes().size();
}
bool SBModuleSpec::SetUUIDBytes(const uint8_t *uuid, size_t uuid_len) {
- return m_opaque_ap->GetUUID().SetBytes(uuid, uuid_len);
+ m_opaque_ap->GetUUID() = UUID::fromOptionalData(uuid, uuid_len);
+ return m_opaque_ap->GetUUID().IsValid();
}
bool SBModuleSpec::GetDescription(lldb::SBStream &description) {
diff --git a/source/API/SBPlatform.cpp b/source/API/SBPlatform.cpp
index 7ec43f13021f..5f29f0033988 100644
--- a/source/API/SBPlatform.cpp
+++ b/source/API/SBPlatform.cpp
@@ -13,10 +13,10 @@
#include "lldb/API/SBLaunchInfo.h"
#include "lldb/API/SBUnixSignals.h"
#include "lldb/Host/File.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/Status.h"
#include "llvm/Support/FileSystem.h"
@@ -53,8 +53,7 @@ struct PlatformConnectOptions {
//----------------------------------------------------------------------
struct PlatformShellCommand {
PlatformShellCommand(const char *shell_command = NULL)
- : m_command(), m_working_dir(), m_status(0), m_signo(0),
- m_timeout_sec(UINT32_MAX) {
+ : m_command(), m_working_dir(), m_status(0), m_signo(0) {
if (shell_command && shell_command[0])
m_command = shell_command;
}
@@ -66,7 +65,7 @@ struct PlatformShellCommand {
std::string m_output;
int m_status;
int m_signo;
- uint32_t m_timeout_sec;
+ Timeout<std::ratio<1>> m_timeout = llvm::None;
};
//----------------------------------------------------------------------
// SBPlatformConnectOptions
@@ -182,11 +181,16 @@ void SBPlatformShellCommand::SetWorkingDirectory(const char *path) {
}
uint32_t SBPlatformShellCommand::GetTimeoutSeconds() {
- return m_opaque_ptr->m_timeout_sec;
+ if (m_opaque_ptr->m_timeout)
+ return m_opaque_ptr->m_timeout->count();
+ return UINT32_MAX;
}
void SBPlatformShellCommand::SetTimeoutSeconds(uint32_t sec) {
- m_opaque_ptr->m_timeout_sec = sec;
+ if (sec == UINT32_MAX)
+ m_opaque_ptr->m_timeout = llvm::None;
+ else
+ m_opaque_ptr->m_timeout = std::chrono::seconds(sec);
}
int SBPlatformShellCommand::GetSignal() { return m_opaque_ptr->m_signo; }
@@ -271,7 +275,7 @@ void SBPlatform::DisconnectRemote() {
bool SBPlatform::IsConnected() {
PlatformSP platform_sp(GetSP());
if (platform_sp)
- platform_sp->IsConnected();
+ return platform_sp->IsConnected();
return false;
}
@@ -326,27 +330,24 @@ const char *SBPlatform::GetHostname() {
}
uint32_t SBPlatform::GetOSMajorVersion() {
- uint32_t major, minor, update;
- PlatformSP platform_sp(GetSP());
- if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
- return major;
- return UINT32_MAX;
+ llvm::VersionTuple version;
+ if (PlatformSP platform_sp = GetSP())
+ version = platform_sp->GetOSVersion();
+ return version.empty() ? UINT32_MAX : version.getMajor();
}
uint32_t SBPlatform::GetOSMinorVersion() {
- uint32_t major, minor, update;
- PlatformSP platform_sp(GetSP());
- if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
- return minor;
- return UINT32_MAX;
+ llvm::VersionTuple version;
+ if (PlatformSP platform_sp = GetSP())
+ version = platform_sp->GetOSVersion();
+ return version.getMinor().getValueOr(UINT32_MAX);
}
uint32_t SBPlatform::GetOSUpdateVersion() {
- uint32_t major, minor, update;
- PlatformSP platform_sp(GetSP());
- if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
- return update;
- return UINT32_MAX;
+ llvm::VersionTuple version;
+ if (PlatformSP platform_sp = GetSP())
+ version = platform_sp->GetOSVersion();
+ return version.getSubminor().getValueOr(UINT32_MAX);
}
SBError SBPlatform::Get(SBFileSpec &src, SBFileSpec &dst) {
@@ -405,18 +406,20 @@ SBError SBPlatform::Run(SBPlatformShellCommand &shell_command) {
if (working_dir)
shell_command.SetWorkingDirectory(working_dir);
}
- return platform_sp->RunShellCommand(
- command, FileSpec{working_dir, false},
- &shell_command.m_opaque_ptr->m_status,
- &shell_command.m_opaque_ptr->m_signo,
- &shell_command.m_opaque_ptr->m_output,
- shell_command.m_opaque_ptr->m_timeout_sec);
+ return platform_sp->RunShellCommand(command, FileSpec{working_dir, false},
+ &shell_command.m_opaque_ptr->m_status,
+ &shell_command.m_opaque_ptr->m_signo,
+ &shell_command.m_opaque_ptr->m_output,
+ shell_command.m_opaque_ptr->m_timeout);
});
}
SBError SBPlatform::Launch(SBLaunchInfo &launch_info) {
return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
- return platform_sp->LaunchProcess(launch_info.ref());
+ ProcessLaunchInfo info = launch_info.ref();
+ Status error = platform_sp->LaunchProcess(info);
+ launch_info.set_ref(info);
+ return error;
});
}
diff --git a/source/API/SBProcess.cpp b/source/API/SBProcess.cpp
index e08a7f4b08e0..4d5ddc86ccf9 100644
--- a/source/API/SBProcess.cpp
+++ b/source/API/SBProcess.cpp
@@ -20,13 +20,13 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/State.h"
#include "lldb/Core/StreamFile.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/SystemRuntime.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Stream.h"
@@ -140,7 +140,7 @@ bool SBProcess::RemoteLaunch(char const **argv, char const **envp,
if (argv)
launch_info.GetArguments().AppendArguments(argv);
if (envp)
- launch_info.GetEnvironmentEntries().SetArguments(envp);
+ launch_info.GetEnvironment() = Environment(envp);
error.SetError(process_sp->Launch(launch_info));
} else {
error.SetErrorString("must be in eStateConnected to call RemoteLaunch");
@@ -896,8 +896,7 @@ SBProcess SBProcess::GetProcessFromEvent(const SBEvent &event) {
ProcessSP process_sp =
Process::ProcessEventData::GetProcessFromEvent(event.get());
if (!process_sp) {
- // StructuredData events also know the process they come from.
- // Try that.
+ // StructuredData events also know the process they come from. Try that.
process_sp = EventDataStructuredData::GetProcessFromEvent(event.get());
}
@@ -1188,6 +1187,57 @@ uint32_t SBProcess::LoadImage(const lldb::SBFileSpec &sb_local_image_spec,
return LLDB_INVALID_IMAGE_TOKEN;
}
+uint32_t SBProcess::LoadImageUsingPaths(const lldb::SBFileSpec &image_spec,
+ SBStringList &paths,
+ lldb::SBFileSpec &loaded_path,
+ lldb::SBError &error) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+ ProcessSP process_sp(GetSP());
+ if (process_sp) {
+ Process::StopLocker stop_locker;
+ if (stop_locker.TryLock(&process_sp->GetRunLock())) {
+ if (log)
+ log->Printf("SBProcess(%p)::LoadImageUsingPaths() => "
+ "calling Platform::LoadImageUsingPaths for: %s",
+ static_cast<void *>(process_sp.get()),
+ image_spec.GetFilename());
+
+ std::lock_guard<std::recursive_mutex> guard(
+ process_sp->GetTarget().GetAPIMutex());
+ PlatformSP platform_sp = process_sp->GetTarget().GetPlatform();
+ size_t num_paths = paths.GetSize();
+ std::vector<std::string> paths_vec;
+ paths_vec.reserve(num_paths);
+ for (size_t i = 0; i < num_paths; i++)
+ paths_vec.push_back(paths.GetStringAtIndex(i));
+ FileSpec loaded_spec;
+
+ uint32_t token = platform_sp->LoadImageUsingPaths(process_sp.get(),
+ *image_spec,
+ paths_vec,
+ error.ref(),
+ &loaded_spec);
+ if (token != LLDB_INVALID_IMAGE_TOKEN)
+ loaded_path = loaded_spec;
+ return token;
+ } else {
+ if (log)
+ log->Printf("SBProcess(%p)::LoadImageUsingPaths() => error: "
+ "process is running",
+ static_cast<void *>(process_sp.get()));
+ error.SetErrorString("process is running");
+ }
+ } else {
+ if (log)
+ log->Printf("SBProcess(%p)::LoadImageUsingPaths() => error: "
+ "called with invalid process",
+ static_cast<void *>(process_sp.get()));
+ error.SetErrorString("process is invalid");
+ }
+
+ return LLDB_INVALID_IMAGE_TOKEN;
+}
+
lldb::SBError SBProcess::UnloadImage(uint32_t image_token) {
lldb::SBError sb_error;
ProcessSP process_sp(GetSP());
diff --git a/source/API/SBQueueItem.cpp b/source/API/SBQueueItem.cpp
index 87ba73f9e6d3..aac5844240fb 100644
--- a/source/API/SBQueueItem.cpp
+++ b/source/API/SBQueueItem.cpp
@@ -112,8 +112,7 @@ SBThread SBQueueItem::GetExtendedBacktraceThread(const char *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
+ // retains the object
process_sp->GetExtendedThreadList().AddThread(thread_sp);
result.SetThread(thread_sp);
if (log) {
diff --git a/source/API/SBStream.cpp b/source/API/SBStream.cpp
index 159ec07e4e02..d1af77a40fa3 100644
--- a/source/API/SBStream.cpp
+++ b/source/API/SBStream.cpp
@@ -26,8 +26,8 @@ SBStream::~SBStream() {}
bool SBStream::IsValid() const { return (m_opaque_ap.get() != NULL); }
-// If this stream is not redirected to a file, it will maintain a local
-// cache for the stream data which can be accessed using this accessor.
+// If this stream is not redirected to a file, it will maintain a local cache
+// for the stream data which can be accessed using this accessor.
const char *SBStream::GetData() {
if (m_is_file || m_opaque_ap.get() == NULL)
return NULL;
@@ -35,9 +35,8 @@ const char *SBStream::GetData() {
return static_cast<StreamString *>(m_opaque_ap.get())->GetData();
}
-// If this stream is not redirected to a file, it will maintain a local
-// cache for the stream output whose length can be accessed using this
-// accessor.
+// If this stream is not redirected to a file, it will maintain a local cache
+// for the stream output whose length can be accessed using this accessor.
size_t SBStream::GetSize() {
if (m_is_file || m_opaque_ap.get() == NULL)
return 0;
diff --git a/source/API/SBTarget.cpp b/source/API/SBTarget.cpp
index 2c1c6bcac71b..550d336906d3 100644
--- a/source/API/SBTarget.cpp
+++ b/source/API/SBTarget.cpp
@@ -23,6 +23,7 @@
#include "lldb/API/SBSourceManager.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBStringList.h"
+#include "lldb/API/SBStructuredData.h"
#include "lldb/API/SBSymbolContextList.h"
#include "lldb/Breakpoint/BreakpointID.h"
#include "lldb/Breakpoint/BreakpointIDList.h"
@@ -38,11 +39,11 @@
#include "lldb/Core/STLUtils.h"
#include "lldb/Core/SearchFilter.h"
#include "lldb/Core/Section.h"
+#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Host/Host.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/DeclVendor.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -58,11 +59,12 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/TargetList.h"
#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"
-#include "../source/Commands/CommandObjectBreakpoint.h"
+#include "Commands/CommandObjectBreakpoint.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Regex.h"
@@ -82,8 +84,8 @@ Status AttachToProcess(ProcessAttachInfo &attach_info, Target &target) {
const auto state = process_sp->GetState();
if (process_sp->IsAlive() && state == eStateConnected) {
// If we are already connected, then we have already specified the
- // listener, so if a valid listener is supplied, we need to error out
- // to let the client know.
+ // listener, so if a valid listener is supplied, we need to error out to
+ // let the client know.
if (attach_info.GetListener())
return Status("process is connected and already has a listener, pass "
"empty listener");
@@ -181,7 +183,31 @@ SBDebugger SBTarget::GetDebugger() const {
return debugger;
}
+SBStructuredData SBTarget::GetStatistics() {
+ SBStructuredData data;
+ TargetSP target_sp(GetSP());
+ if (!target_sp)
+ return data;
+
+ auto stats_up = llvm::make_unique<StructuredData::Dictionary>();
+ int i = 0;
+ for (auto &Entry : target_sp->GetStatistics()) {
+ std::string Desc = lldb_private::GetStatDescription(
+ static_cast<lldb_private::StatisticKind>(i));
+ stats_up->AddIntegerItem(Desc, Entry);
+ i += 1;
+ }
+
+ data.m_impl_up->SetObjectSP(std::move(stats_up));
+ return data;
+}
+
SBProcess SBTarget::LoadCore(const char *core_file) {
+ lldb::SBError error; // Ignored
+ return LoadCore(core_file, error);
+}
+
+SBProcess SBTarget::LoadCore(const char *core_file, lldb::SBError &error) {
SBProcess sb_process;
TargetSP target_sp(GetSP());
if (target_sp) {
@@ -189,9 +215,14 @@ SBProcess SBTarget::LoadCore(const char *core_file) {
ProcessSP process_sp(target_sp->CreateProcess(
target_sp->GetDebugger().GetListener(), "", &filespec));
if (process_sp) {
- process_sp->LoadCore();
- sb_process.SetSP(process_sp);
+ error.SetError(process_sp->LoadCore());
+ if (error.Success())
+ sb_process.SetSP(process_sp);
+ } else {
+ error.SetErrorString("Failed to create the process");
}
+ } else {
+ error.SetErrorString("SBTarget is invalid");
}
return sb_process;
}
@@ -267,8 +298,8 @@ SBProcess SBTarget::Launch(SBListener &listener, char const **argv,
if (state == eStateConnected) {
// If we are already connected, then we have already specified the
- // listener, so if a valid listener is supplied, we need to error out
- // to let the client know.
+ // listener, so if a valid listener is supplied, we need to error out to
+ // let the client know.
if (listener.IsValid()) {
error.SetErrorString("process is connected and already has a listener, "
"pass empty listener");
@@ -290,7 +321,7 @@ SBProcess SBTarget::Launch(SBListener &listener, char const **argv,
if (argv)
launch_info.GetArguments().AppendArguments(argv);
if (envp)
- launch_info.GetEnvironmentEntries().SetArguments(envp);
+ launch_info.GetEnvironment() = Environment(envp);
if (listener.IsValid())
launch_info.SetListener(listener.GetSP());
@@ -340,7 +371,7 @@ SBProcess SBTarget::Launch(SBLaunchInfo &sb_launch_info, SBError &error) {
}
}
- lldb_private::ProcessLaunchInfo &launch_info = sb_launch_info.ref();
+ lldb_private::ProcessLaunchInfo launch_info = sb_launch_info.ref();
if (!launch_info.GetExecutableFile()) {
Module *exe_module = target_sp->GetExecutableModulePointer();
@@ -353,6 +384,7 @@ SBProcess SBTarget::Launch(SBLaunchInfo &sb_launch_info, SBError &error) {
launch_info.GetArchitecture() = arch_spec;
error.SetError(target_sp->Launch(launch_info, NULL));
+ sb_launch_info.set_ref(launch_info);
sb_process.SetSP(target_sp->GetProcessSP());
} else {
error.SetErrorString("SBTarget is invalid");
@@ -469,7 +501,8 @@ lldb::SBProcess SBTarget::AttachToProcessWithName(
if (name && target_sp) {
ProcessAttachInfo attach_info;
- attach_info.GetExecutableFile().SetFile(name, false);
+ attach_info.GetExecutableFile().SetFile(name, false,
+ FileSpec::Style::native);
attach_info.SetWaitForLaunch(wait_for);
if (listener.IsValid())
attach_info.SetListener(listener.GetSP());
@@ -1436,10 +1469,10 @@ lldb::SBModule SBTarget::AddModule(const char *path, const char *triple,
if (target_sp) {
ModuleSpec module_spec;
if (path)
- module_spec.GetFileSpec().SetFile(path, false);
+ module_spec.GetFileSpec().SetFile(path, false, FileSpec::Style::native);
if (uuid_cstr)
- module_spec.GetUUID().SetFromCString(uuid_cstr);
+ module_spec.GetUUID().SetFromStringRef(uuid_cstr);
if (triple)
module_spec.GetArchitecture() = Platform::GetAugmentedArchSpec(
@@ -1448,7 +1481,8 @@ lldb::SBModule SBTarget::AddModule(const char *path, const char *triple,
module_spec.GetArchitecture() = target_sp->GetArchitecture();
if (symfile)
- module_spec.GetSymbolFileSpec().SetFile(symfile, false);
+ module_spec.GetSymbolFileSpec().SetFile(symfile, false,
+ FileSpec::Style::native);
sb_module.SetSP(target_sp->GetSharedModule(module_spec));
}
@@ -1510,6 +1544,18 @@ SBModule SBTarget::FindModule(const SBFileSpec &sb_file_spec) {
return sb_module;
}
+SBSymbolContextList
+SBTarget::FindCompileUnits(const SBFileSpec &sb_file_spec) {
+ SBSymbolContextList sb_sc_list;
+ const TargetSP target_sp(GetSP());
+ if (target_sp && sb_file_spec.IsValid()) {
+ const bool append = true;
+ target_sp->GetImages().FindCompileUnits(*sb_file_spec,
+ append, *sb_sc_list);
+ }
+ return sb_sc_list;
+}
+
lldb::ByteOrder SBTarget::GetByteOrder() {
TargetSP target_sp(GetSP());
if (target_sp)
@@ -1521,9 +1567,9 @@ const char *SBTarget::GetTriple() {
TargetSP target_sp(GetSP());
if (target_sp) {
std::string triple(target_sp->GetArchitecture().GetTriple().str());
- // Unique the string so we don't run into ownership issues since
- // the const strings put the string into the string pool once and
- // the strings never comes out
+ // Unique the string so we don't run into ownership issues since the const
+ // strings put the string into the string pool once and the strings never
+ // comes out
ConstString const_triple(triple.c_str());
return const_triple.GetCString();
}
@@ -1673,8 +1719,8 @@ lldb::SBType SBTarget::FindFirstType(const char *typename_cstr) {
}
}
- // Didn't find the type in the symbols; try the Objective-C runtime
- // if one is installed
+ // Didn't find the type in the symbols; try the Objective-C runtime if one
+ // is installed
ProcessSP process_sp(target_sp->GetProcessSP());
@@ -1782,9 +1828,8 @@ SBValueList SBTarget::FindGlobalVariables(const char *name,
TargetSP target_sp(GetSP());
if (name && target_sp) {
VariableList variable_list;
- const bool append = true;
const uint32_t match_count = target_sp->GetImages().FindGlobalVariables(
- ConstString(name), append, max_matches, variable_list);
+ ConstString(name), max_matches, variable_list);
if (match_count > 0) {
ExecutionContextScope *exe_scope = target_sp->GetProcessSP().get();
@@ -1811,23 +1856,22 @@ SBValueList SBTarget::FindGlobalVariables(const char *name,
if (name && target_sp) {
llvm::StringRef name_ref(name);
VariableList variable_list;
- const bool append = true;
std::string regexstr;
uint32_t match_count;
switch (matchtype) {
case eMatchTypeNormal:
match_count = target_sp->GetImages().FindGlobalVariables(
- ConstString(name), append, max_matches, variable_list);
+ ConstString(name), max_matches, variable_list);
break;
case eMatchTypeRegex:
match_count = target_sp->GetImages().FindGlobalVariables(
- RegularExpression(name_ref), append, max_matches, variable_list);
+ RegularExpression(name_ref), max_matches, variable_list);
break;
case eMatchTypeStartsWith:
regexstr = llvm::Regex::escape(name) + ".*";
match_count = target_sp->GetImages().FindGlobalVariables(
- RegularExpression(regexstr), append, max_matches, variable_list);
+ RegularExpression(regexstr), max_matches, variable_list);
break;
}
@@ -2195,7 +2239,7 @@ lldb::SBLaunchInfo SBTarget::GetLaunchInfo() const {
lldb::SBLaunchInfo launch_info(NULL);
TargetSP target_sp(GetSP());
if (target_sp)
- launch_info.ref() = m_opaque_sp->GetProcessLaunchInfo();
+ launch_info.set_ref(m_opaque_sp->GetProcessLaunchInfo());
return launch_info;
}
diff --git a/source/API/SBThread.cpp b/source/API/SBThread.cpp
index b34489603c8a..0d25b85f57d2 100644
--- a/source/API/SBThread.cpp
+++ b/source/API/SBThread.cpp
@@ -615,8 +615,7 @@ SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
}
// User level plans should be Master Plans so they can be interrupted, other
- // plans executed, and
- // then a "continue" will resume the plan.
+ // plans executed, and then a "continue" will resume the plan.
if (new_plan != NULL) {
new_plan->SetIsMasterPlan(true);
new_plan->SetOkayToDiscard(false);
@@ -634,6 +633,11 @@ SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
}
void SBThread::StepOver(lldb::RunMode stop_other_threads) {
+ SBError error; // Ignored
+ StepOver(stop_other_threads, error);
+}
+
+void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
std::unique_lock<std::recursive_mutex> lock;
@@ -644,28 +648,29 @@ void SBThread::StepOver(lldb::RunMode stop_other_threads) {
static_cast<void *>(exe_ctx.GetThreadPtr()),
Thread::RunModeAsCString(stop_other_threads));
- if (exe_ctx.HasThreadScope()) {
- Thread *thread = exe_ctx.GetThreadPtr();
- bool abort_other_plans = false;
- StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
+ if (!exe_ctx.HasThreadScope()) {
+ error.SetErrorString("this SBThread object is invalid");
+ return;
+ }
- ThreadPlanSP new_plan_sp;
- if (frame_sp) {
- 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, sc, stop_other_threads,
- avoid_no_debug);
- } else {
- new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
- true, abort_other_plans, stop_other_threads);
- }
- }
+ Thread *thread = exe_ctx.GetThreadPtr();
+ bool abort_other_plans = false;
+ StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
- // This returns an error, we should use it!
- ResumeNewPlan(exe_ctx, new_plan_sp.get());
+ ThreadPlanSP new_plan_sp;
+ if (frame_sp) {
+ 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, sc, stop_other_threads,
+ avoid_no_debug);
+ } else {
+ new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
+ true, abort_other_plans, stop_other_threads);
+ }
}
+ error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
}
void SBThread::StepInto(lldb::RunMode stop_other_threads) {
@@ -674,7 +679,7 @@ void SBThread::StepInto(lldb::RunMode stop_other_threads) {
void SBThread::StepInto(const char *target_name,
lldb::RunMode stop_other_threads) {
- SBError error;
+ SBError error; // Ignored
StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
}
@@ -692,41 +697,48 @@ void SBThread::StepInto(const char *target_name, uint32_t end_line,
target_name ? target_name : "<NULL>",
Thread::RunModeAsCString(stop_other_threads));
- if (exe_ctx.HasThreadScope()) {
- bool abort_other_plans = false;
+ if (!exe_ctx.HasThreadScope()) {
+ error.SetErrorString("this SBThread object is invalid");
+ return;
+ }
- Thread *thread = exe_ctx.GetThreadPtr();
- StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
- ThreadPlanSP new_plan_sp;
+ bool abort_other_plans = false;
- if (frame_sp && frame_sp->HasDebugInformation()) {
- SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
- AddressRange range;
- if (end_line == LLDB_INVALID_LINE_NUMBER)
- range = sc.line_entry.range;
- else {
- if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
- return;
- }
+ Thread *thread = exe_ctx.GetThreadPtr();
+ StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
+ ThreadPlanSP new_plan_sp;
- const LazyBool step_out_avoids_code_without_debug_info =
- eLazyBoolCalculate;
- const LazyBool step_in_avoids_code_without_debug_info =
- eLazyBoolCalculate;
- new_plan_sp = thread->QueueThreadPlanForStepInRange(
- abort_other_plans, range, sc, target_name, stop_other_threads,
- 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);
+ if (frame_sp && frame_sp->HasDebugInformation()) {
+ SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
+ AddressRange range;
+ if (end_line == LLDB_INVALID_LINE_NUMBER)
+ range = sc.line_entry.range;
+ else {
+ if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
+ return;
}
- error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
+ const LazyBool step_out_avoids_code_without_debug_info =
+ eLazyBoolCalculate;
+ const LazyBool step_in_avoids_code_without_debug_info =
+ eLazyBoolCalculate;
+ new_plan_sp = thread->QueueThreadPlanForStepInRange(
+ abort_other_plans, range, sc, target_name, stop_other_threads,
+ 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);
}
+ error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
}
void SBThread::StepOut() {
+ SBError error; // Ignored
+ StepOut(error);
+}
+
+void SBThread::StepOut(SBError &error) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
std::unique_lock<std::recursive_mutex> lock;
@@ -736,23 +748,30 @@ void SBThread::StepOut() {
log->Printf("SBThread(%p)::StepOut ()",
static_cast<void *>(exe_ctx.GetThreadPtr()));
- if (exe_ctx.HasThreadScope()) {
- bool abort_other_plans = false;
- bool stop_other_threads = false;
+ if (!exe_ctx.HasThreadScope()) {
+ error.SetErrorString("this SBThread object is invalid");
+ return;
+ }
- Thread *thread = exe_ctx.GetThreadPtr();
+ bool abort_other_plans = false;
+ bool stop_other_threads = false;
- const LazyBool avoid_no_debug = eLazyBoolCalculate;
- ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
- abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
- eVoteNoOpinion, 0, avoid_no_debug));
+ Thread *thread = exe_ctx.GetThreadPtr();
- // This returns an error, we should use it!
- ResumeNewPlan(exe_ctx, new_plan_sp.get());
- }
+ const LazyBool avoid_no_debug = eLazyBoolCalculate;
+ ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
+ abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
+ eVoteNoOpinion, 0, avoid_no_debug));
+
+ error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
+}
+
+void SBThread::StepOutOfFrame(SBFrame &sb_frame) {
+ SBError error; // Ignored
+ StepOutOfFrame(sb_frame, error);
}
-void SBThread::StepOutOfFrame(lldb::SBFrame &sb_frame) {
+void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
std::unique_lock<std::recursive_mutex> lock;
@@ -763,6 +782,7 @@ void SBThread::StepOutOfFrame(lldb::SBFrame &sb_frame) {
log->Printf(
"SBThread(%p)::StepOutOfFrame passed an invalid frame, returning.",
static_cast<void *>(exe_ctx.GetThreadPtr()));
+ error.SetErrorString("passed invalid SBFrame object");
return;
}
@@ -775,27 +795,36 @@ void SBThread::StepOutOfFrame(lldb::SBFrame &sb_frame) {
static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
}
- if (exe_ctx.HasThreadScope()) {
- bool abort_other_plans = false;
- bool stop_other_threads = false;
- Thread *thread = exe_ctx.GetThreadPtr();
- if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
- log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another "
- "thread (0x%" PRIx64 " vrs. 0x%" PRIx64 ", returning.",
- static_cast<void *>(exe_ctx.GetThreadPtr()),
- sb_frame.GetThread().GetThreadID(), thread->GetID());
- }
-
- ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
- abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
- eVoteNoOpinion, frame_sp->GetFrameIndex()));
+ if (!exe_ctx.HasThreadScope()) {
+ error.SetErrorString("this SBThread object is invalid");
+ return;
+ }
- // This returns an error, we should use it!
- ResumeNewPlan(exe_ctx, new_plan_sp.get());
+ bool abort_other_plans = false;
+ bool stop_other_threads = false;
+ Thread *thread = exe_ctx.GetThreadPtr();
+ if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
+ log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another "
+ "thread (0x%" PRIx64 " vrs. 0x%" PRIx64 ", returning.",
+ static_cast<void *>(exe_ctx.GetThreadPtr()),
+ sb_frame.GetThread().GetThreadID(), thread->GetID());
+ error.SetErrorString("passed a frame from another thread");
+ return;
}
+
+ ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
+ abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
+ eVoteNoOpinion, frame_sp->GetFrameIndex()));
+
+ error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
}
void SBThread::StepInstruction(bool step_over) {
+ SBError error; // Ignored
+ StepInstruction(step_over, error);
+}
+
+void SBThread::StepInstruction(bool step_over, SBError &error) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
std::unique_lock<std::recursive_mutex> lock;
@@ -805,17 +834,24 @@ void SBThread::StepInstruction(bool step_over) {
log->Printf("SBThread(%p)::StepInstruction (step_over=%i)",
static_cast<void *>(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());
+ if (!exe_ctx.HasThreadScope()) {
+ error.SetErrorString("this SBThread object is invalid");
+ return;
}
+
+ Thread *thread = exe_ctx.GetThreadPtr();
+ ThreadPlanSP new_plan_sp(
+ thread->QueueThreadPlanForStepSingleInstruction(step_over, true, true));
+
+ error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
}
void SBThread::RunToAddress(lldb::addr_t addr) {
+ SBError error; // Ignored
+ RunToAddress(addr, error);
+}
+
+void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
std::unique_lock<std::recursive_mutex> lock;
@@ -825,20 +861,22 @@ void SBThread::RunToAddress(lldb::addr_t addr) {
log->Printf("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")",
static_cast<void *>(exe_ctx.GetThreadPtr()), addr);
- if (exe_ctx.HasThreadScope()) {
- bool abort_other_plans = false;
- bool stop_other_threads = true;
+ if (!exe_ctx.HasThreadScope()) {
+ error.SetErrorString("this SBThread object is invalid");
+ return;
+ }
- Address target_addr(addr);
+ bool abort_other_plans = false;
+ bool stop_other_threads = true;
- Thread *thread = exe_ctx.GetThreadPtr();
+ Address target_addr(addr);
- ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
- abort_other_plans, target_addr, stop_other_threads));
+ Thread *thread = exe_ctx.GetThreadPtr();
- // This returns an error, we should use it!
- ResumeNewPlan(exe_ctx, new_plan_sp.get());
- }
+ ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
+ abort_other_plans, target_addr, stop_other_threads));
+
+ error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
}
SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
@@ -911,8 +949,7 @@ SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
// 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.
+ // appropriate error message.
bool all_in_function = true;
AddressRange fun_range = frame_sc.function->GetAddressRange();
@@ -1084,6 +1121,11 @@ SBError SBThread::UnwindInnermostExpression() {
}
bool SBThread::Suspend() {
+ SBError error; // Ignored
+ return Suspend(error);
+}
+
+bool SBThread::Suspend(SBError &error) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
std::unique_lock<std::recursive_mutex> lock;
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
@@ -1095,11 +1137,13 @@ bool SBThread::Suspend() {
exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
result = true;
} else {
+ error.SetErrorString("process is running");
if (log)
log->Printf("SBThread(%p)::Suspend() => error: process is running",
static_cast<void *>(exe_ctx.GetThreadPtr()));
}
- }
+ } else
+ error.SetErrorString("this SBThread object is invalid");
if (log)
log->Printf("SBThread(%p)::Suspend() => %i",
static_cast<void *>(exe_ctx.GetThreadPtr()), result);
@@ -1107,6 +1151,11 @@ bool SBThread::Suspend() {
}
bool SBThread::Resume() {
+ SBError error; // Ignored
+ return Resume(error);
+}
+
+bool SBThread::Resume(SBError &error) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
std::unique_lock<std::recursive_mutex> lock;
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
@@ -1119,11 +1168,13 @@ bool SBThread::Resume() {
exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
result = true;
} else {
+ error.SetErrorString("process is running");
if (log)
log->Printf("SBThread(%p)::Resume() => error: process is running",
static_cast<void *>(exe_ctx.GetThreadPtr()));
}
- }
+ } else
+ error.SetErrorString("this SBThread object is invalid");
if (log)
log->Printf("SBThread(%p)::Resume() => %i",
static_cast<void *>(exe_ctx.GetThreadPtr()), result);
@@ -1374,8 +1425,7 @@ SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
runtime->GetExtendedBacktraceThread(real_thread, type_const));
if (new_thread_sp) {
// Save this in the Process' ExtendedThreadList so a strong
- // pointer retains the
- // object.
+ // pointer retains the object.
process->GetExtendedThreadList().AddThread(new_thread_sp);
sb_origin_thread.SetThread(new_thread_sp);
if (log) {
diff --git a/source/API/SBThreadPlan.cpp b/source/API/SBThreadPlan.cpp
index a19023f66de2..131f84195908 100644
--- a/source/API/SBThreadPlan.cpp
+++ b/source/API/SBThreadPlan.cpp
@@ -138,8 +138,7 @@ bool SBThreadPlan::IsValid() {
// plans...
//
// FIXME, you should only be able to queue thread plans from inside the methods
-// of a
-// Scripted Thread Plan. Need a way to enforce that.
+// of a Scripted Thread Plan. Need a way to enforce that.
SBThreadPlan
SBThreadPlan::QueueThreadPlanForStepOverRange(SBAddress &sb_start_address,
diff --git a/source/API/SBType.cpp b/source/API/SBType.cpp
index 80d48754c89b..e199b7a33e48 100644
--- a/source/API/SBType.cpp
+++ b/source/API/SBType.cpp
@@ -88,9 +88,9 @@ TypeImpl &SBType::ref() {
}
const TypeImpl &SBType::ref() const {
- // "const SBAddress &addr" should already have checked "addr.IsValid()"
- // prior to calling this function. In case you didn't we will assert
- // and die to let you know.
+ // "const SBAddress &addr" should already have checked "addr.IsValid()" prior
+ // to calling this function. In case you didn't we will assert and die to let
+ // you know.
assert(m_opaque_sp.get());
return *m_opaque_sp;
}
diff --git a/source/API/SBTypeCategory.cpp b/source/API/SBTypeCategory.cpp
index 38e7cca35dfd..30414bd728cb 100644
--- a/source/API/SBTypeCategory.cpp
+++ b/source/API/SBTypeCategory.cpp
@@ -341,9 +341,9 @@ bool SBTypeCategory::AddTypeSummary(SBTypeNameSpecifier type_name,
// FIXME: we need to iterate over all the Debugger objects and have each of
// them contain a copy of the function
// since we currently have formatters live in a global space, while Python
- // code lives in a specific Debugger-related environment
- // this should eventually be fixed by deciding a final location in the LLDB
- // object space for formatters
+ // code lives in a specific Debugger-related environment this should
+ // eventually be fixed by deciding a final location in the LLDB object space
+ // for formatters
if (summary.IsFunctionCode()) {
const void *name_token =
(const void *)ConstString(type_name.GetName()).GetCString();
@@ -453,9 +453,9 @@ bool SBTypeCategory::AddTypeSynthetic(SBTypeNameSpecifier type_name,
// FIXME: we need to iterate over all the Debugger objects and have each of
// them contain a copy of the function
// since we currently have formatters live in a global space, while Python
- // code lives in a specific Debugger-related environment
- // this should eventually be fixed by deciding a final location in the LLDB
- // object space for formatters
+ // code lives in a specific Debugger-related environment this should
+ // eventually be fixed by deciding a final location in the LLDB object space
+ // for formatters
if (synth.IsClassCode()) {
const void *name_token =
(const void *)ConstString(type_name.GetName()).GetCString();
diff --git a/source/API/SBValue.cpp b/source/API/SBValue.cpp
index b6f044c61a78..a270c0471e9f 100644
--- a/source/API/SBValue.cpp
+++ b/source/API/SBValue.cpp
@@ -89,16 +89,13 @@ public:
// FIXME: This check is necessary but not sufficient. We for sure don't
// want to touch SBValues whose owning
// targets have gone away. This check is a little weak in that it
- // enforces that restriction when you call
- // IsValid, but since IsValid doesn't lock the target, you have no
- // guarantee that the SBValue won't go
- // invalid after you call this...
- // Also, an SBValue could depend on data from one of the modules in the
- // target, and those could go away
- // independently of the target, for instance if a module is unloaded. But
- // right now, neither SBValues
- // nor ValueObjects know which modules they depend on. So I have no good
- // way to make that check without
+ // enforces that restriction when you call IsValid, but since IsValid
+ // doesn't lock the target, you have no guarantee that the SBValue won't
+ // go invalid after you call this... Also, an SBValue could depend on
+ // data from one of the modules in the target, and those could go away
+ // independently of the target, for instance if a module is unloaded.
+ // But right now, neither SBValues nor ValueObjects know which modules
+ // they depend on. So I have no good way to make that check without
// tracking that in all the ValueObject subclasses.
TargetSP target_sp = m_valobj_sp->GetTargetSP();
if (target_sp && target_sp->IsValid())
@@ -129,9 +126,9 @@ public:
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.
+ // 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",
static_cast<void *>(value_sp.get()));
@@ -171,10 +168,8 @@ public:
// 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
- // provide simple accessors for these, which I do here.
+ // calculations in GetSP to return the Target, Process, Thread or Frame. It
+ // is convenient to provide simple accessors for these, which I do here.
TargetSP GetTargetSP() {
if (m_valobj_sp)
return m_valobj_sp->GetTargetSP();
@@ -242,9 +237,9 @@ SBValue &SBValue::operator=(const SBValue &rhs) {
SBValue::~SBValue() {}
bool SBValue::IsValid() {
- // If this function ever changes to anything that does more than just
- // check if the opaque shared pointer is non NULL, then we need to update
- // all "if (m_opaque_sp)" code in this file.
+ // If this function ever changes to anything that does more than just check
+ // if the opaque shared pointer is non NULL, then we need to update all "if
+ // (m_opaque_sp)" code in this file.
return m_opaque_sp.get() != NULL && m_opaque_sp->IsValid() &&
m_opaque_sp->GetRootSP().get() != NULL;
}
@@ -1397,11 +1392,9 @@ lldb::SBAddress SBValue::GetAddress() {
if (module_sp)
module_sp->ResolveFileAddress(value, addr);
} else if (addr_type == eAddressTypeLoad) {
- // no need to check the return value on this.. if it can actually do the
- // resolve
- // addr will be in the form (section,offset), otherwise it will simply
- // be returned
- // as (NULL, value)
+ // no need to check the return value on this.. if it can actually do
+ // the resolve addr will be in the form (section,offset), otherwise it
+ // will simply be returned as (NULL, value)
addr.SetLoadAddress(value, target_sp.get());
}
}
diff --git a/source/API/SystemInitializerFull.cpp b/source/API/SystemInitializerFull.cpp
index 977ebe62353e..18de376183c7 100644
--- a/source/API/SystemInitializerFull.cpp
+++ b/source/API/SystemInitializerFull.cpp
@@ -11,7 +11,7 @@
#include "Plugins/ScriptInterpreter/Python/lldb-python.h"
#endif
-#include "lldb/API/SystemInitializerFull.h"
+#include "SystemInitializerFull.h"
#include "lldb/API/SBCommandInterpreter.h"
@@ -43,6 +43,7 @@
#include "Plugins/ABI/SysV-s390x/ABISysV_s390x.h"
#include "Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h"
#include "Plugins/Architecture/Arm/ArchitectureArm.h"
+#include "Plugins/Architecture/PPC64/ArchitecturePPC64.h"
#include "Plugins/Disassembler/llvm/DisassemblerLLVMC.h"
#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h"
#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h"
@@ -50,6 +51,7 @@
#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
#include "Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h"
#include "Plugins/Instruction/ARM64/EmulateInstructionARM64.h"
+#include "Plugins/Instruction/PPC64/EmulateInstructionPPC64.h"
#include "Plugins/InstrumentationRuntime/ASan/ASanRuntime.h"
#include "Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.h"
#include "Plugins/InstrumentationRuntime/TSan/TSanRuntime.h"
@@ -68,6 +70,9 @@
#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h"
#include "Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h"
#include "Plugins/MemoryHistory/asan/MemoryHistoryASan.h"
+#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
+#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
+#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"
#include "Plugins/OperatingSystem/Go/OperatingSystemGo.h"
#include "Plugins/OperatingSystem/Python/OperatingSystemPython.h"
#include "Plugins/Platform/Android/PlatformAndroid.h"
@@ -82,6 +87,7 @@
#include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h"
#include "Plugins/Process/elf-core/ProcessElfCore.h"
#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
+#include "Plugins/Process/mach-core/ProcessMachCore.h"
#include "Plugins/Process/minidump/ProcessMinidump.h"
#include "Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
@@ -102,7 +108,6 @@
#include "Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h"
#include "Plugins/Platform/MacOSX/PlatformiOSSimulator.h"
#include "Plugins/Process/MacOSX-Kernel/ProcessKDP.h"
-#include "Plugins/Process/mach-core/ProcessMachCore.h"
#include "Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h"
#endif
#include "Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h"
@@ -136,11 +141,10 @@ extern "C" void init_lldb(void);
#define LLDBSwigPyInit init_lldb
#endif
-// these are the Pythonic implementations of the required callbacks
-// these are scripting-language specific, which is why they belong here
-// we still need to use function pointers to them instead of relying
-// on linkage-time resolution because the SWIG stuff and this file
-// get built at different times
+// these are the Pythonic implementations of the required callbacks these are
+// scripting-language specific, which is why they belong here we still need to
+// use function pointers to them instead of relying on linkage-time resolution
+// because the SWIG stuff and this file get built at different times
extern "C" bool LLDBSwigPythonBreakpointCallbackFunction(
const char *python_function_name, const char *session_dictionary_name,
const lldb::StackFrameSP &sb_frame,
@@ -250,6 +254,11 @@ SystemInitializerFull::~SystemInitializerFull() {}
void SystemInitializerFull::Initialize() {
SystemInitializerCommon::Initialize();
+
+ ObjectFileELF::Initialize();
+ ObjectFileMachO::Initialize();
+ ObjectFilePECOFF::Initialize();
+
ScriptInterpreterNone::Initialize();
#ifndef LLDB_DISABLE_PYTHON
@@ -260,10 +269,9 @@ void SystemInitializerFull::Initialize() {
#if !defined(LLDB_DISABLE_PYTHON)
InitializeSWIG();
- // ScriptInterpreterPython::Initialize() depends on things like HostInfo being
- // initialized
- // so it can compute the python directory etc, so we need to do this after
- // SystemInitializerCommon::Initialize().
+ // ScriptInterpreterPython::Initialize() depends on things like HostInfo
+ // being initialized so it can compute the python directory etc, so we need
+ // to do this after SystemInitializerCommon::Initialize().
ScriptInterpreterPython::Initialize();
#endif
@@ -307,11 +315,13 @@ void SystemInitializerFull::Initialize() {
ABISysV_s390x::Initialize();
ArchitectureArm::Initialize();
+ ArchitecturePPC64::Initialize();
DisassemblerLLVMC::Initialize();
JITLoaderGDB::Initialize();
ProcessElfCore::Initialize();
+ ProcessMachCore::Initialize();
minidump::ProcessMinidump::Initialize();
MemoryHistoryASan::Initialize();
AddressSanitizerRuntime::Initialize();
@@ -326,6 +336,7 @@ void SystemInitializerFull::Initialize() {
UnwindAssemblyInstEmulation::Initialize();
UnwindAssembly_x86::Initialize();
EmulateInstructionARM64::Initialize();
+ EmulateInstructionPPC64::Initialize();
SymbolFileDWARFDebugMap::Initialize();
ItaniumABILanguageRuntime::Initialize();
AppleObjCRuntimeV2::Initialize();
@@ -351,7 +362,6 @@ void SystemInitializerFull::Initialize() {
#if defined(__APPLE__)
SymbolVendorMacOSX::Initialize();
ProcessKDP::Initialize();
- ProcessMachCore::Initialize();
PlatformAppleTVSimulator::Initialize();
PlatformAppleWatchSimulator::Initialize();
PlatformRemoteAppleTV::Initialize();
@@ -359,8 +369,8 @@ void SystemInitializerFull::Initialize() {
DynamicLoaderDarwinKernel::Initialize();
#endif
- // This plugin is valid on any host that talks to a Darwin remote.
- // It shouldn't be limited to __APPLE__.
+ // This plugin is valid on any host that talks to a Darwin remote. It
+ // shouldn't be limited to __APPLE__.
StructuredDataDarwinLog::Initialize();
//----------------------------------------------------------------------
@@ -378,8 +388,8 @@ void SystemInitializerFull::Initialize() {
// Scan for any system or user LLDB plug-ins
PluginManager::Initialize();
- // The process settings need to know about installed plug-ins, so the Settings
- // must be initialized
+ // The process settings need to know about installed plug-ins, so the
+ // Settings must be initialized
// AFTER PluginManager::Initialize is called.
Debugger::SettingsInitialize();
@@ -438,6 +448,7 @@ void SystemInitializerFull::Terminate() {
JITLoaderGDB::Terminate();
ProcessElfCore::Terminate();
+ ProcessMachCore::Terminate();
minidump::ProcessMinidump::Terminate();
MemoryHistoryASan::Terminate();
AddressSanitizerRuntime::Terminate();
@@ -451,6 +462,7 @@ void SystemInitializerFull::Terminate() {
UnwindAssembly_x86::Terminate();
UnwindAssemblyInstEmulation::Terminate();
EmulateInstructionARM64::Terminate();
+ EmulateInstructionPPC64::Terminate();
SymbolFileDWARFDebugMap::Terminate();
ItaniumABILanguageRuntime::Terminate();
AppleObjCRuntimeV2::Terminate();
@@ -468,7 +480,6 @@ void SystemInitializerFull::Terminate() {
#if defined(__APPLE__)
DynamicLoaderDarwinKernel::Terminate();
- ProcessMachCore::Terminate();
ProcessKDP::Terminate();
SymbolVendorMacOSX::Terminate();
PlatformAppleTVSimulator::Terminate();
@@ -511,6 +522,10 @@ void SystemInitializerFull::Terminate() {
PlatformDarwinKernel::Terminate();
#endif
+ ObjectFileELF::Terminate();
+ ObjectFileMachO::Terminate();
+ ObjectFilePECOFF::Terminate();
+
// Now shutdown the common parts, in reverse order.
SystemInitializerCommon::Terminate();
}
diff --git a/source/API/SystemInitializerFull.h b/source/API/SystemInitializerFull.h
new file mode 100644
index 000000000000..9cfc6896da61
--- /dev/null
+++ b/source/API/SystemInitializerFull.h
@@ -0,0 +1,38 @@
+//===-- SystemInitializerFull.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_API_SYSTEM_INITIALIZER_FULL_H
+#define LLDB_API_SYSTEM_INITIALIZER_FULL_H
+
+#include "lldb/Initialization/SystemInitializerCommon.h"
+
+namespace lldb_private {
+//------------------------------------------------------------------
+/// Initializes lldb.
+///
+/// This class is responsible for initializing all of lldb system
+/// services needed to use the full LLDB application. This class is
+/// not intended to be used externally, but is instead used
+/// internally by SBDebugger to initialize the system.
+//------------------------------------------------------------------
+class SystemInitializerFull : public SystemInitializerCommon {
+public:
+ SystemInitializerFull();
+ ~SystemInitializerFull() override;
+
+ void Initialize() override;
+ void Terminate() override;
+
+private:
+ void InitializeSWIG();
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_API_SYSTEM_INITIALIZER_FULL_H
diff --git a/source/Breakpoint/Breakpoint.cpp b/source/Breakpoint/Breakpoint.cpp
index 3f6c63e1e5ba..1dc029654bfc 100644
--- a/source/Breakpoint/Breakpoint.cpp
+++ b/source/Breakpoint/Breakpoint.cpp
@@ -23,6 +23,7 @@
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/SearchFilter.h"
#include "lldb/Core/Section.h"
+#include "lldb/Target/SectionLoadList.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
@@ -284,13 +285,13 @@ void Breakpoint::RemoveInvalidLocations(const ArchSpec &arch) {
m_locations.RemoveInvalidLocations(arch);
}
-// For each of the overall options we need to decide how they propagate to
-// the location options. This will determine the precedence of options on
-// the breakpoint vs. its locations.
+// For each of the overall options we need to decide how they propagate to the
+// location options. This will determine the precedence of options on the
+// breakpoint vs. its locations.
-// Disable at the breakpoint level should override the location settings.
-// That way you can conveniently turn off a whole breakpoint without messing
-// up the individual settings.
+// Disable at the breakpoint level should override the location settings. That
+// way you can conveniently turn off a whole breakpoint without messing up the
+// individual settings.
void Breakpoint::SetEnabled(bool enable) {
if (enable == m_options_up->IsEnabled())
@@ -330,10 +331,8 @@ bool Breakpoint::IgnoreCountShouldStop() {
uint32_t ignore = GetIgnoreCount();
if (ignore != 0) {
// When we get here we know the location that caused the stop doesn't have
- // an ignore count,
- // since by contract we call it first... So we don't have to find &
- // decrement it, we only have
- // to decrement our own ignore count.
+ // an ignore count, since by contract we call it first... So we don't have
+ // to find & decrement it, we only have to decrement our own ignore count.
DecrementIgnoreCount();
return false;
} else
@@ -430,8 +429,8 @@ const char *Breakpoint::GetConditionText() const {
// This function is used when "baton" doesn't need to be freed
void Breakpoint::SetCallback(BreakpointHitCallback callback, void *baton,
bool is_synchronous) {
- // The default "Baton" class will keep a copy of "baton" and won't free
- // or delete it when it goes goes out of scope.
+ // The default "Baton" class will keep a copy of "baton" and won't free or
+ // delete it when it goes goes out of scope.
m_options_up->SetCallback(callback, std::make_shared<UntypedBaton>(baton),
is_synchronous);
@@ -477,8 +476,7 @@ void Breakpoint::ResolveBreakpointInModules(ModuleList &module_list,
bool send_event) {
if (m_resolver_sp) {
// If this is not an internal breakpoint, set up to record the new
- // locations, then dispatch
- // an event with the new locations.
+ // locations, then dispatch an event with the new locations.
if (!IsInternal() && send_event) {
BreakpointEventData *new_locations_event = new BreakpointEventData(
eBreakpointEventTypeLocationsAdded, shared_from_this());
@@ -516,8 +514,8 @@ void Breakpoint::ModulesChanged(ModuleList &module_list, bool load,
std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
if (load) {
// The logic for handling new modules is:
- // 1) If the filter rejects this module, then skip it.
- // 2) Run through the current location list and if there are any locations
+ // 1) If the filter rejects this module, then skip it. 2) Run through the
+ // current location list and if there are any locations
// for that module, we mark the module as "seen" and we don't try to
// re-resolve
// breakpoint locations for that module.
@@ -527,20 +525,37 @@ void Breakpoint::ModulesChanged(ModuleList &module_list, bool load,
ModuleList new_modules; // We'll stuff the "unseen" modules in this list,
// and then resolve
- // them after the locations pass. Have to do it this way because
- // resolving breakpoints will add new locations potentially.
+ // them after the locations pass. Have to do it this way because resolving
+ // breakpoints will add new locations potentially.
for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
bool seen = false;
if (!m_filter_sp->ModulePasses(module_sp))
continue;
+ BreakpointLocationCollection locations_with_no_section;
for (BreakpointLocationSP break_loc_sp :
m_locations.BreakpointLocations()) {
+
+ // If the section for this location was deleted, that means it's Module
+ // has gone away but somebody forgot to tell us. Let's clean it up
+ // here.
+ Address section_addr(break_loc_sp->GetAddress());
+ if (section_addr.SectionWasDeleted()) {
+ locations_with_no_section.Add(break_loc_sp);
+ continue;
+ }
+
if (!break_loc_sp->IsEnabled())
continue;
- SectionSP section_sp(break_loc_sp->GetAddress().GetSection());
- if (!section_sp || section_sp->GetModule() == module_sp) {
+
+ SectionSP section_sp(section_addr.GetSection());
+
+ // If we don't have a Section, that means this location is a raw
+ // address that we haven't resolved to a section yet. So we'll have to
+ // look in all the new modules to resolve this location. Otherwise, if
+ // it was set in this module, re-resolve it here.
+ if (section_sp && section_sp->GetModule() == module_sp) {
if (!seen)
seen = true;
@@ -552,6 +567,11 @@ void Breakpoint::ModulesChanged(ModuleList &module_list, bool load,
}
}
}
+
+ size_t num_to_delete = locations_with_no_section.GetSize();
+
+ for (size_t i = 0; i < num_to_delete; i++)
+ m_locations.RemoveLocation(locations_with_no_section.GetByIndex(i));
if (!seen)
new_modules.AppendIfNeeded(module_sp);
@@ -583,10 +603,9 @@ void Breakpoint::ModulesChanged(ModuleList &module_list, bool load,
BreakpointLocationSP break_loc_sp(m_locations.GetByIndex(loc_idx));
SectionSP section_sp(break_loc_sp->GetAddress().GetSection());
if (section_sp && section_sp->GetModule() == module_sp) {
- // Remove this breakpoint since the shared library is
- // unloaded, but keep the breakpoint location around
- // so we always get complete hit count and breakpoint
- // lifetime info
+ // Remove this breakpoint since the shared library is unloaded, but
+ // keep the breakpoint location around so we always get complete
+ // hit count and breakpoint lifetime info
break_loc_sp->ClearBreakpointSite();
if (removed_locations_event) {
removed_locations_event->GetBreakpointLocationCollection().Add(
@@ -614,7 +633,8 @@ static bool SymbolContextsMightBeEquivalent(SymbolContext &old_sc,
bool equivalent_scs = false;
if (old_sc.module_sp.get() == new_sc.module_sp.get()) {
- // If these come from the same module, we can directly compare the pointers:
+ // If these come from the same module, we can directly compare the
+ // pointers:
if (old_sc.comp_unit && new_sc.comp_unit &&
(old_sc.comp_unit == new_sc.comp_unit)) {
if (old_sc.function && new_sc.function &&
@@ -671,15 +691,13 @@ void Breakpoint::ModuleReplaced(ModuleSP old_module_sp,
temp_list.Append(new_module_sp);
ResolveBreakpointInModules(temp_list);
} else {
- // First search the new module for locations.
- // Then compare this with the old list, copy over locations that "look the
- // same"
- // Then delete the old locations.
- // Finally remember to post the creation event.
+ // First search the new module for locations. Then compare this with the
+ // old list, copy over locations that "look the same" Then delete the old
+ // locations. Finally remember to post the creation event.
//
- // Two locations are the same if they have the same comp unit & function (by
- // name) and there are the same number
- // of locations in the old function as in the new one.
+ // Two locations are the same if they have the same comp unit & function
+ // (by name) and there are the same number of locations in the old function
+ // as in the new one.
ModuleList temp_list;
temp_list.Append(new_module_sp);
@@ -692,8 +710,8 @@ void Breakpoint::ModuleReplaced(ModuleSP old_module_sp,
if (num_new_locations > 0) {
// Break out the case of one location -> one location since that's the
- // most common one, and there's no need
- // to build up the structures needed for the merge in that case.
+ // most common one, and there's no need to build up the structures needed
+ // for the merge in that case.
if (num_new_locations == 1 && num_old_locations == 1) {
bool equivalent_locations = false;
SymbolContext old_sc, new_sc;
@@ -716,8 +734,7 @@ void Breakpoint::ModuleReplaced(ModuleSP old_module_sp,
}
} else {
// We don't want to have to keep computing the SymbolContexts for these
- // addresses over and over,
- // so lets get them up front:
+ // addresses over and over, so lets get them up front:
typedef std::map<lldb::break_id_t, SymbolContext> IDToSCMap;
IDToSCMap old_sc_map;
@@ -740,7 +757,8 @@ void Breakpoint::ModuleReplaced(ModuleSP old_module_sp,
lldb::break_id_t old_id = old_sc_map.begin()->first;
SymbolContext &old_sc = old_sc_map.begin()->second;
- // Count the number of entries equivalent to this SC for the old list:
+ // Count the number of entries equivalent to this SC for the old
+ // list:
std::vector<lldb::break_id_t> old_id_vec;
old_id_vec.push_back(old_id);
@@ -760,17 +778,15 @@ void Breakpoint::ModuleReplaced(ModuleSP old_module_sp,
}
// Alright, if we have the same number of potentially equivalent
- // locations in the old
- // and new modules, we'll just map them one to one in ascending ID
- // order (assuming the
- // resolver's order would match the equivalent ones.
- // Otherwise, we'll dump all the old ones, and just take the new ones,
- // erasing the elements
- // from both maps as we go.
+ // locations in the old and new modules, we'll just map them one to
+ // one in ascending ID order (assuming the resolver's order would
+ // match the equivalent ones. Otherwise, we'll dump all the old ones,
+ // and just take the new ones, erasing the elements from both maps as
+ // we go.
if (old_id_vec.size() == new_id_vec.size()) {
- sort(old_id_vec.begin(), old_id_vec.end());
- sort(new_id_vec.begin(), new_id_vec.end());
+ llvm::sort(old_id_vec.begin(), old_id_vec.end());
+ llvm::sort(new_id_vec.begin(), new_id_vec.end());
size_t num_elements = old_id_vec.size();
for (size_t idx = 0; idx < num_elements; idx++) {
BreakpointLocationSP old_loc_sp =
@@ -798,11 +814,9 @@ void Breakpoint::ModuleReplaced(ModuleSP old_module_sp,
}
// Now remove the remaining old locations, and cons up a removed locations
- // event.
- // Note, we don't put the new locations that were swapped with an old
- // location on the locations_to_remove
- // list, so we don't need to worry about telling the world about removing a
- // location we didn't tell them
+ // event. Note, we don't put the new locations that were swapped with an
+ // old location on the locations_to_remove list, so we don't need to worry
+ // about telling the world about removing a location we didn't tell them
// about adding.
BreakpointEventData *locations_event;
@@ -838,8 +852,8 @@ void Breakpoint::ModuleReplaced(ModuleSP old_module_sp,
void Breakpoint::Dump(Stream *) {}
size_t Breakpoint::GetNumResolvedLocations() const {
- // Return the number of breakpoints that are actually resolved and set
- // down in the inferior process.
+ // Return the number of breakpoints that are actually resolved and set down
+ // in the inferior process.
return m_locations.GetNumResolvedLocations();
}
@@ -866,9 +880,8 @@ void Breakpoint::GetDescription(Stream *s, lldb::DescriptionLevel level,
const size_t num_resolved_locations = GetNumResolvedLocations();
// They just made the breakpoint, they don't need to be told HOW they made
- // it...
- // Also, we'll print the breakpoint number differently depending on whether
- // there is 1 or more locations.
+ // it... Also, we'll print the breakpoint number differently depending on
+ // whether there is 1 or more locations.
if (level != eDescriptionLevelInitial) {
s->Printf("%i: ", GetID());
GetResolverDescription(s);
@@ -885,8 +898,7 @@ void Breakpoint::GetDescription(Stream *s, lldb::DescriptionLevel level,
(uint64_t)num_resolved_locations, GetHitCount());
} else {
// Don't print the pending notification for exception resolvers since we
- // don't generally
- // know how to set them until the target is run.
+ // don't generally know how to set them until the target is run.
if (m_resolver_sp->getResolverID() !=
BreakpointResolver::ExceptionResolver)
s->Printf(", locations = 0 (pending)");
@@ -942,8 +954,7 @@ void Breakpoint::GetDescription(Stream *s, lldb::DescriptionLevel level,
}
// The brief description is just the location name (1.2 or whatever). That's
- // pointless to
- // show in the breakpoint's description, so suppress it.
+ // pointless to show in the breakpoint's description, so suppress it.
if (show_locations && level != lldb::eDescriptionLevelBrief) {
s->IndentMore();
for (size_t i = 0; i < num_locations; ++i) {
diff --git a/source/Breakpoint/BreakpointID.cpp b/source/Breakpoint/BreakpointID.cpp
index b80106546822..3f72f2052b52 100644
--- a/source/Breakpoint/BreakpointID.cpp
+++ b/source/Breakpoint/BreakpointID.cpp
@@ -29,10 +29,9 @@ BreakpointID::~BreakpointID() = default;
static llvm::StringRef g_range_specifiers[] = {"-", "to", "To", "TO"};
// Tells whether or not STR is valid to use between two strings representing
-// breakpoint IDs, to
-// indicate a range of breakpoint IDs. This is broken out into a separate
-// function so that we can
-// easily change or add to the format for specifying ID ranges at a later date.
+// breakpoint IDs, to indicate a range of breakpoint IDs. This is broken out
+// into a separate function so that we can easily change or add to the format
+// for specifying ID ranges at a later date.
bool BreakpointID::IsRangeIdentifier(llvm::StringRef str) {
for (auto spec : g_range_specifiers) {
diff --git a/source/Breakpoint/BreakpointIDList.cpp b/source/Breakpoint/BreakpointIDList.cpp
index 6d610d512f3b..bc4c2a111fd4 100644
--- a/source/Breakpoint/BreakpointIDList.cpp
+++ b/source/Breakpoint/BreakpointIDList.cpp
@@ -16,9 +16,9 @@
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/Args.h"
using namespace lldb;
using namespace lldb_private;
@@ -89,14 +89,13 @@ bool BreakpointIDList::FindBreakpointID(const char *bp_id_str,
return FindBreakpointID(*bp_id, position);
}
-void BreakpointIDList::InsertStringArray(const char **string_array,
- size_t array_size,
- CommandReturnObject &result) {
- if (string_array == nullptr)
+void BreakpointIDList::InsertStringArray(
+ llvm::ArrayRef<const char *> string_array, CommandReturnObject &result) {
+ if(string_array.empty())
return;
- for (uint32_t i = 0; i < array_size; ++i) {
- auto bp_id = BreakpointID::ParseCanonicalReference(string_array[i]);
+ for (const char *str : string_array) {
+ auto bp_id = BreakpointID::ParseCanonicalReference(str);
if (bp_id.hasValue())
m_breakpoint_ids.push_back(*bp_id);
}
@@ -237,13 +236,13 @@ void BreakpointIDList::FindAndReplaceIDRanges(Args &old_args, Target *target,
}
// We have valid range starting & ending breakpoint IDs. Go through all
- // the breakpoints in the target and find all the breakpoints that fit
- // into this range, and add them to new_args.
+ // the breakpoints in the target and find all the breakpoints that fit into
+ // this range, and add them to new_args.
// Next check to see if we have location id's. If so, make sure the
- // start_bp_id and end_bp_id are for the same breakpoint; otherwise we
- // have an illegal range: breakpoint id ranges that specify bp locations
- // are NOT allowed to cross major bp id numbers.
+ // start_bp_id and end_bp_id are for the same breakpoint; otherwise we have
+ // an illegal range: breakpoint id ranges that specify bp locations are NOT
+ // allowed to cross major bp id numbers.
if ((start_loc_id != LLDB_INVALID_BREAK_ID) ||
(end_loc_id != LLDB_INVALID_BREAK_ID)) {
diff --git a/source/Breakpoint/BreakpointList.cpp b/source/Breakpoint/BreakpointList.cpp
index 01ac59f0a903..4a49b1e105ab 100644
--- a/source/Breakpoint/BreakpointList.cpp
+++ b/source/Breakpoint/BreakpointList.cpp
@@ -99,7 +99,7 @@ void BreakpointList::RemoveAll(bool notify) {
void BreakpointList::RemoveAllowed(bool notify) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
+
bp_collection::iterator pos, end = m_breakpoints.end();
if (notify) {
for (pos = m_breakpoints.begin(); pos != end; ++pos) {
@@ -116,10 +116,12 @@ void BreakpointList::RemoveAllowed(bool notify) {
}
pos = m_breakpoints.begin();
while ( pos != end) {
- if((*pos)->AllowDelete())
- pos = m_breakpoints.erase(pos);
- else
- pos++;
+ auto bp = *pos;
+ if (bp->AllowDelete()) {
+ bp->ClearAllBreakpointSites();
+ pos = m_breakpoints.erase(pos);
+ } else
+ pos++;
}
}
diff --git a/source/Breakpoint/BreakpointLocation.cpp b/source/Breakpoint/BreakpointLocation.cpp
index f59c334fe5c8..932147703304 100644
--- a/source/Breakpoint/BreakpointLocation.cpp
+++ b/source/Breakpoint/BreakpointLocation.cpp
@@ -110,8 +110,8 @@ void BreakpointLocation::SetThreadID(lldb::tid_t thread_id) {
if (thread_id != LLDB_INVALID_THREAD_ID)
GetLocationOptions()->SetThreadID(thread_id);
else {
- // If we're resetting this to an invalid thread id, then
- // don't make an options pointer just to do that.
+ // If we're resetting this to an invalid thread id, then don't make an
+ // options pointer just to do that.
if (m_options_ap.get() != nullptr)
m_options_ap->SetThreadID(thread_id);
}
@@ -132,8 +132,8 @@ void BreakpointLocation::SetThreadIndex(uint32_t index) {
if (index != 0)
GetLocationOptions()->GetThreadSpec()->SetIndex(index);
else {
- // If we're resetting this to an invalid thread id, then
- // don't make an options pointer just to do that.
+ // If we're resetting this to an invalid thread id, then don't make an
+ // options pointer just to do that.
if (m_options_ap.get() != nullptr)
m_options_ap->GetThreadSpec()->SetIndex(index);
}
@@ -154,8 +154,8 @@ void BreakpointLocation::SetThreadName(const char *thread_name) {
if (thread_name != nullptr)
GetLocationOptions()->GetThreadSpec()->SetName(thread_name);
else {
- // If we're resetting this to an invalid thread id, then
- // don't make an options pointer just to do that.
+ // If we're resetting this to an invalid thread id, then don't make an
+ // options pointer just to do that.
if (m_options_ap.get() != nullptr)
m_options_ap->GetThreadSpec()->SetName(thread_name);
}
@@ -176,8 +176,8 @@ void BreakpointLocation::SetQueueName(const char *queue_name) {
if (queue_name != nullptr)
GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name);
else {
- // If we're resetting this to an invalid thread id, then
- // don't make an options pointer just to do that.
+ // If we're resetting this to an invalid thread id, then don't make an
+ // options pointer just to do that.
if (m_options_ap.get() != nullptr)
m_options_ap->GetThreadSpec()->SetQueueName(queue_name);
}
@@ -203,8 +203,8 @@ bool BreakpointLocation::InvokeCallback(StoppointCallbackContext *context) {
void BreakpointLocation::SetCallback(BreakpointHitCallback callback,
void *baton, bool is_synchronous) {
- // The default "Baton" class will keep a copy of "baton" and won't free
- // or delete it when it goes goes out of scope.
+ // The default "Baton" class will keep a copy of "baton" and won't free or
+ // delete it when it goes goes out of scope.
GetLocationOptions()->SetCallback(
callback, std::make_shared<UntypedBaton>(baton), is_synchronous);
SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged);
@@ -283,8 +283,7 @@ bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx,
}
// We need to make sure the user sees any parse errors in their condition, so
- // we'll hook the
- // constructor errors up to the debugger's Async I/O.
+ // we'll hook the constructor errors up to the debugger's Async I/O.
ValueObjectSP result_value_sp;
@@ -372,9 +371,9 @@ bool BreakpointLocation::IgnoreCountShouldStop() {
}
BreakpointOptions *BreakpointLocation::GetLocationOptions() {
- // If we make the copy we don't copy the callbacks because that is potentially
- // expensive and we don't want to do that for the simple case where someone is
- // just disabling the location.
+ // If we make the copy we don't copy the callbacks because that is
+ // potentially expensive and we don't want to do that for the simple case
+ // where someone is just disabling the location.
if (m_options_ap.get() == nullptr)
m_options_ap.reset(
new BreakpointOptions(false));
@@ -479,9 +478,8 @@ bool BreakpointLocation::ClearBreakpointSite() {
if (m_bp_site_sp.get()) {
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.
+ // 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);
@@ -499,8 +497,8 @@ void BreakpointLocation::GetDescription(Stream *s,
SymbolContext sc;
// If the description level is "initial" then the breakpoint is printing out
- // our initial state,
- // and we should let it decide how it wants to print our label.
+ // our initial state, and we should let it decide how it wants to print our
+ // label.
if (level != eDescriptionLevelInitial) {
s->Indent();
BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
diff --git a/source/Breakpoint/BreakpointLocationList.cpp b/source/Breakpoint/BreakpointLocationList.cpp
index 1e4b4412a427..23ca89da6ce1 100644
--- a/source/Breakpoint/BreakpointLocationList.cpp
+++ b/source/Breakpoint/BreakpointLocationList.cpp
@@ -49,12 +49,12 @@ bool BreakpointLocationList::ShouldStop(StoppointCallbackContext *context,
BreakpointLocationSP bp = FindByID(break_id);
if (bp) {
// Let the BreakpointLocation decide if it should stop here (could not have
- // reached it's target hit count yet, or it could have a callback
- // that decided it shouldn't stop (shared library loads/unloads).
+ // reached it's target hit count yet, or it could have a callback that
+ // decided it shouldn't stop (shared library loads/unloads).
return bp->ShouldStop(context);
}
- // We should stop here since this BreakpointLocation isn't valid anymore or it
- // doesn't exist.
+ // We should stop here since this BreakpointLocation isn't valid anymore or
+ // it doesn't exist.
return true;
}
@@ -246,10 +246,10 @@ bool BreakpointLocationList::RemoveLocation(
m_address_to_location.erase(bp_loc_sp->GetAddress());
- collection::iterator pos, end = m_locations.end();
- for (pos = m_locations.begin(); pos != end; ++pos) {
- if ((*pos).get() == bp_loc_sp.get()) {
- m_locations.erase(pos);
+ size_t num_locations = m_locations.size();
+ for (size_t idx = 0; idx < num_locations; idx++) {
+ if (m_locations[idx].get() == bp_loc_sp.get()) {
+ RemoveLocationByIndex(idx);
return true;
}
}
@@ -257,17 +257,23 @@ bool BreakpointLocationList::RemoveLocation(
return false;
}
+void BreakpointLocationList::RemoveLocationByIndex(size_t idx) {
+ assert (idx < m_locations.size());
+ m_address_to_location.erase(m_locations[idx]->GetAddress());
+ m_locations.erase(m_locations.begin() + idx);
+}
+
void BreakpointLocationList::RemoveInvalidLocations(const ArchSpec &arch) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
size_t idx = 0;
- // Don't cache m_location.size() as it will change since we might
- // remove locations from our vector...
+ // Don't cache m_location.size() as it will change since we might remove
+ // locations from our vector...
while (idx < m_locations.size()) {
BreakpointLocation *bp_loc = m_locations[idx].get();
if (bp_loc->GetAddress().SectionWasDeleted()) {
// Section was deleted which means this breakpoint comes from a module
// that is no longer valid, so we should remove it.
- m_locations.erase(m_locations.begin() + idx);
+ RemoveLocationByIndex(idx);
continue;
}
if (arch.IsValid()) {
@@ -276,12 +282,13 @@ void BreakpointLocationList::RemoveInvalidLocations(const ArchSpec &arch) {
if (!arch.IsCompatibleMatch(module_sp->GetArchitecture())) {
// The breakpoint was in a module whose architecture is no longer
// compatible with "arch", so we need to remove it
- m_locations.erase(m_locations.begin() + idx);
+ RemoveLocationByIndex(idx);
continue;
}
}
}
- // Only increment the index if we didn't remove the locations at index "idx"
+ // Only increment the index if we didn't remove the locations at index
+ // "idx"
++idx;
}
}
diff --git a/source/Breakpoint/BreakpointOptions.cpp b/source/Breakpoint/BreakpointOptions.cpp
index 662b288794d3..b5869fc34dfc 100644
--- a/source/Breakpoint/BreakpointOptions.cpp
+++ b/source/Breakpoint/BreakpointOptions.cpp
@@ -425,10 +425,9 @@ void BreakpointOptions::SetCallback(BreakpointHitCallback callback,
const lldb::BatonSP &callback_baton_sp,
bool callback_is_synchronous) {
// FIXME: This seems unsafe. If BatonSP actually *is* a CommandBaton, but
- // in a shared_ptr<Baton> instead of a shared_ptr<CommandBaton>, then we
- // will set m_baton_is_command_baton to false, which is incorrect.
- // One possible solution is to make the base Baton class provide a method
- // such as:
+ // in a shared_ptr<Baton> instead of a shared_ptr<CommandBaton>, then we will
+ // set m_baton_is_command_baton to false, which is incorrect. One possible
+ // solution is to make the base Baton class provide a method such as:
// virtual StringRef getBatonId() const { return ""; }
// and have CommandBaton override this to return something unique, and then
// check for it here. Another option might be to make Baton using the llvm
@@ -470,12 +469,18 @@ const Baton *BreakpointOptions::GetBaton() const {
bool BreakpointOptions::InvokeCallback(StoppointCallbackContext *context,
lldb::user_id_t break_id,
lldb::user_id_t break_loc_id) {
- if (m_callback && context->is_synchronous == IsCallbackSynchronous()) {
- return m_callback(m_callback_baton_sp ? m_callback_baton_sp->data()
+ if (m_callback) {
+ if (context->is_synchronous == IsCallbackSynchronous()) {
+ return m_callback(m_callback_baton_sp ? m_callback_baton_sp->data()
: nullptr,
context, break_id, break_loc_id);
- } else
- return true;
+ } else if (IsCallbackSynchronous()) {
+ // If a synchronous callback is called at async time, it should not say
+ // to stop.
+ return false;
+ }
+ }
+ return true;
}
bool BreakpointOptions::HasCallback() const {
@@ -526,7 +531,10 @@ const ThreadSpec *BreakpointOptions::GetThreadSpecNoCreate() const {
ThreadSpec *BreakpointOptions::GetThreadSpec() {
if (m_thread_spec_ap.get() == nullptr)
+ {
+ m_set_flags.Set(eThreadSpec);
m_thread_spec_ap.reset(new ThreadSpec());
+ }
return m_thread_spec_ap.get();
}
@@ -545,8 +553,7 @@ void BreakpointOptions::SetThreadSpec(
void BreakpointOptions::GetDescription(Stream *s,
lldb::DescriptionLevel level) const {
// Figure out if there are any options not at their default value, and only
- // print
- // anything if there are:
+ // print anything if there are:
if (m_ignore_count != 0 || !m_enabled || m_one_shot || m_auto_continue ||
(GetThreadSpecNoCreate() != nullptr &&
@@ -651,8 +658,7 @@ bool BreakpointOptions::BreakpointOptionsCallbackFunction(
CommandReturnObject result;
Debugger &debugger = target->GetDebugger();
// Rig up the results secondary output stream to the debugger's, so the
- // output will come out synchronously
- // if the debugger is set up that way.
+ // output will come out synchronously if the debugger is set up that way.
StreamSP output_stream(debugger.GetAsyncOutputStream());
StreamSP error_stream(debugger.GetAsyncErrorStream());
diff --git a/source/Breakpoint/BreakpointResolver.cpp b/source/Breakpoint/BreakpointResolver.cpp
index 31aefb08f976..6ab578dd8576 100644
--- a/source/Breakpoint/BreakpointResolver.cpp
+++ b/source/Breakpoint/BreakpointResolver.cpp
@@ -15,8 +15,8 @@
// Project includes
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
-// Have to include the other breakpoint resolver types here so the static create
-// from StructuredData can call them.
+// Have to include the other breakpoint resolver types here so the static
+// create from StructuredData can call them.
#include "lldb/Breakpoint/BreakpointResolverAddress.h"
#include "lldb/Breakpoint/BreakpointResolverFileLine.h"
#include "lldb/Breakpoint/BreakpointResolverFileRegex.h"
@@ -212,8 +212,7 @@ void BreakpointResolver::SetSCMatchesByLine(SearchFilter &filter,
sc_list.RemoveContextAtIndex(current_idx);
// ResolveSymbolContext will always return a number that is >= the line
- // number you pass in.
- // So the smaller line number is always better.
+ // number you pass in. So the smaller line number is always better.
if (sc.line_entry.line < closest_line_number)
closest_line_number = sc.line_entry.line;
} else
@@ -234,8 +233,7 @@ void BreakpointResolver::SetSCMatchesByLine(SearchFilter &filter,
}
// Next go through and see if there are line table entries that are
- // contiguous, and if so keep only the
- // first of the contiguous range:
+ // contiguous, and if so keep only the first of the contiguous range:
current_idx = 0;
std::map<Block *, lldb::addr_t> blocks_with_breakpoints;
diff --git a/source/Breakpoint/BreakpointResolverAddress.cpp b/source/Breakpoint/BreakpointResolverAddress.cpp
index 32f2045ed59a..d4647e2c589d 100644
--- a/source/Breakpoint/BreakpointResolverAddress.cpp
+++ b/source/Breakpoint/BreakpointResolverAddress.cpp
@@ -66,7 +66,7 @@ BreakpointResolver *BreakpointResolverAddress::CreateFromStructuredData(
error.SetErrorString("BRA::CFSD: Couldn't read module name entry.");
return nullptr;
}
- module_filespec.SetFile(module_name, false);
+ module_filespec.SetFile(module_name, false, FileSpec::Style::native);
}
return new BreakpointResolverAddress(bkpt, address, module_filespec);
}
@@ -100,11 +100,10 @@ BreakpointResolverAddress::SerializeToStructuredData() {
}
void BreakpointResolverAddress::ResolveBreakpoint(SearchFilter &filter) {
- // If the address is not section relative, then we should not try to
- // re-resolve it, it is just some
- // random address and we wouldn't know what to do on reload. But if it is
- // section relative, we need to
- // re-resolve it since the section it's in may have shifted on re-run.
+ // If the address is not section relative, then we should not try to re-
+ // resolve it, it is just some random address and we wouldn't know what to do
+ // on reload. But if it is section relative, we need to re-resolve it since
+ // the section it's in may have shifted on re-run.
bool re_resolve = false;
if (m_addr.GetSection() || m_module_filespec)
re_resolve = true;
@@ -137,8 +136,8 @@ BreakpointResolverAddress::SearchCallback(SearchFilter &filter,
if (filter.AddressPasses(m_addr)) {
if (m_breakpoint->GetNumLocations() == 0) {
// If the address is just an offset, and we're given a module, see if we
- // can find the appropriate module
- // loaded in the binary, and fix up m_addr to use that.
+ // can find the appropriate module loaded in the binary, and fix up
+ // m_addr to use that.
if (!m_addr.IsSectionOffset() && m_module_filespec) {
Target &target = m_breakpoint->GetTarget();
ModuleSpec module_spec(m_module_filespec);
diff --git a/source/Breakpoint/BreakpointResolverFileLine.cpp b/source/Breakpoint/BreakpointResolverFileLine.cpp
index 780d25db9ccb..ecef88eb9989 100644
--- a/source/Breakpoint/BreakpointResolverFileLine.cpp
+++ b/source/Breakpoint/BreakpointResolverFileLine.cpp
@@ -110,20 +110,40 @@ BreakpointResolverFileLine::SerializeToStructuredData() {
// Filter the symbol context list to remove contexts where the line number was
// moved into a new function. We do this conservatively, so if e.g. we cannot
-// resolve the function in the context (which can happen in case of
-// line-table-only debug info), we leave the context as is. The trickiest part
-// here is handling inlined functions -- in this case we need to make sure we
-// look at the declaration line of the inlined function, NOT the function it was
+// resolve the function in the context (which can happen in case of line-table-
+// only debug info), we leave the context as is. The trickiest part here is
+// handling inlined functions -- in this case we need to make sure we look at
+// the declaration line of the inlined function, NOT the function it was
// inlined into.
-void BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list) {
+void BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list,
+ bool is_relative) {
if (m_exact_match)
return; // Nothing to do. Contexts are precise.
+ llvm::StringRef relative_path;
+ if (is_relative)
+ relative_path = m_file_spec.GetDirectory().GetStringRef();
+
Log * log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
for(uint32_t i = 0; i < sc_list.GetSize(); ++i) {
SymbolContext sc;
sc_list.GetContextAtIndex(i, sc);
- if (! sc.block)
+ if (is_relative) {
+ // If the path was relative, make sure any matches match as long as the
+ // relative parts of the path match the path from support files
+ auto sc_dir = sc.line_entry.file.GetDirectory().GetStringRef();
+ if (!sc_dir.endswith(relative_path)) {
+ // We had a relative path specified and the relative directory doesn't
+ // match so remove this one
+ LLDB_LOG(log, "removing not matching relative path {0} since it "
+ "doesn't end with {1}", sc_dir, relative_path);
+ sc_list.RemoveContextAtIndex(i);
+ --i;
+ continue;
+ }
+ }
+
+ if (!sc.block)
continue;
FileSpec file;
@@ -179,33 +199,38 @@ BreakpointResolverFileLine::SearchCallback(SearchFilter &filter,
assert(m_breakpoint != NULL);
// There is a tricky bit here. You can have two compilation units that
- // #include the same file, and in one of them the function at m_line_number is
- // used (and so code and a line entry for it is generated) but in the other it
- // isn't. If we considered the CU's independently, then in the second
- // inclusion, we'd move the breakpoint to the next function that actually
- // generated code in the header file. That would end up being confusing. So
- // instead, we do the CU iterations by hand here, then scan through the
- // complete list of matches, and figure out the closest line number match, and
- // only set breakpoints on that match.
+ // #include the same file, and in one of them the function at m_line_number
+ // is used (and so code and a line entry for it is generated) but in the
+ // other it isn't. If we considered the CU's independently, then in the
+ // second inclusion, we'd move the breakpoint to the next function that
+ // actually generated code in the header file. That would end up being
+ // confusing. So instead, we do the CU iterations by hand here, then scan
+ // through the complete list of matches, and figure out the closest line
+ // number match, and only set breakpoints on that match.
+
+ // Note also that if file_spec only had a file name and not a directory,
+ // there may be many different file spec's in the resultant list. The
+ // closest line match for one will not be right for some totally different
+ // file. So we go through the match list and pull out the sets that have the
+ // same file spec in their line_entry and treat each set separately.
- // Note also that if file_spec only had a file name and not a directory, there
- // may be many different file spec's in the resultant list. The closest line
- // match for one will not be right for some totally different file. So we go
- // through the match list and pull out the sets that have the same file spec
- // in their line_entry and treat each set separately.
+ FileSpec search_file_spec = m_file_spec;
+ const bool is_relative = m_file_spec.IsRelative();
+ if (is_relative)
+ search_file_spec.GetDirectory().Clear();
const size_t num_comp_units = context.module_sp->GetNumCompileUnits();
for (size_t i = 0; i < num_comp_units; i++) {
CompUnitSP cu_sp(context.module_sp->GetCompileUnitAtIndex(i));
if (cu_sp) {
if (filter.CompUnitPasses(*cu_sp))
- cu_sp->ResolveSymbolContext(m_file_spec, m_line_number, m_inlines,
+ cu_sp->ResolveSymbolContext(search_file_spec, m_line_number, m_inlines,
m_exact_match, eSymbolContextEverything,
sc_list);
}
}
- FilterContexts(sc_list);
+ FilterContexts(sc_list, is_relative);
StreamString s;
s.Printf("for %s:%d ", m_file_spec.GetFilename().AsCString("<Unknown>"),
diff --git a/source/Breakpoint/BreakpointResolverName.cpp b/source/Breakpoint/BreakpointResolverName.cpp
index 468de35db0ee..ba277ae2655e 100644
--- a/source/Breakpoint/BreakpointResolverName.cpp
+++ b/source/Breakpoint/BreakpointResolverName.cpp
@@ -16,11 +16,13 @@
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
#include "Plugins/Language/ObjC/ObjCLanguage.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
+#include "lldb/Core/Architecture.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Target/Target.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"
@@ -239,9 +241,8 @@ void BreakpointResolverName::AddNameLookup(const ConstString &name,
// FIXME: Right now we look at the module level, and call the module's
// "FindFunctions".
// Greg says he will add function tables, maybe at the CompileUnit level to
-// accelerate function
-// lookup. At that point, we should switch the depth to CompileUnit, and look
-// in these tables.
+// accelerate function lookup. At that point, we should switch the depth to
+// CompileUnit, and look in these tables.
Searcher::CallbackReturn
BreakpointResolverName::SearchCallback(SearchFilter &filter,
@@ -299,8 +300,8 @@ BreakpointResolverName::SearchCallback(SearchFilter &filter,
break;
}
- // If the filter specifies a Compilation Unit, remove the ones that don't pass
- // at this point.
+ // If the filter specifies a Compilation Unit, remove the ones that don't
+ // pass at this point.
if (filter_by_cu || filter_by_language) {
uint32_t num_functions = func_list.GetSize();
@@ -365,6 +366,12 @@ BreakpointResolverName::SearchCallback(SearchFilter &filter,
sc.symbol->GetPrologueByteSize();
if (prologue_byte_size)
break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
+ else {
+ const Architecture *arch =
+ m_breakpoint->GetTarget().GetArchitecturePlugin();
+ if (arch)
+ arch->AdjustBreakpointAddress(*sc.symbol, break_addr);
+ }
}
}
diff --git a/source/Breakpoint/BreakpointSiteList.cpp b/source/Breakpoint/BreakpointSiteList.cpp
index 87ce292feb8e..9bb9aa366106 100644
--- a/source/Breakpoint/BreakpointSiteList.cpp
+++ b/source/Breakpoint/BreakpointSiteList.cpp
@@ -24,8 +24,7 @@ BreakpointSiteList::BreakpointSiteList() : m_mutex(), m_bp_site_list() {}
BreakpointSiteList::~BreakpointSiteList() {}
// Add breakpoint site to the list. However, if the element already exists in
-// the
-// list, then we don't add it, and return LLDB_INVALID_BREAK_ID.
+// the list, then we don't add it, and return LLDB_INVALID_BREAK_ID.
lldb::break_id_t BreakpointSiteList::Add(const BreakpointSiteSP &bp) {
lldb::addr_t bp_site_load_addr = bp->GetLoadAddress();
@@ -45,8 +44,8 @@ bool BreakpointSiteList::ShouldStop(StoppointCallbackContext *context,
BreakpointSiteSP site_sp(FindByID(site_id));
if (site_sp) {
// Let the BreakpointSite decide if it should stop here (could not have
- // reached it's target hit count yet, or it could have a callback
- // that decided it shouldn't stop (shared library loads/unloads).
+ // reached it's target hit count yet, or it could have a callback that
+ // decided it shouldn't stop (shared library loads/unloads).
return site_sp->ShouldStop(context);
}
// We should stop here since this BreakpointSite isn't valid anymore or it
@@ -60,7 +59,8 @@ lldb::break_id_t BreakpointSiteList::FindIDByAddress(lldb::addr_t addr) {
// PRIx64 " ) => %u", __FUNCTION__, (uint64_t)addr, bp->GetID());
return bp.get()->GetID();
}
- // DBLogIf(PD_LOG_BREAKPOINTS, "BreakpointSiteList::%s ( addr = 0x%8.8" PRIx64
+ // DBLogIf(PD_LOG_BREAKPOINTS, "BreakpointSiteList::%s ( addr = 0x%8.8"
+ // PRIx64
// " ) => NONE", __FUNCTION__, (uint64_t)addr);
return LLDB_INVALID_BREAK_ID;
}
@@ -185,10 +185,9 @@ bool BreakpointSiteList::FindInRange(lldb::addr_t lower_bound,
if (lower == m_bp_site_list.end() || (*lower).first >= upper_bound)
return false;
- // This is one tricky bit. The breakpoint might overlap the bottom end of the
- // range. So we grab the
- // breakpoint prior to the lower bound, and check that that + its byte size
- // isn't in our range.
+ // This is one tricky bit. The breakpoint might overlap the bottom end of
+ // the range. So we grab the breakpoint prior to the lower bound, and check
+ // that that + its byte size isn't in our range.
if (lower != m_bp_site_list.begin()) {
collection::const_iterator prev_pos = lower;
prev_pos--;
diff --git a/source/Breakpoint/Watchpoint.cpp b/source/Breakpoint/Watchpoint.cpp
index a141a6b5c2f9..7a936d1fb130 100644
--- a/source/Breakpoint/Watchpoint.cpp
+++ b/source/Breakpoint/Watchpoint.cpp
@@ -59,8 +59,8 @@ Watchpoint::~Watchpoint() = default;
// This function is used when "baton" doesn't need to be freed
void Watchpoint::SetCallback(WatchpointHitCallback callback, void *baton,
bool is_synchronous) {
- // The default "Baton" class will keep a copy of "baton" and won't free
- // or delete it when it goes goes out of scope.
+ // The default "Baton" class will keep a copy of "baton" and won't free or
+ // delete it when it goes goes out of scope.
m_options.SetCallback(callback, std::make_shared<UntypedBaton>(baton),
is_synchronous);
@@ -103,8 +103,8 @@ bool Watchpoint::CaptureWatchedValue(const ExecutionContext &exe_ctx) {
Address watch_address(GetLoadAddress());
if (!m_type.IsValid()) {
// Don't know how to report new & old values, since we couldn't make a
- // scalar type for this watchpoint.
- // This works around an assert in ValueObjectMemory::Create.
+ // scalar type for this watchpoint. This works around an assert in
+ // ValueObjectMemory::Create.
// FIXME: This should not happen, but if it does in some case we care about,
// we can go grab the value raw and print it as unsigned.
return false;
@@ -217,11 +217,9 @@ void Watchpoint::DumpWithLevel(Stream *s,
bool Watchpoint::IsEnabled() const { return m_enabled; }
// Within StopInfo.cpp, we purposely turn on the ephemeral mode right before
-// temporarily disable the watchpoint
-// in order to perform possible watchpoint actions without triggering further
-// watchpoint events.
-// After the temporary disabled watchpoint is enabled, we then turn off the
-// ephemeral mode.
+// temporarily disable the watchpoint in order to perform possible watchpoint
+// actions without triggering further watchpoint events. After the temporary
+// disabled watchpoint is enabled, we then turn off the ephemeral mode.
void Watchpoint::TurnOnEphemeralMode() { m_is_ephemeral = true; }
diff --git a/source/Breakpoint/WatchpointList.cpp b/source/Breakpoint/WatchpointList.cpp
index 6ec3bd09c142..6497780084d9 100644
--- a/source/Breakpoint/WatchpointList.cpp
+++ b/source/Breakpoint/WatchpointList.cpp
@@ -203,9 +203,9 @@ bool WatchpointList::ShouldStop(StoppointCallbackContext *context,
WatchpointSP wp_sp = FindByID(watch_id);
if (wp_sp) {
- // Let the Watchpoint decide if it should stop here (could not have
- // reached it's target hit count yet, or it could have a callback
- // that decided it shouldn't stop.
+ // Let the Watchpoint decide if it should stop here (could not have reached
+ // it's target hit count yet, or it could have a callback that decided it
+ // shouldn't stop.
return wp_sp->ShouldStop(context);
}
// We should stop here since this Watchpoint isn't valid anymore or it
diff --git a/source/Breakpoint/WatchpointOptions.cpp b/source/Breakpoint/WatchpointOptions.cpp
index 558ebc51008c..402fee943a02 100644
--- a/source/Breakpoint/WatchpointOptions.cpp
+++ b/source/Breakpoint/WatchpointOptions.cpp
@@ -143,8 +143,7 @@ void WatchpointOptions::GetCallbackDescription(
void WatchpointOptions::GetDescription(Stream *s,
lldb::DescriptionLevel level) const {
// Figure out if there are any options not at their default value, and only
- // print
- // anything if there are:
+ // print anything if there are:
if ((GetThreadSpecNoCreate() != nullptr &&
GetThreadSpecNoCreate()->HasSpecification())) {
diff --git a/source/Commands/CMakeLists.txt b/source/Commands/CMakeLists.txt
index 55b41b1050c5..1dbaab5174e0 100644
--- a/source/Commands/CMakeLists.txt
+++ b/source/Commands/CMakeLists.txt
@@ -1,7 +1,6 @@
add_lldb_library(lldbCommands
CommandCompletions.cpp
CommandObjectApropos.cpp
- CommandObjectArgs.cpp
CommandObjectBreakpoint.cpp
CommandObjectBreakpointCommand.cpp
CommandObjectBugreport.cpp
@@ -21,7 +20,7 @@ add_lldb_library(lldbCommands
CommandObjectRegister.cpp
CommandObjectSettings.cpp
CommandObjectSource.cpp
- CommandObjectSyntax.cpp
+ CommandObjectStats.cpp
CommandObjectTarget.cpp
CommandObjectThread.cpp
CommandObjectType.cpp
diff --git a/source/Commands/CommandCompletions.cpp b/source/Commands/CommandCompletions.cpp
index 34cad970ff6e..bdfdbb83219b 100644
--- a/source/Commands/CommandCompletions.cpp
+++ b/source/Commands/CommandCompletions.cpp
@@ -23,14 +23,13 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Host/FileSystem.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Target/Target.h"
-#include "lldb/Utility/CleanUp.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/TildeExpressionResolver.h"
@@ -58,9 +57,7 @@ CommandCompletions::CommonCompletionElement
bool CommandCompletions::InvokeCommonCompletionCallbacks(
CommandInterpreter &interpreter, uint32_t completion_mask,
- llvm::StringRef completion_str, int match_start_point,
- int max_return_elements, SearchFilter *searcher, bool &word_complete,
- StringList &matches) {
+ CompletionRequest &request, SearchFilter *searcher) {
bool handled = false;
if (completion_mask & eCustomCompletion)
@@ -73,25 +70,18 @@ bool CommandCompletions::InvokeCommonCompletionCallbacks(
g_common_completions[i].type &&
g_common_completions[i].callback != nullptr) {
handled = true;
- g_common_completions[i].callback(interpreter, completion_str,
- match_start_point, max_return_elements,
- searcher, word_complete, matches);
+ g_common_completions[i].callback(interpreter, request, searcher);
}
}
return handled;
}
int CommandCompletions::SourceFiles(CommandInterpreter &interpreter,
- llvm::StringRef partial_file_name,
- int match_start_point,
- int max_return_elements,
- SearchFilter *searcher, bool &word_complete,
- StringList &matches) {
- word_complete = true;
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ request.SetWordComplete(true);
// Find some way to switch "include support files..."
- SourceFileCompleter completer(interpreter, false, partial_file_name,
- match_start_point, max_return_elements,
- matches);
+ SourceFileCompleter completer(interpreter, false, request);
if (searcher == nullptr) {
lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
@@ -100,12 +90,11 @@ int CommandCompletions::SourceFiles(CommandInterpreter &interpreter,
} else {
completer.DoCompletion(searcher);
}
- return matches.GetSize();
+ return request.GetMatches().GetSize();
}
static int DiskFilesOrDirectories(const llvm::Twine &partial_name,
- bool only_directories, bool &saw_directory,
- StringList &matches,
+ bool only_directories, StringList &matches,
TildeExpressionResolver &Resolver) {
matches.Clear();
@@ -139,24 +128,22 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name,
// but after that, we're done regardless of any matches.
if (FirstSep == llvm::StringRef::npos) {
llvm::StringSet<> MatchSet;
- saw_directory = Resolver.ResolvePartial(Username, MatchSet);
+ Resolver.ResolvePartial(Username, MatchSet);
for (const auto &S : MatchSet) {
Resolved = S.getKey();
path::append(Resolved, path::get_separator());
matches.AppendString(Resolved);
}
- saw_directory = (matches.GetSize() > 0);
}
return matches.GetSize();
}
- // If there was no trailing slash, then we're done as soon as we resolve the
- // expression to the correct directory. Otherwise we need to continue
+ // If there was no trailing slash, then we're done as soon as we resolve
+ // the expression to the correct directory. Otherwise we need to continue
// looking for matches within that directory.
if (FirstSep == llvm::StringRef::npos) {
// Make sure it ends with a separator.
path::append(CompletionBuffer, path::get_separator());
- saw_directory = true;
matches.AppendString(CompletionBuffer);
return 1;
}
@@ -165,7 +152,13 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name,
// search in the fully resolved directory, but CompletionBuffer keeps the
// unmodified form that the user typed.
Storage = Resolved;
- SearchDir = Resolved;
+ llvm::StringRef RemainderDir = path::parent_path(Remainder);
+ if (!RemainderDir.empty()) {
+ // Append the remaining path to the resolved directory.
+ Storage.append(path::get_separator());
+ Storage.append(RemainderDir);
+ }
+ SearchDir = Storage;
} else {
SearchDir = path::parent_path(CompletionBuffer);
}
@@ -222,7 +215,6 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name,
CompletionBuffer.append(Name);
if (is_dir) {
- saw_directory = true;
path::append(CompletionBuffer, path::get_separator());
}
@@ -233,51 +225,40 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name,
}
int CommandCompletions::DiskFiles(CommandInterpreter &interpreter,
- llvm::StringRef partial_file_name,
- int match_start_point,
- int max_return_elements,
- SearchFilter *searcher, bool &word_complete,
- StringList &matches) {
- word_complete = false;
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ request.SetWordComplete(false);
StandardTildeExpressionResolver Resolver;
- return DiskFiles(partial_file_name, matches, Resolver);
+ return DiskFiles(request.GetCursorArgumentPrefix(), request.GetMatches(),
+ Resolver);
}
int CommandCompletions::DiskFiles(const llvm::Twine &partial_file_name,
StringList &matches,
TildeExpressionResolver &Resolver) {
- bool word_complete;
- int ret_val = DiskFilesOrDirectories(partial_file_name, false, word_complete,
- matches, Resolver);
- return ret_val;
+ return DiskFilesOrDirectories(partial_file_name, false, matches, Resolver);
}
-int CommandCompletions::DiskDirectories(
- CommandInterpreter &interpreter, llvm::StringRef partial_file_name,
- int match_start_point, int max_return_elements, SearchFilter *searcher,
- bool &word_complete, StringList &matches) {
- word_complete = false;
+int CommandCompletions::DiskDirectories(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ request.SetWordComplete(false);
StandardTildeExpressionResolver Resolver;
- return DiskDirectories(partial_file_name, matches, Resolver);
+ return DiskDirectories(request.GetCursorArgumentPrefix(),
+ request.GetMatches(), Resolver);
}
int CommandCompletions::DiskDirectories(const llvm::Twine &partial_file_name,
StringList &matches,
TildeExpressionResolver &Resolver) {
- bool word_complete;
- int ret_val = DiskFilesOrDirectories(partial_file_name, true, word_complete,
- matches, Resolver);
- return ret_val;
+ return DiskFilesOrDirectories(partial_file_name, true, matches, Resolver);
}
int CommandCompletions::Modules(CommandInterpreter &interpreter,
- llvm::StringRef partial_file_name,
- int match_start_point, int max_return_elements,
- SearchFilter *searcher, bool &word_complete,
- StringList &matches) {
- word_complete = true;
- ModuleCompleter completer(interpreter, partial_file_name, match_start_point,
- max_return_elements, matches);
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ request.SetWordComplete(true);
+ ModuleCompleter completer(interpreter, request);
if (searcher == nullptr) {
lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
@@ -286,17 +267,14 @@ int CommandCompletions::Modules(CommandInterpreter &interpreter,
} else {
completer.DoCompletion(searcher);
}
- return matches.GetSize();
+ return request.GetMatches().GetSize();
}
int CommandCompletions::Symbols(CommandInterpreter &interpreter,
- llvm::StringRef partial_file_name,
- int match_start_point, int max_return_elements,
- SearchFilter *searcher, bool &word_complete,
- StringList &matches) {
- word_complete = true;
- SymbolCompleter completer(interpreter, partial_file_name, match_start_point,
- max_return_elements, matches);
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ request.SetWordComplete(true);
+ SymbolCompleter completer(interpreter, request);
if (searcher == nullptr) {
lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
@@ -305,13 +283,12 @@ int CommandCompletions::Symbols(CommandInterpreter &interpreter,
} else {
completer.DoCompletion(searcher);
}
- return matches.GetSize();
+ return request.GetMatches().GetSize();
}
-int CommandCompletions::SettingsNames(
- CommandInterpreter &interpreter, llvm::StringRef partial_setting_name,
- int match_start_point, int max_return_elements, SearchFilter *searcher,
- bool &word_complete, StringList &matches) {
+int CommandCompletions::SettingsNames(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
// Cache the full setting name list
static StringList g_property_names;
if (g_property_names.GetSize() == 0) {
@@ -327,47 +304,39 @@ int CommandCompletions::SettingsNames(
}
size_t exact_matches_idx = SIZE_MAX;
- const size_t num_matches = g_property_names.AutoComplete(
- partial_setting_name, matches, exact_matches_idx);
- word_complete = exact_matches_idx != SIZE_MAX;
+ const size_t num_matches =
+ g_property_names.AutoComplete(request.GetCursorArgumentPrefix(),
+ request.GetMatches(), exact_matches_idx);
+ request.SetWordComplete(exact_matches_idx != SIZE_MAX);
return num_matches;
}
-int CommandCompletions::PlatformPluginNames(
- CommandInterpreter &interpreter, llvm::StringRef partial_name,
- int match_start_point, int max_return_elements, SearchFilter *searcher,
- bool &word_complete, lldb_private::StringList &matches) {
- const uint32_t num_matches =
- PluginManager::AutoCompletePlatformName(partial_name, matches);
- word_complete = num_matches == 1;
+int CommandCompletions::PlatformPluginNames(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ const uint32_t num_matches = PluginManager::AutoCompletePlatformName(
+ request.GetCursorArgumentPrefix(), request.GetMatches());
+ request.SetWordComplete(num_matches == 1);
return num_matches;
}
-int CommandCompletions::ArchitectureNames(
- CommandInterpreter &interpreter, llvm::StringRef partial_name,
- int match_start_point, int max_return_elements, SearchFilter *searcher,
- bool &word_complete, lldb_private::StringList &matches) {
- const uint32_t num_matches = ArchSpec::AutoComplete(partial_name, matches);
- word_complete = num_matches == 1;
+int CommandCompletions::ArchitectureNames(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ const uint32_t num_matches = ArchSpec::AutoComplete(request);
+ request.SetWordComplete(num_matches == 1);
return num_matches;
}
-int CommandCompletions::VariablePath(
- CommandInterpreter &interpreter, llvm::StringRef partial_name,
- int match_start_point, int max_return_elements, SearchFilter *searcher,
- bool &word_complete, lldb_private::StringList &matches) {
- return Variable::AutoComplete(interpreter.GetExecutionContext(), partial_name,
- matches, word_complete);
+int CommandCompletions::VariablePath(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ return Variable::AutoComplete(interpreter.GetExecutionContext(), request);
}
CommandCompletions::Completer::Completer(CommandInterpreter &interpreter,
- llvm::StringRef completion_str,
- int match_start_point,
- int max_return_elements,
- StringList &matches)
- : m_interpreter(interpreter), m_completion_str(completion_str),
- m_match_start_point(match_start_point),
- m_max_return_elements(max_return_elements), m_matches(matches) {}
+ CompletionRequest &request)
+ : m_interpreter(interpreter), m_request(request) {}
CommandCompletions::Completer::~Completer() = default;
@@ -377,13 +346,10 @@ CommandCompletions::Completer::~Completer() = default;
CommandCompletions::SourceFileCompleter::SourceFileCompleter(
CommandInterpreter &interpreter, bool include_support_files,
- llvm::StringRef completion_str, int match_start_point,
- int max_return_elements, StringList &matches)
- : CommandCompletions::Completer(interpreter, completion_str,
- match_start_point, max_return_elements,
- matches),
+ CompletionRequest &request)
+ : CommandCompletions::Completer(interpreter, request),
m_include_support_files(include_support_files), m_matching_files() {
- FileSpec partial_spec(m_completion_str, false);
+ FileSpec partial_spec(m_request.GetCursorArgumentPrefix(), false);
m_file_name = partial_spec.GetFilename().GetCString();
m_dir_name = partial_spec.GetDirectory().GetCString();
}
@@ -443,10 +409,10 @@ CommandCompletions::SourceFileCompleter::DoCompletion(SearchFilter *filter) {
filter->Search(*this);
// Now convert the filelist to completions:
for (size_t i = 0; i < m_matching_files.GetSize(); i++) {
- m_matches.AppendString(
+ m_request.GetMatches().AppendString(
m_matching_files.GetFileSpecAtIndex(i).GetFilename().GetCString());
}
- return m_matches.GetSize();
+ return m_request.GetMatches().GetSize();
}
//----------------------------------------------------------------------
@@ -461,15 +427,12 @@ static bool regex_chars(const char comp) {
}
CommandCompletions::SymbolCompleter::SymbolCompleter(
- CommandInterpreter &interpreter, llvm::StringRef completion_str,
- int match_start_point, int max_return_elements, StringList &matches)
- : CommandCompletions::Completer(interpreter, completion_str,
- match_start_point, max_return_elements,
- matches) {
+ CommandInterpreter &interpreter, CompletionRequest &request)
+ : CommandCompletions::Completer(interpreter, request) {
std::string regex_str;
- if (!completion_str.empty()) {
+ if (!m_request.GetCursorArgumentPrefix().empty()) {
regex_str.append("^");
- regex_str.append(completion_str);
+ regex_str.append(m_request.GetCursorArgumentPrefix());
} else {
// Match anything since the completion string is empty
regex_str.append(".");
@@ -515,21 +478,18 @@ size_t CommandCompletions::SymbolCompleter::DoCompletion(SearchFilter *filter) {
filter->Search(*this);
collection::iterator pos = m_match_set.begin(), end = m_match_set.end();
for (pos = m_match_set.begin(); pos != end; pos++)
- m_matches.AppendString((*pos).GetCString());
+ m_request.GetMatches().AppendString((*pos).GetCString());
- return m_matches.GetSize();
+ return m_request.GetMatches().GetSize();
}
//----------------------------------------------------------------------
// ModuleCompleter
//----------------------------------------------------------------------
CommandCompletions::ModuleCompleter::ModuleCompleter(
- CommandInterpreter &interpreter, llvm::StringRef completion_str,
- int match_start_point, int max_return_elements, StringList &matches)
- : CommandCompletions::Completer(interpreter, completion_str,
- match_start_point, max_return_elements,
- matches) {
- FileSpec partial_spec(m_completion_str, false);
+ CommandInterpreter &interpreter, CompletionRequest &request)
+ : CommandCompletions::Completer(interpreter, request) {
+ FileSpec partial_spec(m_request.GetCursorArgumentPrefix(), false);
m_file_name = partial_spec.GetFilename().GetCString();
m_dir_name = partial_spec.GetDirectory().GetCString();
}
@@ -557,7 +517,7 @@ Searcher::CallbackReturn CommandCompletions::ModuleCompleter::SearchCallback(
match = false;
if (match) {
- m_matches.AppendString(cur_file_name);
+ m_request.GetMatches().AppendString(cur_file_name);
}
}
return Searcher::eCallbackReturnContinue;
@@ -565,5 +525,5 @@ Searcher::CallbackReturn CommandCompletions::ModuleCompleter::SearchCallback(
size_t CommandCompletions::ModuleCompleter::DoCompletion(SearchFilter *filter) {
filter->Search(*this);
- return m_matches.GetSize();
+ return m_request.GetMatches().GetSize();
}
diff --git a/source/Commands/CommandObjectApropos.cpp b/source/Commands/CommandObjectApropos.cpp
index 1114a511aa07..047575278faa 100644
--- a/source/Commands/CommandObjectApropos.cpp
+++ b/source/Commands/CommandObjectApropos.cpp
@@ -13,11 +13,11 @@
// Other libraries and framework includes
// Project includes
#include "CommandObjectApropos.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/Property.h"
+#include "lldb/Utility/Args.h"
using namespace lldb;
using namespace lldb_private;
@@ -53,8 +53,8 @@ bool CommandObjectApropos::DoExecute(Args &args, CommandReturnObject &result) {
if (argc == 1) {
auto search_word = args[0].ref;
if (!search_word.empty()) {
- // The bulk of the work must be done inside the Command Interpreter, since
- // the command dictionary is private.
+ // The bulk of the work must be done inside the Command Interpreter,
+ // since the command dictionary is private.
StringList commands_found;
StringList commands_help;
diff --git a/source/Commands/CommandObjectArgs.cpp b/source/Commands/CommandObjectArgs.cpp
deleted file mode 100644
index 92c2107dc33c..000000000000
--- a/source/Commands/CommandObjectArgs.cpp
+++ /dev/null
@@ -1,234 +0,0 @@
-//===-- CommandObjectArgs.cpp -----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "CommandObjectArgs.h"
-#include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h"
-#include "lldb/Core/Debugger.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/Value.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Host/OptionParser.h"
-#include "lldb/Interpreter/Args.h"
-#include "lldb/Interpreter/CommandInterpreter.h"
-#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/Variable.h"
-#include "lldb/Target/ABI.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/StackFrame.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-
-#include "llvm/ADT/StringSwitch.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-// This command is a toy. I'm just using it to have a way to construct the
-// arguments to
-// calling functions.
-//
-
-static OptionDefinition g_arg_options[] = {
- // clang-format off
- { LLDB_OPT_SET_1, false, "debug", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose debug logging of the expression parsing and evaluation." },
- // clang-format on
-};
-
-CommandObjectArgs::CommandOptions::CommandOptions(
- CommandInterpreter &interpreter)
- : Options() {
- // Keep only one place to reset the values to their defaults
- OptionParsingStarting(nullptr);
-}
-
-CommandObjectArgs::CommandOptions::~CommandOptions() = default;
-
-Status CommandObjectArgs::CommandOptions::SetOptionValue(
- uint32_t option_idx, llvm::StringRef option_arg,
- ExecutionContext *execution_context) {
- Status error;
-
- const int short_option = m_getopt_table[option_idx].val;
- error.SetErrorStringWithFormat("invalid short option character '%c'",
- short_option);
-
- return error;
-}
-
-void CommandObjectArgs::CommandOptions::OptionParsingStarting(
- ExecutionContext *execution_context) {}
-
-llvm::ArrayRef<OptionDefinition>
-CommandObjectArgs::CommandOptions::GetDefinitions() {
- return llvm::makeArrayRef(g_arg_options);
-}
-
-CommandObjectArgs::CommandObjectArgs(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "args",
- "When stopped at the start of a function, reads "
- "function arguments of type (u?)int(8|16|32|64)_t, "
- "(void|char)*",
- "args"),
- m_options(interpreter) {}
-
-CommandObjectArgs::~CommandObjectArgs() = default;
-
-Options *CommandObjectArgs::GetOptions() { return &m_options; }
-
-bool CommandObjectArgs::DoExecute(Args &args, CommandReturnObject &result) {
- ConstString target_triple;
-
- Process *process = m_exe_ctx.GetProcessPtr();
- if (!process) {
- result.AppendError("Args found no process.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- const ABI *abi = process->GetABI().get();
- if (!abi) {
- result.AppendError("The current process has no ABI.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- if (args.empty()) {
- result.AppendError("args requires at least one argument");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- Thread *thread = m_exe_ctx.GetThreadPtr();
-
- if (!thread) {
- result.AppendError("args found no thread.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- lldb::StackFrameSP thread_cur_frame = thread->GetSelectedFrame();
- if (!thread_cur_frame) {
- result.AppendError("The current thread has no current frame.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- ModuleSP thread_module_sp(
- thread_cur_frame->GetFrameCodeAddress().GetModule());
- if (!thread_module_sp) {
- result.AppendError("The PC has no associated module.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- TypeSystem *type_system =
- thread_module_sp->GetTypeSystemForLanguage(eLanguageTypeC);
- if (type_system == nullptr) {
- result.AppendError("Unable to create C type system.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- ValueList value_list;
-
- for (auto &arg_entry : args.entries()) {
- llvm::StringRef arg_type = arg_entry.ref;
- Value value;
- value.SetValueType(Value::eValueTypeScalar);
- CompilerType compiler_type;
-
- std::size_t int_pos = arg_type.find("int");
- if (int_pos != llvm::StringRef::npos) {
- Encoding encoding = eEncodingSint;
-
- int width = 0;
-
- if (int_pos > 1) {
- result.AppendErrorWithFormat("Invalid format: %s.\n",
- arg_entry.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- if (int_pos == 1 && arg_type[0] != 'u') {
- result.AppendErrorWithFormat("Invalid format: %s.\n",
- arg_entry.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- if (arg_type[0] == 'u') {
- encoding = eEncodingUint;
- }
-
- llvm::StringRef width_spec = arg_type.drop_front(int_pos + 3);
-
- auto exp_result = llvm::StringSwitch<llvm::Optional<int>>(width_spec)
- .Case("8_t", 8)
- .Case("16_t", 16)
- .Case("32_t", 32)
- .Case("64_t", 64)
- .Default(llvm::None);
- if (!exp_result.hasValue()) {
- result.AppendErrorWithFormat("Invalid format: %s.\n",
- arg_entry.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- width = *exp_result;
-
- compiler_type =
- type_system->GetBuiltinTypeForEncodingAndBitSize(encoding, width);
-
- if (!compiler_type.IsValid()) {
- result.AppendErrorWithFormat(
- "Couldn't get Clang type for format %s (%s integer, width %d).\n",
- arg_entry.c_str(),
- (encoding == eEncodingSint ? "signed" : "unsigned"), width);
-
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- } else if (arg_type == "void*") {
- compiler_type =
- type_system->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType();
- } else if (arg_type == "char*") {
- compiler_type =
- type_system->GetBasicTypeFromAST(eBasicTypeChar).GetPointerType();
- } else {
- result.AppendErrorWithFormat("Invalid format: %s.\n", arg_entry.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- value.SetCompilerType(compiler_type);
- value_list.PushValue(value);
- }
-
- if (!abi->GetArgumentValues(*thread, value_list)) {
- result.AppendError("Couldn't get argument values");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- result.GetOutputStream().Printf("Arguments : \n");
-
- for (auto entry : llvm::enumerate(args.entries())) {
- result.GetOutputStream().Printf(
- "%" PRIu64 " (%s): ", (uint64_t)entry.index(), entry.value().c_str());
- value_list.GetValueAtIndex(entry.index())->Dump(&result.GetOutputStream());
- result.GetOutputStream().Printf("\n");
- }
-
- return result.Succeeded();
-}
diff --git a/source/Commands/CommandObjectArgs.h b/source/Commands/CommandObjectArgs.h
deleted file mode 100644
index aa7d2411adc8..000000000000
--- a/source/Commands/CommandObjectArgs.h
+++ /dev/null
@@ -1,52 +0,0 @@
-//===-- CommandObjectArgs.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_CommandObjectArgs_h_
-#define liblldb_CommandObjectArgs_h_
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Interpreter/CommandObject.h"
-#include "lldb/Interpreter/Options.h"
-
-namespace lldb_private {
-
-class CommandObjectArgs : public CommandObjectParsed {
-public:
- class CommandOptions : public Options {
- public:
- CommandOptions(CommandInterpreter &interpreter);
-
- ~CommandOptions() override;
-
- Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
- ExecutionContext *execution_context) override;
-
- void OptionParsingStarting(ExecutionContext *execution_context) override;
-
- llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
- };
-
- CommandObjectArgs(CommandInterpreter &interpreter);
-
- ~CommandObjectArgs() override;
-
- Options *GetOptions() override;
-
-protected:
- CommandOptions m_options;
-
- bool DoExecute(Args &command, CommandReturnObject &result) override;
-};
-
-} // namespace lldb_private
-
-#endif // liblldb_CommandObjectArgs_h_
diff --git a/source/Commands/CommandObjectBreakpoint.cpp b/source/Commands/CommandObjectBreakpoint.cpp
index 5a175d61060e..fb0553e482db 100644
--- a/source/Commands/CommandObjectBreakpoint.cpp
+++ b/source/Commands/CommandObjectBreakpoint.cpp
@@ -22,6 +22,7 @@
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionValueBoolean.h"
#include "lldb/Interpreter/OptionValueString.h"
#include "lldb/Interpreter/OptionValueUInt64.h"
@@ -84,8 +85,8 @@ public:
switch (short_option) {
case 'c':
- // Normally an empty breakpoint condition marks is as unset.
- // But we need to say it was passed in.
+ // Normally an empty breakpoint condition marks is as unset. But we need
+ // to say it was passed in.
m_bp_opts.SetCondition(option_arg.str().c_str());
m_bp_opts.m_set_flags.Set(BreakpointOptions::eCondition);
break;
@@ -100,7 +101,7 @@ public:
break;
case 'G': {
bool value, success;
- value = Args::StringToBoolean(option_arg, false, &success);
+ value = OptionArgParser::ToBoolean(option_arg, false, &success);
if (success) {
m_bp_opts.SetAutoContinue(value);
} else
@@ -121,7 +122,7 @@ public:
break;
case 'o': {
bool value, success;
- value = Args::StringToBoolean(option_arg, false, &success);
+ value = OptionArgParser::ToBoolean(option_arg, false, &success);
if (success) {
m_bp_opts.SetOneShot(value);
} else
@@ -262,8 +263,9 @@ static OptionDefinition g_breakpoint_set_options[] = {
"#included, set target.inline-breakpoint-strategy to \"always\"." },
{ LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Specifies the line number on which to set this breakpoint." },
- // Comment out this option for the moment, as we don't actually use it, but will in the future.
- // This way users won't see it, but the infrastructure is left in place.
+ // Comment out this option for the moment, as we don't actually use it, but
+ // will in the future. This way users won't see it, but the infrastructure is
+ // left in place.
// { 0, false, "column", 'C', OptionParser::eRequiredArgument, nullptr, "<column>",
// "Set the breakpoint by source location at this particular column."},
@@ -281,7 +283,7 @@ static OptionDefinition g_breakpoint_set_options[] = {
{ LLDB_OPT_SET_9, false, "source-regexp-function", 'X', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "When used with '-p' limits the source regex to source contained in the named "
"functions. Can be repeated multiple times." },
{ LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFullName, "Set the breakpoint by fully qualified function names. For C++ this means "
- "namespaces and all arguments, and for Objective C this means a full function "
+ "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, nullptr, nullptr, 0, eArgTypeSelector, "Set the breakpoint by ObjC selector name. Can be repeated multiple times to "
@@ -377,8 +379,8 @@ public:
switch (short_option) {
case 'a': {
- m_load_addr = Args::StringToAddress(execution_context, option_arg,
- LLDB_INVALID_ADDRESS, &error);
+ m_load_addr = OptionArgParser::ToAddress(execution_context, option_arg,
+ LLDB_INVALID_ADDRESS, &error);
} break;
case 'A':
@@ -442,7 +444,7 @@ public:
case 'h': {
bool success;
- m_catch_bp = Args::StringToBoolean(option_arg, true, &success);
+ m_catch_bp = OptionArgParser::ToBoolean(option_arg, true, &success);
if (!success)
error.SetErrorStringWithFormat(
"Invalid boolean value for on-catch option: '%s'",
@@ -456,7 +458,7 @@ public:
case 'K': {
bool success;
bool value;
- value = Args::StringToBoolean(option_arg, true, &success);
+ value = OptionArgParser::ToBoolean(option_arg, true, &success);
if (value)
m_skip_prologue = eLazyBoolYes;
else
@@ -485,7 +487,7 @@ public:
case 'm': {
bool success;
bool value;
- value = Args::StringToBoolean(option_arg, true, &success);
+ value = OptionArgParser::ToBoolean(option_arg, true, &success);
if (value)
m_move_to_nearest_code = eLazyBoolYes;
else
@@ -519,8 +521,8 @@ public:
case 'R': {
lldb::addr_t tmp_offset_addr;
- tmp_offset_addr =
- Args::StringToAddress(execution_context, option_arg, 0, &error);
+ tmp_offset_addr = OptionArgParser::ToAddress(execution_context,
+ option_arg, 0, &error);
if (error.Success())
m_offset_addr = tmp_offset_addr;
} break;
@@ -549,7 +551,7 @@ public:
case 'w': {
bool success;
- m_throw_bp = Args::StringToBoolean(option_arg, true, &success);
+ m_throw_bp = OptionArgParser::ToBoolean(option_arg, true, &success);
if (!success)
error.SetErrorStringWithFormat(
"Invalid boolean value for on-throw option: '%s'",
@@ -853,9 +855,9 @@ protected:
output_stream.Printf("Breakpoint set in dummy target, will get copied "
"into future targets.\n");
else {
- // Don't print out this warning for exception breakpoints. They can get
- // set before the target is set, but we won't know how to actually set
- // the breakpoint till we run.
+ // Don't print out this warning for exception breakpoints. They can
+ // get set before the target is set, but we won't know how to actually
+ // set the breakpoint till we run.
if (bp_sp->GetNumLocations() == 0 && break_type != eSetTypeException) {
output_stream.Printf("WARNING: Unable to resolve breakpoint to any "
"actual locations.\n");
@@ -874,8 +876,8 @@ private:
bool GetDefaultFile(Target *target, FileSpec &file,
CommandReturnObject &result) {
uint32_t default_line;
- // First use the Source Manager's default file.
- // Then use the current stack frame's file.
+ // First use the Source Manager's default file. Then use the current stack
+ // frame's file.
if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line)) {
StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
if (cur_frame == nullptr) {
@@ -1451,7 +1453,8 @@ protected:
return false;
}
- // The following are the various types of breakpoints that could be cleared:
+ // The following are the various types of breakpoints that could be
+ // cleared:
// 1). -f -l (clearing breakpoint by source location)
BreakpointClearType break_type = eClearTypeInvalid;
@@ -1783,7 +1786,7 @@ public:
switch (short_option) {
case 'L': {
bool value, success;
- value = Args::StringToBoolean(option_arg, false, &success);
+ value = OptionArgParser::ToBoolean(option_arg, false, &success);
if (success) {
m_permissions.SetAllowList(value);
} else
@@ -1793,7 +1796,7 @@ public:
} break;
case 'A': {
bool value, success;
- value = Args::StringToBoolean(option_arg, false, &success);
+ value = OptionArgParser::ToBoolean(option_arg, false, &success);
if (success) {
m_permissions.SetAllowDisable(value);
} else
@@ -1803,7 +1806,7 @@ public:
} break;
case 'D': {
bool value, success;
- value = Args::StringToBoolean(option_arg, false, &success);
+ value = OptionArgParser::ToBoolean(option_arg, false, &success);
if (success) {
m_permissions.SetAllowDelete(value);
} else
@@ -1897,8 +1900,8 @@ protected:
return false;
}
}
- // Now configure them, we already pre-checked the names so we don't need
- // to check the error:
+ // Now configure them, we already pre-checked the names so we don't need to
+ // check the error:
BreakpointSP bp_sp;
if (m_bp_id.m_breakpoint.OptionWasSet())
{
@@ -2559,11 +2562,10 @@ void CommandObjectMultiwordBreakpoint::VerifyIDs(Args &args, Target *target,
}
// Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff
- // directly from the old ARGS to
- // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead
- // generate a list of strings for
- // all the breakpoint ids in the range, and shove all of those breakpoint id
- // strings into TEMP_ARGS.
+ // directly from the old ARGS to the new TEMP_ARGS. Do not copy breakpoint
+ // id range strings over; instead generate a list of strings for all the
+ // breakpoint ids in the range, and shove all of those breakpoint id strings
+ // into TEMP_ARGS.
BreakpointIDList::FindAndReplaceIDRanges(args, target, allow_locations,
purpose, result, temp_args);
@@ -2571,18 +2573,15 @@ void CommandObjectMultiwordBreakpoint::VerifyIDs(Args &args, Target *target,
// NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual
// BreakpointIDList:
- valid_ids->InsertStringArray(temp_args.GetConstArgumentVector(),
- temp_args.GetArgumentCount(), result);
+ valid_ids->InsertStringArray(temp_args.GetArgumentArrayRef(), result);
- // At this point, all of the breakpoint ids that the user passed in have been
- // converted to breakpoint IDs
- // and put into valid_ids.
+ // At this point, all of the breakpoint ids that the user passed in have
+ // been converted to breakpoint IDs and put into valid_ids.
if (result.Succeeded()) {
// Now that we've converted everything from args into a list of breakpoint
- // ids, go through our tentative list
- // of breakpoint id's and verify that they correspond to valid/currently set
- // breakpoints.
+ // ids, go through our tentative list of breakpoint id's and verify that
+ // they correspond to valid/currently set breakpoints.
const size_t count = valid_ids->GetSize();
for (size_t i = 0; i < count; ++i) {
diff --git a/source/Commands/CommandObjectBreakpointCommand.cpp b/source/Commands/CommandObjectBreakpointCommand.cpp
index 170cb8513116..f2546cbed848 100644
--- a/source/Commands/CommandObjectBreakpointCommand.cpp
+++ b/source/Commands/CommandObjectBreakpointCommand.cpp
@@ -22,6 +22,7 @@
#include "lldb/Host/OptionParser.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
@@ -293,7 +294,7 @@ are no syntax errors may indicate that a function was declared but never called.
break;
case 's':
- m_script_language = (lldb::ScriptLanguage)Args::StringToOptionEnum(
+ m_script_language = (lldb::ScriptLanguage)OptionArgParser::ToOptionEnum(
option_arg, g_breakpoint_add_options[option_idx].enum_values,
eScriptLanguageNone, error);
@@ -307,7 +308,8 @@ are no syntax errors may indicate that a function was declared but never called.
case 'e': {
bool success = false;
- m_stop_on_error = Args::StringToBoolean(option_arg, false, &success);
+ m_stop_on_error =
+ OptionArgParser::ToBoolean(option_arg, false, &success);
if (!success)
error.SetErrorStringWithFormat(
"invalid value for stop-on-error: \"%s\"",
@@ -410,8 +412,8 @@ protected:
} else {
BreakpointLocationSP bp_loc_sp(
bp->FindLocationByID(cur_bp_id.GetLocationID()));
- // This breakpoint does have an associated location.
- // Get its breakpoint options.
+ // This breakpoint does have an associated location. Get its
+ // breakpoint options.
if (bp_loc_sp)
bp_options = bp_loc_sp->GetLocationOptions();
}
@@ -420,9 +422,9 @@ protected:
}
}
- // 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 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.
@@ -454,16 +456,15 @@ private:
std::vector<BreakpointOptions *> 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.
+ // 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;
};
diff --git a/source/Commands/CommandObjectCommands.cpp b/source/Commands/CommandObjectCommands.cpp
index c9d71a65754b..3012ee4a188d 100644
--- a/source/Commands/CommandObjectCommands.cpp
+++ b/source/Commands/CommandObjectCommands.cpp
@@ -18,16 +18,17 @@
#include "lldb/Core/Debugger.h"
#include "lldb/Core/IOHandler.h"
#include "lldb/Host/OptionParser.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandHistory.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandObjectRegexCommand.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionValueBoolean.h"
#include "lldb/Interpreter/OptionValueString.h"
#include "lldb/Interpreter/OptionValueUInt64.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/StringList.h"
using namespace lldb;
@@ -234,20 +235,13 @@ public:
return "";
}
- int HandleArgumentCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point, int max_return_elements,
- bool &word_complete,
- StringList &matches) override {
- auto completion_str = input[cursor_index].ref;
- completion_str = completion_str.take_front(cursor_char_position);
-
+ int HandleArgumentCompletion(
+ CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
- completion_str, match_start_point, max_return_elements, nullptr,
- word_complete, matches);
- return matches.GetSize();
+ request, nullptr);
+ return request.GetMatches().GetSize();
}
Options *GetOptions() override { return &m_options; }
@@ -330,9 +324,8 @@ protected:
m_interpreter.HandleCommandsFromFile(cmd_file, exe_ctx, options, result);
} else {
- // No options were set, inherit any settings from nested "command
- // source" commands,
- // or set to sane default settings...
+ // No options were set, inherit any settings from nested "command source"
+ // commands, or set to sane default settings...
CommandInterpreterRunOptions options;
m_interpreter.HandleCommandsFromFile(cmd_file, exe_ctx, options, result);
}
@@ -543,9 +536,9 @@ rather than using a positional placeholder:"
~CommandObjectCommandsAlias() override = default;
protected:
- bool DoExecute(const char *raw_command_line,
+ bool DoExecute(llvm::StringRef raw_command_line,
CommandReturnObject &result) override {
- if (!raw_command_line || !raw_command_line[0]) {
+ if (raw_command_line.empty()) {
result.AppendError("'command alias' requires at least two arguments");
return false;
}
@@ -553,42 +546,13 @@ protected:
ExecutionContext exe_ctx = GetCommandInterpreter().GetExecutionContext();
m_option_group.NotifyOptionParsingStarting(&exe_ctx);
- const char *remainder = nullptr;
-
- if (raw_command_line[0] == '-') {
- // We have some options and these options MUST end with --.
- const char *end_options = nullptr;
- const char *s = raw_command_line;
- while (s && s[0]) {
- end_options = ::strstr(s, "--");
- if (end_options) {
- end_options += 2; // Get past the "--"
- if (::isspace(end_options[0])) {
- remainder = end_options;
- while (::isspace(*remainder))
- ++remainder;
- break;
- }
- }
- s = end_options;
- }
-
- if (end_options) {
- Args args(
- llvm::StringRef(raw_command_line, end_options - raw_command_line));
- if (!ParseOptions(args, result))
- return false;
+ OptionsWithRaw args_with_suffix(raw_command_line);
+ const char *remainder = args_with_suffix.GetRawPart().c_str();
- Status error(m_option_group.NotifyOptionParsingFinished(&exe_ctx));
- if (error.Fail()) {
- result.AppendError(error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
- }
- if (nullptr == remainder)
- remainder = raw_command_line;
+ if (args_with_suffix.HasArgs())
+ if (!ParseOptionsAndNotify(args_with_suffix.GetArgs(), result,
+ m_option_group, exe_ctx))
+ return false;
llvm::StringRef raw_command_string(remainder);
Args args(raw_command_string);
@@ -613,8 +577,7 @@ protected:
}
// Strip the new alias name off 'raw_command_string' (leave it on args,
- // which gets passed to 'Execute', which
- // does the stripping itself.
+ // which gets passed to 'Execute', which does the stripping itself.
size_t pos = raw_command_string.find(alias_command);
if (pos == 0) {
raw_command_string = raw_command_string.substr(alias_command.size());
@@ -652,9 +615,8 @@ protected:
return false;
} else if (!cmd_obj->WantsRawCommandString()) {
// Note that args was initialized with the original command, and has not
- // been updated to this point.
- // Therefore can we pass it to the version of Execute that does not
- // need/expect raw input in the alias.
+ // been updated to this point. Therefore can we pass it to the version of
+ // Execute that does not need/expect raw input in the alias.
return HandleAliasingNormalCommand(args, result);
} else {
return HandleAliasingRawCommand(alias_command, raw_command_string,
@@ -1128,8 +1090,8 @@ protected:
return error;
}
const size_t first_separator_char_pos = 1;
- // use the char that follows 's' as the regex separator character
- // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
+ // use the char that follows 's' as the regex separator character so we can
+ // have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
const char separator_char = regex_sed[first_separator_char_pos];
const size_t second_separator_char_pos =
regex_sed.find(separator_char, first_separator_char_pos + 1);
@@ -1158,8 +1120,7 @@ protected:
}
if (third_separator_char_pos != regex_sed_size - 1) {
- // Make sure that everything that follows the last regex
- // separator char
+ // Make sure that everything that follows the last regex separator char
if (regex_sed.find_first_not_of("\t\n\v\f\r ",
third_separator_char_pos + 1) !=
std::string::npos) {
@@ -1307,7 +1268,7 @@ public:
}
protected:
- bool DoExecute(const char *raw_command_line,
+ bool DoExecute(llvm::StringRef raw_command_line,
CommandReturnObject &result) override {
ScriptInterpreter *scripter = m_interpreter.GetScriptInterpreter();
@@ -1396,7 +1357,7 @@ public:
}
protected:
- bool DoExecute(const char *raw_command_line,
+ bool DoExecute(llvm::StringRef raw_command_line,
CommandReturnObject &result) override {
ScriptInterpreter *scripter = m_interpreter.GetScriptInterpreter();
@@ -1462,20 +1423,13 @@ public:
~CommandObjectCommandsScriptImport() override = default;
- int HandleArgumentCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point, int max_return_elements,
- bool &word_complete,
- StringList &matches) override {
- llvm::StringRef completion_str = input[cursor_index].ref;
- completion_str = completion_str.take_front(cursor_char_position);
-
+ int HandleArgumentCompletion(
+ CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
- completion_str, match_start_point, max_return_elements, nullptr,
- word_complete, matches);
- return matches.GetSize();
+ request, nullptr);
+ return request.GetMatches().GetSize();
}
Options *GetOptions() override { return &m_options; }
@@ -1540,10 +1494,11 @@ protected:
// FIXME: this is necessary because CommandObject::CheckRequirements()
// assumes that commands won't ever be recursively invoked, but it's
// actually possible to craft a Python script that does other "command
- // script imports" in __lldb_init_module the real fix is to have recursive
- // commands possible with a CommandInvocation object separate from the
- // CommandObject itself, so that recursive command invocations won't stomp
- // on each other (wrt to execution contents, options, and more)
+ // script imports" in __lldb_init_module the real fix is to have
+ // recursive commands possible with a CommandInvocation object separate
+ // from the CommandObject itself, so that recursive command invocations
+ // won't stomp on each other (wrt to execution contents, options, and
+ // more)
m_exe_ctx.Clear();
if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(
entry.c_str(), m_options.m_allow_reload, init_session, error)) {
@@ -1639,7 +1594,7 @@ protected:
break;
case 's':
m_synchronicity =
- (ScriptedCommandSynchronicity)Args::StringToOptionEnum(
+ (ScriptedCommandSynchronicity)OptionArgParser::ToOptionEnum(
option_arg, GetDefinitions()[option_idx].enum_values, 0, error);
if (!error.Success())
error.SetErrorStringWithFormat(
diff --git a/source/Commands/CommandObjectDisassemble.cpp b/source/Commands/CommandObjectDisassemble.cpp
index 31c54b7d433b..519e5e2dcdb0 100644
--- a/source/Commands/CommandObjectDisassemble.cpp
+++ b/source/Commands/CommandObjectDisassemble.cpp
@@ -20,6 +20,7 @@
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
@@ -101,14 +102,14 @@ Status CommandObjectDisassemble::CommandOptions::SetOptionValue(
break;
case 's': {
- start_addr = Args::StringToAddress(execution_context, option_arg,
- LLDB_INVALID_ADDRESS, &error);
+ start_addr = OptionArgParser::ToAddress(execution_context, option_arg,
+ LLDB_INVALID_ADDRESS, &error);
if (start_addr != LLDB_INVALID_ADDRESS)
some_location_specified = true;
} break;
case 'e': {
- end_addr = Args::StringToAddress(execution_context, option_arg,
- LLDB_INVALID_ADDRESS, &error);
+ end_addr = OptionArgParser::ToAddress(execution_context, option_arg,
+ LLDB_INVALID_ADDRESS, &error);
if (end_addr != LLDB_INVALID_ADDRESS)
some_location_specified = true;
} break;
@@ -125,8 +126,8 @@ Status CommandObjectDisassemble::CommandOptions::SetOptionValue(
case 'l':
frame_line = true;
- // Disassemble the current source line kind of implies showing mixed
- // source code context.
+ // Disassemble the current source line kind of implies showing mixed source
+ // code context.
show_mixed = true;
some_location_specified = true;
break;
@@ -160,15 +161,14 @@ Status CommandObjectDisassemble::CommandOptions::SetOptionValue(
case 'A':
if (execution_context) {
- auto target_sp =
- execution_context ? execution_context->GetTargetSP() : TargetSP();
- auto platform_sp = target_sp ? target_sp->GetPlatform() : PlatformSP();
- arch = Platform::GetAugmentedArchSpec(platform_sp.get(), option_arg);
+ const auto &target_sp = execution_context->GetTargetSP();
+ auto platform_ptr = target_sp ? target_sp->GetPlatform().get() : nullptr;
+ arch = Platform::GetAugmentedArchSpec(platform_ptr, option_arg);
}
break;
case 'a': {
- symbol_containing_addr = Args::StringToAddress(
+ symbol_containing_addr = OptionArgParser::ToAddress(
execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
if (symbol_containing_addr != LLDB_INVALID_ADDRESS) {
some_location_specified = true;
@@ -204,10 +204,9 @@ void CommandObjectDisassemble::CommandOptions::OptionParsingStarting(
execution_context ? execution_context->GetTargetPtr() : nullptr;
// This is a hack till we get the ability to specify features based on
- // architecture. For now GetDisassemblyFlavor
- // is really only valid for x86 (and for the llvm assembler plugin, but I'm
- // papering over that since that is the
- // only disassembler plugin we have...
+ // architecture. For now GetDisassemblyFlavor is really only valid for x86
+ // (and for the llvm assembler plugin, but I'm papering over that since that
+ // is the only disassembler plugin we have...
if (target) {
if (target->GetArchitecture().GetTriple().getArch() == llvm::Triple::x86 ||
target->GetArchitecture().GetTriple().getArch() ==
@@ -374,8 +373,8 @@ bool CommandObjectDisassemble::DoExecute(Args &command,
}
}
- // Did the "m_options.frame_line" find a valid range already? If so
- // skip the rest...
+ // Did the "m_options.frame_line" find a valid range already? If so skip
+ // the rest...
if (range.GetByteSize() == 0) {
if (m_options.at_pc) {
if (frame == nullptr) {
diff --git a/source/Commands/CommandObjectExpression.cpp b/source/Commands/CommandObjectExpression.cpp
index 01ca31111555..08959ff8473d 100644
--- a/source/Commands/CommandObjectExpression.cpp
+++ b/source/Commands/CommandObjectExpression.cpp
@@ -27,6 +27,7 @@
#include "lldb/Host/OptionParser.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Target/Language.h"
@@ -88,7 +89,7 @@ Status CommandObjectExpression::CommandOptions::SetOptionValue(
case 'a': {
bool success;
bool result;
- result = Args::StringToBoolean(option_arg, true, &success);
+ result = OptionArgParser::ToBoolean(option_arg, true, &success);
if (!success)
error.SetErrorStringWithFormat(
"invalid all-threads value setting: \"%s\"",
@@ -99,7 +100,7 @@ Status CommandObjectExpression::CommandOptions::SetOptionValue(
case 'i': {
bool success;
- bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
+ bool tmp_value = OptionArgParser::ToBoolean(option_arg, true, &success);
if (success)
ignore_breakpoints = tmp_value;
else
@@ -111,7 +112,7 @@ Status CommandObjectExpression::CommandOptions::SetOptionValue(
case 'j': {
bool success;
- bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
+ bool tmp_value = OptionArgParser::ToBoolean(option_arg, true, &success);
if (success)
allow_jit = tmp_value;
else
@@ -131,7 +132,7 @@ Status CommandObjectExpression::CommandOptions::SetOptionValue(
case 'u': {
bool success;
- bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
+ bool tmp_value = OptionArgParser::ToBoolean(option_arg, true, &success);
if (success)
unwind_on_error = tmp_value;
else
@@ -146,8 +147,8 @@ Status CommandObjectExpression::CommandOptions::SetOptionValue(
m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityFull;
break;
}
- m_verbosity =
- (LanguageRuntimeDescriptionDisplayVerbosity)Args::StringToOptionEnum(
+ m_verbosity = (LanguageRuntimeDescriptionDisplayVerbosity)
+ OptionArgParser::ToOptionEnum(
option_arg, GetDefinitions()[option_idx].enum_values, 0, error);
if (!error.Success())
error.SetErrorStringWithFormat(
@@ -167,7 +168,7 @@ Status CommandObjectExpression::CommandOptions::SetOptionValue(
case 'X': {
bool success;
- bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
+ bool tmp_value = OptionArgParser::ToBoolean(option_arg, true, &success);
if (success)
auto_apply_fixits = tmp_value ? eLazyBoolYes : eLazyBoolNo;
else
@@ -317,13 +318,13 @@ CanBeUsedForElementCountPrinting(ValueObject &valobj) {
return Status();
}
-bool CommandObjectExpression::EvaluateExpression(const char *expr,
+bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr,
Stream *output_stream,
Stream *error_stream,
CommandReturnObject *result) {
- // Don't use m_exe_ctx as this might be called asynchronously
- // after the command object DoExecute has finished when doing
- // multi-line expression that use an input reader...
+ // Don't use m_exe_ctx as this might be called asynchronously after the
+ // command object DoExecute has finished when doing multi-line expression
+ // that use an input reader...
ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
Target *target = exe_ctx.GetTargetPtr();
@@ -362,8 +363,8 @@ bool CommandObjectExpression::EvaluateExpression(const char *expr,
if (m_command_options.top_level)
options.SetExecutionPolicy(eExecutionPolicyTopLevel);
- // If there is any chance we are going to stop and want to see
- // what went wrong with our expression, we should generate debug info
+ // 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);
@@ -474,9 +475,8 @@ bool CommandObjectExpression::IOHandlerIsInputComplete(IOHandler &io_handler,
// An empty lines is used to indicate the end of input
const size_t num_lines = lines.GetSize();
if (num_lines > 0 && lines[num_lines - 1].empty()) {
- // Remove the last empty line from "lines" so it doesn't appear
- // in our resulting input and return true to indicate we are done
- // getting lines
+ // Remove the last empty line from "lines" so it doesn't appear in our
+ // resulting input and return true to indicate we are done getting lines
lines.PopBack();
return true;
}
@@ -508,125 +508,91 @@ void CommandObjectExpression::GetMultilineExpression() {
debugger.PushIOHandler(io_handler_sp);
}
-bool CommandObjectExpression::DoExecute(const char *command,
+bool CommandObjectExpression::DoExecute(llvm::StringRef command,
CommandReturnObject &result) {
m_fixed_expression.clear();
auto exe_ctx = GetCommandInterpreter().GetExecutionContext();
m_option_group.NotifyOptionParsingStarting(&exe_ctx);
- const char *expr = nullptr;
-
- if (command[0] == '\0') {
+ if (command.empty()) {
GetMultilineExpression();
return result.Succeeded();
}
- if (command[0] == '-') {
- // We have some options and these options MUST end with --.
- const char *end_options = nullptr;
- const char *s = command;
- while (s && s[0]) {
- end_options = ::strstr(s, "--");
- if (end_options) {
- end_options += 2; // Get past the "--"
- if (::isspace(end_options[0])) {
- expr = end_options;
- while (::isspace(*expr))
- ++expr;
- break;
- }
- }
- s = end_options;
- }
-
- if (end_options) {
- Args args(llvm::StringRef(command, end_options - command));
- if (!ParseOptions(args, result))
- return false;
+ OptionsWithRaw args(command);
+ llvm::StringRef expr = args.GetRawPart();
- Status error(m_option_group.NotifyOptionParsingFinished(&exe_ctx));
- if (error.Fail()) {
- result.AppendError(error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ if (args.HasArgs()) {
+ if (!ParseOptionsAndNotify(args.GetArgs(), result, m_option_group, exe_ctx))
+ return false;
- if (m_repl_option.GetOptionValue().GetCurrentValue()) {
- Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
- if (target) {
- // Drop into REPL
- m_expr_lines.clear();
- m_expr_line_count = 0;
+ if (m_repl_option.GetOptionValue().GetCurrentValue()) {
+ Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
+ if (target) {
+ // Drop into REPL
+ m_expr_lines.clear();
+ m_expr_line_count = 0;
- Debugger &debugger = target->GetDebugger();
+ Debugger &debugger = target->GetDebugger();
- // Check if the LLDB command interpreter is sitting on top of a REPL
- // that
- // launched it...
- if (debugger.CheckTopIOHandlerTypes(
- IOHandler::Type::CommandInterpreter, IOHandler::Type::REPL)) {
- // the LLDB command interpreter is sitting on top of a REPL that
- // launched it,
- // so just say the command interpreter is done and fall back to the
- // existing REPL
- m_interpreter.GetIOHandler(false)->SetIsDone(true);
- } else {
- // We are launching the REPL on top of the current LLDB command
- // interpreter,
- // so just push one
- bool initialize = false;
- Status repl_error;
- REPLSP repl_sp(target->GetREPL(
- repl_error, m_command_options.language, nullptr, false));
+ // Check if the LLDB command interpreter is sitting on top of a REPL
+ // that launched it...
+ if (debugger.CheckTopIOHandlerTypes(IOHandler::Type::CommandInterpreter,
+ IOHandler::Type::REPL)) {
+ // the LLDB command interpreter is sitting on top of a REPL that
+ // launched it, so just say the command interpreter is done and
+ // fall back to the existing REPL
+ m_interpreter.GetIOHandler(false)->SetIsDone(true);
+ } else {
+ // We are launching the REPL on top of the current LLDB command
+ // interpreter, so just push one
+ bool initialize = false;
+ Status repl_error;
+ REPLSP repl_sp(target->GetREPL(repl_error, m_command_options.language,
+ nullptr, false));
- if (!repl_sp) {
- initialize = true;
- repl_sp = target->GetREPL(repl_error, m_command_options.language,
- nullptr, true);
- if (!repl_error.Success()) {
- result.SetError(repl_error);
- return result.Succeeded();
- }
+ if (!repl_sp) {
+ initialize = true;
+ repl_sp = target->GetREPL(repl_error, m_command_options.language,
+ nullptr, true);
+ if (!repl_error.Success()) {
+ result.SetError(repl_error);
+ return result.Succeeded();
}
+ }
- if (repl_sp) {
- if (initialize) {
- repl_sp->SetCommandOptions(m_command_options);
- repl_sp->SetFormatOptions(m_format_options);
- repl_sp->SetValueObjectDisplayOptions(m_varobj_options);
- }
+ if (repl_sp) {
+ if (initialize) {
+ repl_sp->SetCommandOptions(m_command_options);
+ repl_sp->SetFormatOptions(m_format_options);
+ repl_sp->SetValueObjectDisplayOptions(m_varobj_options);
+ }
- IOHandlerSP io_handler_sp(repl_sp->GetIOHandler());
+ IOHandlerSP io_handler_sp(repl_sp->GetIOHandler());
- io_handler_sp->SetIsDone(false);
+ io_handler_sp->SetIsDone(false);
- debugger.PushIOHandler(io_handler_sp);
- } else {
- repl_error.SetErrorStringWithFormat(
- "Couldn't create a REPL for %s",
- Language::GetNameForLanguageType(m_command_options.language));
- result.SetError(repl_error);
- return result.Succeeded();
- }
+ debugger.PushIOHandler(io_handler_sp);
+ } else {
+ repl_error.SetErrorStringWithFormat(
+ "Couldn't create a REPL for %s",
+ Language::GetNameForLanguageType(m_command_options.language));
+ result.SetError(repl_error);
+ return result.Succeeded();
}
}
}
- // No expression following options
- else if (expr == nullptr || expr[0] == '\0') {
- GetMultilineExpression();
- return result.Succeeded();
- }
+ }
+ // No expression following options
+ else if (expr.empty()) {
+ GetMultilineExpression();
+ return result.Succeeded();
}
}
- if (expr == nullptr)
- expr = command;
-
+ Target *target = GetSelectedOrDummyTarget();
if (EvaluateExpression(expr, &(result.GetOutputStream()),
&(result.GetErrorStream()), &result)) {
- Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
- if (!target)
- target = GetDummyTarget();
if (!m_fixed_expression.empty() && target->GetEnableNotifyAboutFixIts()) {
CommandHistory &history = m_interpreter.GetCommandHistory();
@@ -634,18 +600,21 @@ bool CommandObjectExpression::DoExecute(const char *command,
// for expr???)
// If we can it would be nice to show that.
std::string fixed_command("expression ");
- if (expr == command)
- fixed_command.append(m_fixed_expression);
- else {
+ if (args.HasArgs()) {
// Add in any options that might have been in the original command:
- fixed_command.append(command, expr - command);
+ fixed_command.append(args.GetArgStringWithDelimiter());
+ fixed_command.append(m_fixed_expression);
+ } else
fixed_command.append(m_fixed_expression);
- }
history.AppendString(fixed_command);
}
+ // Increment statistics to record this expression evaluation success.
+ target->IncrementStats(StatisticKind::ExpressionSuccessful);
return true;
}
+ // Increment statistics to record this expression evaluation failure.
+ target->IncrementStats(StatisticKind::ExpressionFailure);
result.SetStatus(eReturnStatusFailed);
return false;
}
diff --git a/source/Commands/CommandObjectExpression.h b/source/Commands/CommandObjectExpression.h
index 0cf2a7263d52..710f87140977 100644
--- a/source/Commands/CommandObjectExpression.h
+++ b/source/Commands/CommandObjectExpression.h
@@ -72,9 +72,9 @@ protected:
bool IOHandlerIsInputComplete(IOHandler &io_handler,
StringList &lines) override;
- bool DoExecute(const char *command, CommandReturnObject &result) override;
+ bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override;
- bool EvaluateExpression(const char *expr, Stream *output_stream,
+ bool EvaluateExpression(llvm::StringRef expr, Stream *output_stream,
Stream *error_stream,
CommandReturnObject *result = NULL);
diff --git a/source/Commands/CommandObjectFrame.cpp b/source/Commands/CommandObjectFrame.cpp
index 0bcc35062968..0183c43f85b5 100644
--- a/source/Commands/CommandObjectFrame.cpp
+++ b/source/Commands/CommandObjectFrame.cpp
@@ -24,7 +24,6 @@
#include "lldb/DataFormatters/ValueObjectPrinter.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/OptionParser.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionGroupFormat.h"
@@ -44,6 +43,7 @@
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
@@ -342,8 +342,8 @@ protected:
frame_idx += m_options.relative_frame_offset;
else {
if (frame_idx == 0) {
- // If you are already at the bottom of the stack, then just warn and
- // don't reset the frame.
+ // If you are already at the bottom of the stack, then just warn
+ // and don't reset the frame.
result.AppendError("Already at the bottom of the stack.");
result.SetStatus(eReturnStatusFailed);
return false;
@@ -463,21 +463,14 @@ public:
Options *GetOptions() override { return &m_option_group; }
- int HandleArgumentCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point, int max_return_elements,
- bool &word_complete,
- StringList &matches) override {
+ int HandleArgumentCompletion(
+ CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
// Arguments are the standard source file completer.
- auto completion_str = input[cursor_index].ref;
- completion_str = completion_str.take_front(cursor_char_position);
-
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eVariablePathCompletion,
- completion_str, match_start_point, max_return_elements, nullptr,
- word_complete, matches);
- return matches.GetSize();
+ request, nullptr);
+ return request.GetMatches().GetSize();
}
protected:
@@ -504,16 +497,15 @@ protected:
}
bool DoExecute(Args &command, CommandReturnObject &result) override {
- // No need to check "frame" for validity as eCommandRequiresFrame ensures it
- // is valid
+ // No need to check "frame" for validity as eCommandRequiresFrame ensures
+ // it is valid
StackFrame *frame = m_exe_ctx.GetFramePtr();
Stream &s = result.GetOutputStream();
// Be careful about the stack frame, if any summary formatter runs code, it
- // might clear the StackFrameList
- // for the thread. So hold onto a shared pointer to the frame so it stays
- // alive.
+ // might clear the StackFrameList for the thread. So hold onto a shared
+ // pointer to the frame so it stays alive.
VariableList *variable_list =
frame->GetVariableList(m_option_variable.show_globals);
@@ -547,8 +539,8 @@ protected:
if (!command.empty()) {
VariableList regex_var_list;
- // If we have any args to the variable command, we will make
- // variable objects from them...
+ // If we have any args to the variable command, we will make variable
+ // objects from them...
for (auto &entry : command) {
if (m_option_variable.use_regex) {
const size_t regex_start_index = regex_var_list.GetSize();
@@ -620,9 +612,6 @@ protected:
if (!scope_string.empty())
s.PutCString(scope_string);
-
- // if (format != eFormatDefault)
- // valobj_sp->SetFormat (format);
if (m_option_variable.show_decl && var_sp &&
var_sp->GetDeclaration().GetFile()) {
var_sp->GetDeclaration().DumpStopContext(&s, false);
@@ -680,14 +669,13 @@ protected:
if (m_option_variable.show_scope)
scope_string = GetScopeString(var_sp).str();
- // Use the variable object code to make sure we are
- // using the same APIs as the public API will be
- // using...
+ // Use the variable object code to make sure we are using the same
+ // APIs as the public API will be using...
valobj_sp = frame->GetValueObjectForFrameVariable(
var_sp, m_varobj_options.use_dynamic);
if (valobj_sp) {
- // When dumping all variables, don't print any variables
- // that are not in scope to avoid extra unneeded output
+ // When dumping all variables, don't print any variables that are
+ // not in scope to avoid extra unneeded output
if (valobj_sp->IsInScope()) {
if (!valobj_sp->GetTargetSP()
->GetDisplayRuntimeSupportValues() &&
@@ -723,7 +711,14 @@ protected:
m_interpreter.TruncationWarningGiven();
}
- return result.Succeeded();
+ // Increment statistics.
+ bool res = result.Succeeded();
+ Target *target = GetSelectedOrDummyTarget();
+ if (res)
+ target->IncrementStats(StatisticKind::FrameVarSuccess);
+ else
+ target->IncrementStats(StatisticKind::FrameVarFailure);
+ return res;
}
protected:
diff --git a/source/Commands/CommandObjectHelp.cpp b/source/Commands/CommandObjectHelp.cpp
index 99e9d7b3abd4..903c6011b03f 100644
--- a/source/Commands/CommandObjectHelp.cpp
+++ b/source/Commands/CommandObjectHelp.cpp
@@ -89,10 +89,9 @@ bool CommandObjectHelp::DoExecute(Args &command, CommandReturnObject &result) {
CommandObject *cmd_obj;
const size_t argc = command.GetArgumentCount();
- // 'help' doesn't take any arguments, other than command names. If argc is 0,
- // we show the user
- // all commands (aliases and user commands if asked for). Otherwise every
- // argument must be the name of a command or a sub-command.
+ // 'help' doesn't take any arguments, other than command names. If argc is
+ // 0, we show the user all commands (aliases and user commands if asked for).
+ // Otherwise every argument must be the name of a command or a sub-command.
if (argc == 0) {
uint32_t cmd_types = CommandInterpreter::eCommandTypesBuiltin;
if (m_options.m_show_aliases)
@@ -210,34 +209,24 @@ bool CommandObjectHelp::DoExecute(Args &command, CommandReturnObject &result) {
return result.Succeeded();
}
-int CommandObjectHelp::HandleCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) {
+int CommandObjectHelp::HandleCompletion(CompletionRequest &request) {
// Return the completions of the commands in the help system:
- if (cursor_index == 0) {
- return m_interpreter.HandleCompletionMatches(
- input, cursor_index, cursor_char_position, match_start_point,
- max_return_elements, word_complete, matches);
+ if (request.GetCursorIndex() == 0) {
+ return m_interpreter.HandleCompletionMatches(request);
} else {
- CommandObject *cmd_obj = m_interpreter.GetCommandObject(input[0].ref);
+ CommandObject *cmd_obj =
+ m_interpreter.GetCommandObject(request.GetParsedLine()[0].ref);
// The command that they are getting help on might be ambiguous, in which
- // case we should complete that,
- // otherwise complete with the command the user is getting help on...
+ // case we should complete that, otherwise complete with the command the
+ // user is getting help on...
if (cmd_obj) {
- input.Shift();
- cursor_index--;
- return cmd_obj->HandleCompletion(
- input, cursor_index, cursor_char_position, match_start_point,
- max_return_elements, word_complete, matches);
+ request.GetParsedLine().Shift();
+ request.SetCursorIndex(request.GetCursorIndex() - 1);
+ return cmd_obj->HandleCompletion(request);
} else {
- return m_interpreter.HandleCompletionMatches(
- input, cursor_index, cursor_char_position, match_start_point,
- max_return_elements, word_complete, matches);
+ return m_interpreter.HandleCompletionMatches(request);
}
}
}
diff --git a/source/Commands/CommandObjectHelp.h b/source/Commands/CommandObjectHelp.h
index f1f87f8e63cc..c78682dead1f 100644
--- a/source/Commands/CommandObjectHelp.h
+++ b/source/Commands/CommandObjectHelp.h
@@ -30,10 +30,7 @@ public:
~CommandObjectHelp() override;
- int HandleCompletion(Args &input, int &cursor_index,
- int &cursor_char_position, int match_start_point,
- int max_return_elements, bool &word_complete,
- StringList &matches) override;
+ int HandleCompletion(CompletionRequest &request) override;
static void GenerateAdditionalHelpAvenuesMessage(
Stream *s, llvm::StringRef command, llvm::StringRef prefix,
diff --git a/source/Commands/CommandObjectLog.cpp b/source/Commands/CommandObjectLog.cpp
index ef82d07f15fb..1389ff2bde02 100644
--- a/source/Commands/CommandObjectLog.cpp
+++ b/source/Commands/CommandObjectLog.cpp
@@ -16,9 +16,9 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Host/OptionParser.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -26,6 +26,7 @@
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"
@@ -100,7 +101,7 @@ public:
switch (short_option) {
case 'f':
- log_file.SetFile(option_arg, true);
+ log_file.SetFile(option_arg, true, FileSpec::Style::native);
break;
case 't':
log_options |= LLDB_LOG_OPTION_THREADSAFE;
@@ -345,7 +346,7 @@ protected:
}
} else if (sub_command.equals_lower("increment")) {
bool success;
- bool increment = Args::StringToBoolean(param, false, &success);
+ bool increment = OptionArgParser::ToBoolean(param, false, &success);
if (success) {
Timer::SetQuiet(!increment);
result.SetStatus(eReturnStatusSuccessFinishNoResult);
diff --git a/source/Commands/CommandObjectMemory.cpp b/source/Commands/CommandObjectMemory.cpp
index 8f4c186a8d69..e4a49e55857d 100644
--- a/source/Commands/CommandObjectMemory.cpp
+++ b/source/Commands/CommandObjectMemory.cpp
@@ -24,9 +24,9 @@
#include "lldb/Core/ValueObjectMemory.h"
#include "lldb/DataFormatters/ValueObjectPrinter.h"
#include "lldb/Host/OptionParser.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionGroupFormat.h"
#include "lldb/Interpreter/OptionGroupOutputFile.h"
#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
@@ -40,6 +40,7 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataBufferLLVM.h"
#include "lldb/Utility/StreamString.h"
@@ -553,8 +554,8 @@ protected:
lldb::addr_t addr;
size_t total_byte_size = 0;
if (argc == 0) {
- // Use the last address and byte size and all options as they were
- // if no options have been set
+ // Use the last address and byte size and all options as they were if no
+ // options have been set
addr = m_next_addr;
total_byte_size = m_prev_byte_size;
clang_ast_type = m_prev_clang_ast_type;
@@ -573,8 +574,8 @@ protected:
// TODO For non-8-bit byte addressable architectures this needs to be
// revisited to fully support all lldb's range of formatting options.
- // Furthermore code memory reads (for those architectures) will not
- // be correctly formatted even w/o formatting options.
+ // Furthermore code memory reads (for those architectures) will not be
+ // correctly formatted even w/o formatting options.
size_t item_byte_size =
target->GetArchitecture().GetDataByteSize() > 1
? target->GetArchitecture().GetDataByteSize()
@@ -590,8 +591,8 @@ protected:
}
if (argc > 0)
- addr = Args::StringToAddress(&m_exe_ctx, command[0].ref,
- LLDB_INVALID_ADDRESS, &error);
+ addr = OptionArgParser::ToAddress(&m_exe_ctx, command[0].ref,
+ LLDB_INVALID_ADDRESS, &error);
if (addr == LLDB_INVALID_ADDRESS) {
result.AppendError("invalid start address expression.");
@@ -601,7 +602,7 @@ protected:
}
if (argc == 2) {
- lldb::addr_t end_addr = Args::StringToAddress(
+ lldb::addr_t end_addr = OptionArgParser::ToAddress(
&m_exe_ctx, command[1].ref, LLDB_INVALID_ADDRESS, nullptr);
if (end_addr == LLDB_INVALID_ADDRESS) {
result.AppendError("invalid end address expression.");
@@ -843,16 +844,14 @@ protected:
if (!m_format_options.GetCountValue().OptionWasSet() || item_count == 1) {
// this turns requests such as
// memory read -fc -s10 -c1 *charPtrPtr
- // which make no sense (what is a char of size 10?)
- // into a request for fetching 10 chars of size 1 from the same memory
- // location
+ // which make no sense (what is a char of size 10?) into a request for
+ // fetching 10 chars of size 1 from the same memory location
format = eFormatCharArray;
item_count = item_byte_size;
item_byte_size = 1;
} else {
- // 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
+ // 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 %" PRIu64 " is not supported",
(uint64_t)item_byte_size);
@@ -1036,13 +1035,13 @@ protected:
}
Status error;
- lldb::addr_t low_addr = Args::StringToAddress(&m_exe_ctx, command[0].ref,
- LLDB_INVALID_ADDRESS, &error);
+ lldb::addr_t low_addr = OptionArgParser::ToAddress(
+ &m_exe_ctx, command[0].ref, LLDB_INVALID_ADDRESS, &error);
if (low_addr == LLDB_INVALID_ADDRESS || error.Fail()) {
result.AppendError("invalid low address");
return false;
}
- lldb::addr_t high_addr = Args::StringToAddress(
+ lldb::addr_t high_addr = OptionArgParser::ToAddress(
&m_exe_ctx, command[1].ref, LLDB_INVALID_ADDRESS, &error);
if (high_addr == LLDB_INVALID_ADDRESS || error.Fail()) {
result.AppendError("invalid high address");
@@ -1210,7 +1209,7 @@ public:
switch (short_option) {
case 'i':
- m_infile.SetFile(option_value, true);
+ m_infile.SetFile(option_value, true, FileSpec::Style::native);
if (!m_infile.Exists()) {
m_infile.Clear();
error.SetErrorStringWithFormat("input file does not exist: '%s'",
@@ -1345,8 +1344,8 @@ protected:
size_t item_byte_size = byte_size_value.GetCurrentValue();
Status error;
- lldb::addr_t addr = Args::StringToAddress(&m_exe_ctx, command[0].ref,
- LLDB_INVALID_ADDRESS, &error);
+ lldb::addr_t addr = OptionArgParser::ToAddress(
+ &m_exe_ctx, command[0].ref, LLDB_INVALID_ADDRESS, &error);
if (addr == LLDB_INVALID_ADDRESS) {
result.AppendError("invalid address expression\n");
@@ -1469,7 +1468,7 @@ protected:
break;
}
case eFormatBoolean:
- uval64 = Args::StringToBoolean(entry.ref, false, &success);
+ uval64 = OptionArgParser::ToBoolean(entry.ref, false, &success);
if (!success) {
result.AppendErrorWithFormat(
"'%s' is not a valid boolean string value.\n", entry.c_str());
@@ -1642,8 +1641,8 @@ protected:
}
Status error;
- lldb::addr_t addr = Args::StringToAddress(&m_exe_ctx, command[0].ref,
- LLDB_INVALID_ADDRESS, &error);
+ lldb::addr_t addr = OptionArgParser::ToAddress(
+ &m_exe_ctx, command[0].ref, LLDB_INVALID_ADDRESS, &error);
if (addr == LLDB_INVALID_ADDRESS) {
result.AppendError("invalid address expression");
@@ -1709,10 +1708,10 @@ protected:
m_cmd_name.c_str(), m_cmd_syntax.c_str());
result.SetStatus(eReturnStatusFailed);
} else {
- auto load_addr_str = command[0].ref;
if (command.GetArgumentCount() == 1) {
- load_addr = Args::StringToAddress(&m_exe_ctx, load_addr_str,
- LLDB_INVALID_ADDRESS, &error);
+ auto load_addr_str = command[0].ref;
+ load_addr = OptionArgParser::ToAddress(&m_exe_ctx, load_addr_str,
+ LLDB_INVALID_ADDRESS, &error);
if (error.Fail() || load_addr == LLDB_INVALID_ADDRESS) {
result.AppendErrorWithFormat(
"invalid address argument \"%s\": %s\n", command[0].c_str(),
diff --git a/source/Commands/CommandObjectMultiword.cpp b/source/Commands/CommandObjectMultiword.cpp
index 0d0aa108a4ce..ade1a2d01f38 100644
--- a/source/Commands/CommandObjectMultiword.cpp
+++ b/source/Commands/CommandObjectMultiword.cpp
@@ -55,8 +55,7 @@ CommandObjectSP CommandObjectMultiword::GetSubcommandSP(llvm::StringRef sub_cmd,
if (num_matches == 1) {
// Cleaner, but slightly less efficient would be to call back into this
- // function, since I now
- // know I have an exact match...
+ // function, since I now know I have an exact match...
sub_cmd = matches->GetStringAtIndex(0);
pos = m_subcommand_dict.find(sub_cmd);
@@ -121,8 +120,8 @@ bool CommandObjectMultiword::Execute(const char *args_string,
CommandObject *sub_cmd_obj = GetSubcommandObject(sub_command, &matches);
if (sub_cmd_obj != nullptr) {
// Now call CommandObject::Execute to process options in `rest_of_line`.
- // From there the command-specific version of Execute will be called,
- // with the processed arguments.
+ // From there the command-specific version of Execute will be called, with
+ // the processed arguments.
args.Shift();
sub_cmd_obj->Execute(args_string, result);
@@ -156,8 +155,8 @@ bool CommandObjectMultiword::Execute(const char *args_string,
}
void CommandObjectMultiword::GenerateHelpText(Stream &output_stream) {
- // First time through here, generate the help text for the object and
- // push it to the return result object as well
+ // First time through here, generate the help text for the object and push it
+ // to the return result object as well
CommandObject::GenerateHelpText(output_stream);
output_stream.PutCString("\nThe following subcommands are supported:\n\n");
@@ -187,18 +186,14 @@ void CommandObjectMultiword::GenerateHelpText(Stream &output_stream) {
"'help <command> <subcommand>'.\n");
}
-int CommandObjectMultiword::HandleCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) {
+int CommandObjectMultiword::HandleCompletion(CompletionRequest &request) {
// Any of the command matches will provide a complete word, otherwise the
// individual completers will override this.
- word_complete = true;
+ request.SetWordComplete(true);
+ auto &matches = request.GetMatches();
- auto arg0 = input[0].ref;
- if (cursor_index == 0) {
+ auto arg0 = request.GetParsedLine()[0].ref;
+ if (request.GetCursorIndex() == 0) {
AddNamesMatchingPartialString(m_subcommand_dict, arg0, matches);
if (matches.GetSize() == 1 && matches.GetStringAtIndex(0) != nullptr &&
@@ -206,16 +201,14 @@ int CommandObjectMultiword::HandleCompletion(Args &input, int &cursor_index,
StringList temp_matches;
CommandObject *cmd_obj = GetSubcommandObject(arg0, &temp_matches);
if (cmd_obj != nullptr) {
- if (input.GetArgumentCount() == 1) {
- word_complete = true;
+ if (request.GetParsedLine().GetArgumentCount() == 1) {
+ request.SetWordComplete(true);
} else {
matches.DeleteStringAtIndex(0);
- input.Shift();
- cursor_char_position = 0;
- input.AppendArgument(llvm::StringRef());
- return cmd_obj->HandleCompletion(
- input, cursor_index, cursor_char_position, match_start_point,
- max_return_elements, word_complete, matches);
+ request.GetParsedLine().Shift();
+ request.SetCursorCharPosition(0);
+ request.GetParsedLine().AppendArgument(llvm::StringRef());
+ return cmd_obj->HandleCompletion(request);
}
}
}
@@ -227,11 +220,9 @@ int CommandObjectMultiword::HandleCompletion(Args &input, int &cursor_index,
} else {
// Remove the one match that we got from calling GetSubcommandObject.
matches.DeleteStringAtIndex(0);
- input.Shift();
- cursor_index--;
- return sub_command_object->HandleCompletion(
- input, cursor_index, cursor_char_position, match_start_point,
- max_return_elements, word_complete, matches);
+ request.GetParsedLine().Shift();
+ request.SetCursorIndex(request.GetCursorIndex() - 1);
+ return sub_command_object->HandleCompletion(request);
}
}
}
@@ -371,31 +362,20 @@ Options *CommandObjectProxy::GetOptions() {
return nullptr;
}
-int CommandObjectProxy::HandleCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) {
+int CommandObjectProxy::HandleCompletion(CompletionRequest &request) {
CommandObject *proxy_command = GetProxyCommandObject();
if (proxy_command)
- return proxy_command->HandleCompletion(
- input, cursor_index, cursor_char_position, match_start_point,
- max_return_elements, word_complete, matches);
- matches.Clear();
+ return proxy_command->HandleCompletion(request);
+ request.GetMatches().Clear();
return 0;
}
int CommandObjectProxy::HandleArgumentCompletion(
- Args &input, int &cursor_index, int &cursor_char_position,
- OptionElementVector &opt_element_vector, int match_start_point,
- int max_return_elements, bool &word_complete, StringList &matches) {
+ CompletionRequest &request, OptionElementVector &opt_element_vector) {
CommandObject *proxy_command = GetProxyCommandObject();
if (proxy_command)
- return proxy_command->HandleArgumentCompletion(
- input, cursor_index, cursor_char_position, opt_element_vector,
- match_start_point, max_return_elements, word_complete, matches);
- matches.Clear();
+ return proxy_command->HandleArgumentCompletion(request, opt_element_vector);
+ request.GetMatches().Clear();
return 0;
}
diff --git a/source/Commands/CommandObjectPlatform.cpp b/source/Commands/CommandObjectPlatform.cpp
index 8ed003767d58..f822a8b54cb0 100644
--- a/source/Commands/CommandObjectPlatform.cpp
+++ b/source/Commands/CommandObjectPlatform.cpp
@@ -18,7 +18,6 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Host/OptionParser.h"
#include "lldb/Host/StringConvert.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandOptionValidators.h"
#include "lldb/Interpreter/CommandReturnObject.h"
@@ -27,6 +26,7 @@
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/DataExtractor.h"
#include "llvm/ADT/SmallString.h"
@@ -178,17 +178,10 @@ public:
~CommandObjectPlatformSelect() override = default;
- int HandleCompletion(Args &input, int &cursor_index,
- int &cursor_char_position, int match_start_point,
- int max_return_elements, bool &word_complete,
- StringList &matches) override {
- std::string completion_str(input.GetArgumentAtIndex(cursor_index));
- completion_str.erase(cursor_char_position);
-
- CommandCompletions::PlatformPluginNames(
- GetCommandInterpreter(), completion_str.c_str(), match_start_point,
- max_return_elements, nullptr, word_complete, matches);
- return matches.GetSize();
+ int HandleCompletion(CompletionRequest &request) override {
+ CommandCompletions::PlatformPluginNames(GetCommandInterpreter(), request,
+ nullptr);
+ return request.GetMatches().GetSize();
}
Options *GetOptions() override { return &m_option_group; }
@@ -385,8 +378,8 @@ protected:
Status error;
if (platform_sp->IsConnected()) {
- // Cache the instance name if there is one since we are
- // about to disconnect and the name might go with it.
+ // Cache the instance name if there is one since we are about to
+ // disconnect and the name might go with it.
const char *hostname_cstr = platform_sp->GetHostname();
std::string hostname;
if (hostname_cstr)
@@ -867,8 +860,8 @@ public:
// argument entry.
arg2.push_back(file_arg_host);
- // Push the data for the first and the second arguments into the m_arguments
- // vector.
+ // Push the data for the first and the second arguments into the
+ // m_arguments vector.
m_arguments.push_back(arg1);
m_arguments.push_back(arg2);
}
@@ -1059,8 +1052,8 @@ protected:
if (argc > 0) {
if (m_options.launch_info.GetExecutableFile()) {
- // We already have an executable file, so we will use this
- // and all arguments to this function are extra arguments
+ // We already have an executable file, so we will use this and all
+ // arguments to this function are extra arguments
m_options.launch_info.GetArguments().AppendArguments(args);
} else {
// We don't have any file yet, so the first argument is our
@@ -1342,32 +1335,32 @@ protected:
} break;
case 'n':
- match_info.GetProcessInfo().GetExecutableFile().SetFile(option_arg,
- false);
+ match_info.GetProcessInfo().GetExecutableFile().SetFile(
+ option_arg, false, FileSpec::Style::native);
match_info.SetNameMatchType(NameMatch::Equals);
break;
case 'e':
- match_info.GetProcessInfo().GetExecutableFile().SetFile(option_arg,
- false);
+ match_info.GetProcessInfo().GetExecutableFile().SetFile(
+ option_arg, false, FileSpec::Style::native);
match_info.SetNameMatchType(NameMatch::EndsWith);
break;
case 's':
- match_info.GetProcessInfo().GetExecutableFile().SetFile(option_arg,
- false);
+ match_info.GetProcessInfo().GetExecutableFile().SetFile(
+ option_arg, false, FileSpec::Style::native);
match_info.SetNameMatchType(NameMatch::StartsWith);
break;
case 'c':
- match_info.GetProcessInfo().GetExecutableFile().SetFile(option_arg,
- false);
+ match_info.GetProcessInfo().GetExecutableFile().SetFile(
+ option_arg, false, FileSpec::Style::native);
match_info.SetNameMatchType(NameMatch::Contains);
break;
case 'r':
- match_info.GetProcessInfo().GetExecutableFile().SetFile(option_arg,
- false);
+ match_info.GetProcessInfo().GetExecutableFile().SetFile(
+ option_arg, false, FileSpec::Style::native);
match_info.SetNameMatchType(NameMatch::RegularExpression);
break;
@@ -1536,7 +1529,8 @@ public:
break;
case 'n':
- attach_info.GetExecutableFile().SetFile(option_arg, false);
+ attach_info.GetExecutableFile().SetFile(option_arg, false,
+ FileSpec::Style::native);
break;
case 'w':
@@ -1560,11 +1554,8 @@ public:
}
bool HandleOptionArgumentCompletion(
- Args &input, int cursor_index, int char_pos,
- OptionElementVector &opt_element_vector, int opt_element_index,
- int match_start_point, int max_return_elements,
- CommandInterpreter &interpreter, bool &word_complete,
- StringList &matches) override {
+ CompletionRequest &request, OptionElementVector &opt_element_vector,
+ int opt_element_index, CommandInterpreter &interpreter) override {
int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
@@ -1574,11 +1565,10 @@ public:
// Are we in the name?
// Look to see if there is a -P argument provided, and if so use that
- // plugin, otherwise
- // use the default plugin.
+ // plugin, otherwise use the default plugin.
const char *partial_name = nullptr;
- partial_name = input.GetArgumentAtIndex(opt_arg_pos);
+ partial_name = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos);
PlatformSP platform_sp(interpreter.GetPlatform(true));
if (platform_sp) {
@@ -1586,14 +1576,14 @@ public:
ProcessInstanceInfoMatch match_info;
if (partial_name) {
match_info.GetProcessInfo().GetExecutableFile().SetFile(
- partial_name, false);
+ partial_name, false, FileSpec::Style::native);
match_info.SetNameMatchType(NameMatch::StartsWith);
}
platform_sp->FindProcesses(match_info, process_infos);
const uint32_t num_matches = process_infos.GetSize();
if (num_matches > 0) {
for (uint32_t i = 0; i < num_matches; ++i) {
- matches.AppendString(
+ request.GetMatches().AppendString(
process_infos.GetProcessNameAtIndex(i),
process_infos.GetProcessNameLengthAtIndex(i));
}
@@ -1693,7 +1683,7 @@ class CommandObjectPlatformShell : public CommandObjectRaw {
public:
class CommandOptions : public Options {
public:
- CommandOptions() : Options(), timeout(10) {}
+ CommandOptions() : Options() {}
~CommandOptions() override = default;
@@ -1709,11 +1699,13 @@ public:
switch (short_option) {
case 't':
- timeout = 10;
- if (option_arg.getAsInteger(10, timeout))
+ uint32_t timeout_sec;
+ if (option_arg.getAsInteger(10, timeout_sec))
error.SetErrorStringWithFormat(
"could not convert \"%s\" to a numeric value.",
option_arg.str().c_str());
+ else
+ timeout = std::chrono::seconds(timeout_sec);
break;
default:
error.SetErrorStringWithFormat("invalid short option character '%c'",
@@ -1726,7 +1718,7 @@ public:
void OptionParsingStarting(ExecutionContext *execution_context) override {}
- uint32_t timeout;
+ Timeout<std::micro> timeout = std::chrono::seconds(10);
};
CommandObjectPlatformShell(CommandInterpreter &interpreter)
@@ -1739,47 +1731,24 @@ public:
Options *GetOptions() override { return &m_options; }
- bool DoExecute(const char *raw_command_line,
+ bool DoExecute(llvm::StringRef raw_command_line,
CommandReturnObject &result) override {
ExecutionContext exe_ctx = GetCommandInterpreter().GetExecutionContext();
m_options.NotifyOptionParsingStarting(&exe_ctx);
- const char *expr = nullptr;
// Print out an usage syntax on an empty command line.
- if (raw_command_line[0] == '\0') {
+ if (raw_command_line.empty()) {
result.GetOutputStream().Printf("%s\n", this->GetSyntax().str().c_str());
return true;
}
- if (raw_command_line[0] == '-') {
- // We have some options and these options MUST end with --.
- const char *end_options = nullptr;
- const char *s = raw_command_line;
- while (s && s[0]) {
- end_options = ::strstr(s, "--");
- if (end_options) {
- end_options += 2; // Get past the "--"
- if (::isspace(end_options[0])) {
- expr = end_options;
- while (::isspace(*expr))
- ++expr;
- break;
- }
- }
- s = end_options;
- }
+ OptionsWithRaw args(raw_command_line);
+ const char *expr = args.GetRawPart().c_str();
- if (end_options) {
- Args args(
- llvm::StringRef(raw_command_line, end_options - raw_command_line));
- if (!ParseOptions(args, result))
- return false;
- }
- }
-
- if (expr == nullptr)
- expr = raw_command_line;
+ if (args.HasArgs())
+ if (!ParseOptions(args.GetArgs(), result))
+ return false;
PlatformSP platform_sp(
m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
diff --git a/source/Commands/CommandObjectPlugin.cpp b/source/Commands/CommandObjectPlugin.cpp
index 7e1b7f61f766..1f379a2660ed 100644
--- a/source/Commands/CommandObjectPlugin.cpp
+++ b/source/Commands/CommandObjectPlugin.cpp
@@ -42,20 +42,13 @@ public:
~CommandObjectPluginLoad() override = default;
- int HandleArgumentCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point, int max_return_elements,
- bool &word_complete,
- StringList &matches) override {
- auto completion_str = input[cursor_index].ref;
- completion_str = completion_str.take_front(cursor_char_position);
-
+ int HandleArgumentCompletion(
+ CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
- completion_str, match_start_point, max_return_elements, nullptr,
- word_complete, matches);
- return matches.GetSize();
+ request, nullptr);
+ return request.GetMatches().GetSize();
}
protected:
diff --git a/source/Commands/CommandObjectProcess.cpp b/source/Commands/CommandObjectProcess.cpp
index 9fbdd7630548..3ac27918df4c 100644
--- a/source/Commands/CommandObjectProcess.cpp
+++ b/source/Commands/CommandObjectProcess.cpp
@@ -21,9 +21,9 @@
#include "lldb/Host/Host.h"
#include "lldb/Host/OptionParser.h"
#include "lldb/Host/StringConvert.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
@@ -31,6 +31,7 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/UnixSignals.h"
+#include "lldb/Utility/Args.h"
using namespace lldb;
using namespace lldb_private;
@@ -133,20 +134,14 @@ public:
~CommandObjectProcessLaunch() override = default;
- int HandleArgumentCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point, int max_return_elements,
- bool &word_complete,
- StringList &matches) override {
- std::string completion_str(input.GetArgumentAtIndex(cursor_index));
- completion_str.erase(cursor_char_position);
+ int HandleArgumentCompletion(
+ CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
- completion_str.c_str(), match_start_point, max_return_elements, nullptr,
- word_complete, matches);
- return matches.GetSize();
+ request, nullptr);
+ return request.GetMatches().GetSize();
}
Options *GetOptions() override { return &m_options; }
@@ -179,18 +174,18 @@ protected:
llvm::StringRef target_settings_argv0 = target->GetArg0();
// 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
+ // (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.
+ // 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.
+ // The user did not explicitly specify whether to disable ASLR. Fall
+ // back to the target.disable-aslr setting.
disable_aslr = target->GetDisableASLR();
}
@@ -205,11 +200,7 @@ protected:
if (target->GetDisableSTDIO())
m_options.launch_info.GetFlags().Set(eLaunchFlagDisableSTDIO);
- Args environment;
- target->GetEnvironmentAsArgs(environment);
- if (environment.GetArgumentCount() > 0)
- m_options.launch_info.GetEnvironmentEntries().AppendArguments(
- environment);
+ m_options.launch_info.GetEnvironment() = target->GetEnvironment();
if (!target_settings_argv0.empty()) {
m_options.launch_info.GetArguments().AppendArgument(
@@ -237,11 +228,10 @@ protected:
ProcessSP process_sp(target->GetProcessSP());
if (process_sp) {
// 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_sp->SyncIOHandler(0, 2000);
+ // stack to the main command handler and show an (lldb) prompt before
+ // HandlePrivateEvent (from PrivateStateThread) has a chance to call
+ // PushProcessIOHandler().
+ process_sp->SyncIOHandler(0, std::chrono::seconds(2));
llvm::StringRef data = stream.GetString();
if (!data.empty())
@@ -362,7 +352,8 @@ public:
break;
case 'n':
- attach_info.GetExecutableFile().SetFile(option_arg, false);
+ attach_info.GetExecutableFile().SetFile(option_arg, false,
+ FileSpec::Style::native);
break;
case 'w':
@@ -390,11 +381,8 @@ public:
}
bool HandleOptionArgumentCompletion(
- Args &input, int cursor_index, int char_pos,
- OptionElementVector &opt_element_vector, int opt_element_index,
- int match_start_point, int max_return_elements,
- CommandInterpreter &interpreter, bool &word_complete,
- StringList &matches) override {
+ CompletionRequest &request, OptionElementVector &opt_element_vector,
+ int opt_element_index, CommandInterpreter &interpreter) override {
int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
@@ -404,11 +392,10 @@ public:
// Are we in the name?
// Look to see if there is a -P argument provided, and if so use that
- // plugin, otherwise
- // use the default plugin.
+ // plugin, otherwise use the default plugin.
const char *partial_name = nullptr;
- partial_name = input.GetArgumentAtIndex(opt_arg_pos);
+ partial_name = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos);
PlatformSP platform_sp(interpreter.GetPlatform(true));
if (platform_sp) {
@@ -416,14 +403,14 @@ public:
ProcessInstanceInfoMatch match_info;
if (partial_name) {
match_info.GetProcessInfo().GetExecutableFile().SetFile(
- partial_name, false);
+ partial_name, false, FileSpec::Style::native);
match_info.SetNameMatchType(NameMatch::StartsWith);
}
platform_sp->FindProcesses(match_info, process_infos);
const size_t num_matches = process_infos.GetSize();
if (num_matches > 0) {
for (size_t i = 0; i < num_matches; ++i) {
- matches.AppendString(
+ request.GetMatches().AppendString(
process_infos.GetProcessNameAtIndex(i),
process_infos.GetProcessNameLengthAtIndex(i));
}
@@ -456,10 +443,9 @@ protected:
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
// N.B. The attach should be synchronous. It doesn't help much to get the
- // prompt back between initiating the attach
- // and the target actually stopping. So even if the interpreter is set to
- // be asynchronous, we wait for the stop
- // ourselves here.
+ // prompt back between initiating the attach and the target actually
+ // stopping. So even if the interpreter is set to be asynchronous, we wait
+ // for the stop ourselves here.
StateType state = eStateInvalid;
Process *process = m_exe_ctx.GetProcessPtr();
@@ -485,9 +471,8 @@ protected:
}
// Record the old executable module, we want to issue a warning if the
- // process of attaching changed the
- // current executable (like somebody said "file foo" then attached to a PID
- // whose executable was bar.)
+ // process of attaching changed the current executable (like somebody said
+ // "file foo" then attached to a PID whose executable was bar.)
ModuleSP old_exec_module_sp = target->GetExecutableModule();
ArchSpec old_arch_spec = target->GetArchitecture();
@@ -556,8 +541,8 @@ protected:
target->GetArchitecture().GetTriple().getTriple().c_str());
}
- // This supports the use-case scenario of immediately continuing the process
- // once attached.
+ // This supports the use-case scenario of immediately continuing the
+ // process once attached.
if (m_options.attach_info.GetContinueOnceAttached())
m_interpreter.HandleCommand("process continue", eLazyBoolNo, result);
@@ -695,11 +680,10 @@ protected:
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(iohandler_id, 2000);
+ // stack to the main command handler and show an (lldb) prompt before
+ // HandlePrivateEvent (from PrivateStateThread) has a chance to call
+ // PushProcessIOHandler().
+ process->SyncIOHandler(iohandler_id, std::chrono::seconds(2));
result.AppendMessageWithFormat("Process %" PRIu64 " resuming\n",
process->GetID());
@@ -760,7 +744,7 @@ public:
case 's':
bool tmp_result;
bool success;
- tmp_result = Args::StringToBoolean(option_arg, false, &success);
+ tmp_result = OptionArgParser::ToBoolean(option_arg, false, &success);
if (!success)
error.SetErrorStringWithFormat("invalid boolean option: \"%s\"",
option_arg.str().c_str());
@@ -991,7 +975,7 @@ public:
case 'i':
do_install = true;
if (!option_arg.empty())
- install_path.SetFile(option_arg, false);
+ install_path.SetFile(option_arg, false, FileSpec::Style::native);
break;
default:
error.SetErrorStringWithFormat("invalid short option character '%c'",
@@ -1444,7 +1428,7 @@ public:
bool VerifyCommandOptionValue(const std::string &option, int &real_value) {
bool okay = true;
bool success = false;
- bool tmp_value = Args::StringToBoolean(option, false, &success);
+ bool tmp_value = OptionArgParser::ToBoolean(option, false, &success);
if (success && tmp_value)
real_value = 1;
@@ -1563,8 +1547,7 @@ protected:
int32_t signo = signals_sp->GetSignalNumberFromName(arg.c_str());
if (signo != LLDB_INVALID_SIGNAL_NUMBER) {
// Casting the actions as bools here should be okay, because
- // VerifyCommandOptionValue guarantees
- // the value is either 0 or 1.
+ // VerifyCommandOptionValue guarantees the value is either 0 or 1.
if (stop_action != -1)
signals_sp->SetShouldStop(signo, stop_action);
if (pass_action != -1) {
diff --git a/source/Commands/CommandObjectQuit.cpp b/source/Commands/CommandObjectQuit.cpp
index be55dab61683..37ed12be358f 100644
--- a/source/Commands/CommandObjectQuit.cpp
+++ b/source/Commands/CommandObjectQuit.cpp
@@ -16,6 +16,7 @@
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Target/Process.h"
+#include "lldb/Utility/StreamString.h"
using namespace lldb;
using namespace lldb_private;
@@ -26,14 +27,13 @@ using namespace lldb_private;
CommandObjectQuit::CommandObjectQuit(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "quit", "Quit the LLDB debugger.",
- "quit") {}
+ "quit [exit-code]") {}
CommandObjectQuit::~CommandObjectQuit() {}
-// returns true if there is at least one alive process
-// is_a_detach will be true if all alive processes will be detached when you
-// quit
-// and false if at least one process will be killed instead
+// returns true if there is at least one alive process is_a_detach will be true
+// if all alive processes will be detached when you quit and false if at least
+// one process will be killed instead
bool CommandObjectQuit::ShouldAskForConfirmation(bool &is_a_detach) {
if (m_interpreter.GetPromptOnQuit() == false)
return false;
@@ -78,6 +78,41 @@ bool CommandObjectQuit::DoExecute(Args &command, CommandReturnObject &result) {
return false;
}
}
+
+ if (command.GetArgumentCount() > 1) {
+ result.AppendError("Too many arguments for 'quit'. Only an optional exit "
+ "code is allowed");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (command.GetArgumentCount() > 1) {
+ result.AppendError("Too many arguments for 'quit'. Only an optional exit "
+ "code is allowed");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ // We parse the exit code argument if there is one.
+ if (command.GetArgumentCount() == 1) {
+ llvm::StringRef arg = command.GetArgumentAtIndex(0);
+ int exit_code;
+ if (arg.getAsInteger(/*autodetect radix*/ 0, exit_code)) {
+ lldb_private::StreamString s;
+ std::string arg_str = arg.str();
+ s.Printf("Couldn't parse '%s' as integer for exit code.", arg_str.data());
+ result.AppendError(s.GetString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ if (!m_interpreter.SetQuitExitCode(exit_code)) {
+ result.AppendError("The current driver doesn't allow custom exit codes"
+ " for the quit command.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+
const uint32_t event_type =
CommandInterpreter::eBroadcastBitQuitCommandReceived;
m_interpreter.BroadcastEvent(event_type);
diff --git a/source/Commands/CommandObjectRegister.cpp b/source/Commands/CommandObjectRegister.cpp
index d535742016ac..4dadc5d68d20 100644
--- a/source/Commands/CommandObjectRegister.cpp
+++ b/source/Commands/CommandObjectRegister.cpp
@@ -9,10 +9,10 @@
#include "CommandObjectRegister.h"
#include "lldb/Core/Debugger.h"
+#include "lldb/Core/DumpRegisterValue.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Host/OptionParser.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionGroupFormat.h"
@@ -25,6 +25,7 @@
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/DataExtractor.h"
#include "llvm/Support/Errno.h"
@@ -92,8 +93,8 @@ public:
bool prefix_with_altname = (bool)m_command_options.alternate_name;
bool prefix_with_name = !prefix_with_altname;
- reg_value.Dump(&strm, reg_info, prefix_with_name, prefix_with_altname,
- m_format_options.GetFormat(), 8);
+ DumpRegisterValue(reg_value, &strm, reg_info, prefix_with_name,
+ prefix_with_altname, m_format_options.GetFormat(), 8);
if ((reg_info->encoding == eEncodingUint) ||
(reg_info->encoding == eEncodingSint)) {
Process *process = exe_ctx.GetProcessPtr();
@@ -192,8 +193,8 @@ protected:
num_register_sets = reg_ctx->GetRegisterSetCount();
for (set_idx = 0; set_idx < num_register_sets; ++set_idx) {
- // When dump_all_sets option is set, dump primitive as well as derived
- // registers.
+ // When dump_all_sets option is set, dump primitive as well as
+ // derived registers.
DumpRegisterSet(m_exe_ctx, strm, reg_ctx, set_idx,
!m_command_options.dump_all_sets.GetCurrentValue());
}
@@ -209,8 +210,8 @@ protected:
result.SetStatus(eReturnStatusFailed);
} else {
for (auto &entry : command) {
- // in most LLDB commands we accept $rbx as the name for register RBX -
- // and here we would reject it and non-existant. we should be more
+ // in most LLDB commands we accept $rbx as the name for register RBX
+ // - and here we would reject it and non-existant. we should be more
// consistent towards the user and allow them to say reg read $rbx -
// internally, however, we should be strict and not allow ourselves
// to call our registers $rbx in our own API
@@ -350,11 +351,11 @@ protected:
auto reg_name = command[0].ref;
auto value_str = command[1].ref;
- // in most LLDB commands we accept $rbx as the name for register RBX - and
- // here we would reject it and non-existant. we should be more consistent
- // towards the user and allow them to say reg write $rbx - internally,
- // however, we should be strict and not allow ourselves to call our
- // registers $rbx in our own API
+ // in most LLDB commands we accept $rbx as the name for register RBX -
+ // and here we would reject it and non-existant. we should be more
+ // consistent towards the user and allow them to say reg write $rbx -
+ // internally, however, we should be strict and not allow ourselves to
+ // call our registers $rbx in our own API
reg_name.consume_front("$");
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
@@ -365,8 +366,8 @@ protected:
Status error(reg_value.SetValueFromString(reg_info, value_str));
if (error.Success()) {
if (reg_ctx->WriteRegister(reg_info, reg_value)) {
- // Toss all frames and anything else in the thread
- // after a register has been written.
+ // Toss all frames and anything else in the thread after a register
+ // has been written.
m_exe_ctx.GetThreadRef().Flush();
result.SetStatus(eReturnStatusSuccessFinishNoResult);
return true;
diff --git a/source/Commands/CommandObjectSettings.cpp b/source/Commands/CommandObjectSettings.cpp
index d42466cd13b1..f259f2fe200d 100644
--- a/source/Commands/CommandObjectSettings.cpp
+++ b/source/Commands/CommandObjectSettings.cpp
@@ -133,32 +133,27 @@ insert-before or insert-after.");
bool m_global;
};
- int HandleArgumentCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point, int max_return_elements,
- bool &word_complete,
- StringList &matches) override {
- std::string completion_str(input.GetArgumentAtIndex(cursor_index),
- cursor_char_position);
+ int HandleArgumentCompletion(
+ CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
- const size_t argc = input.GetArgumentCount();
+ const size_t argc = request.GetParsedLine().GetArgumentCount();
const char *arg = nullptr;
int setting_var_idx;
- for (setting_var_idx = 1; setting_var_idx < static_cast<int>(argc);
+ for (setting_var_idx = 0; setting_var_idx < static_cast<int>(argc);
++setting_var_idx) {
- arg = input.GetArgumentAtIndex(setting_var_idx);
+ arg = request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
if (arg && arg[0] != '-')
break; // We found our setting variable name index
}
- if (cursor_index == setting_var_idx) {
+ if (request.GetCursorIndex() == setting_var_idx) {
// Attempting to complete setting variable name
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(), match_start_point, max_return_elements,
- nullptr, word_complete, matches);
+ request, nullptr);
} else {
- arg = input.GetArgumentAtIndex(cursor_index);
+ arg =
+ request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex());
if (arg) {
if (arg[0] == '-') {
@@ -166,24 +161,23 @@ insert-before or insert-after.");
} else {
// Complete setting value
const char *setting_var_name =
- input.GetArgumentAtIndex(setting_var_idx);
+ request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
Status error;
lldb::OptionValueSP value_sp(
m_interpreter.GetDebugger().GetPropertyValue(
&m_exe_ctx, setting_var_name, false, error));
if (value_sp) {
- value_sp->AutoComplete(m_interpreter, completion_str.c_str(),
- match_start_point, max_return_elements,
- word_complete, matches);
+ value_sp->AutoComplete(m_interpreter, request);
}
}
}
}
- return matches.GetSize();
+ return request.GetMatches().GetSize();
}
protected:
- bool DoExecute(const char *command, CommandReturnObject &result) override {
+ bool DoExecute(llvm::StringRef command,
+ CommandReturnObject &result) override {
Args cmd_args(command);
// Process possible options.
@@ -220,10 +214,8 @@ protected:
if (error.Success()) {
// FIXME this is the same issue as the one in commands script import
// we could be setting target.load-script-from-symbol-file which would
- // cause
- // Python scripts to be loaded, which could run LLDB commands
- // (e.g. settings set target.process.python-os-plugin-path) and cause a
- // crash
+ // cause Python scripts to be loaded, which could run LLDB commands (e.g.
+ // settings set target.process.python-os-plugin-path) and cause a crash
// if we did not clear the command's exe_ctx first
ExecutionContext exe_ctx(m_exe_ctx);
m_exe_ctx.Clear();
@@ -274,20 +266,13 @@ public:
~CommandObjectSettingsShow() override = default;
- int HandleArgumentCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point, int max_return_elements,
- bool &word_complete,
- StringList &matches) override {
- std::string completion_str(input.GetArgumentAtIndex(cursor_index),
- cursor_char_position);
-
+ int HandleArgumentCompletion(
+ CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(), match_start_point, max_return_elements, nullptr,
- word_complete, matches);
- return matches.GetSize();
+ request, nullptr);
+ return request.GetMatches().GetSize();
}
protected:
@@ -347,20 +332,13 @@ public:
~CommandObjectSettingsList() override = default;
- int HandleArgumentCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point, int max_return_elements,
- bool &word_complete,
- StringList &matches) override {
- std::string completion_str(input.GetArgumentAtIndex(cursor_index),
- cursor_char_position);
-
+ int HandleArgumentCompletion(
+ CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(), match_start_point, max_return_elements, nullptr,
- word_complete, matches);
- return matches.GetSize();
+ request, nullptr);
+ return request.GetMatches().GetSize();
}
protected:
@@ -442,26 +420,19 @@ public:
~CommandObjectSettingsRemove() override = default;
- int HandleArgumentCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point, int max_return_elements,
- bool &word_complete,
- StringList &matches) override {
- std::string completion_str(input.GetArgumentAtIndex(cursor_index),
- cursor_char_position);
-
- // Attempting to complete variable name
- if (cursor_index < 2)
+ int HandleArgumentCompletion(
+ CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (request.GetCursorIndex() < 2)
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(), match_start_point, max_return_elements,
- nullptr, word_complete, matches);
- return matches.GetSize();
+ request, nullptr);
+ return request.GetMatches().GetSize();
}
protected:
- bool DoExecute(const char *command, CommandReturnObject &result) override {
+ bool DoExecute(llvm::StringRef command,
+ CommandReturnObject &result) override {
result.SetStatus(eReturnStatusSuccessFinishNoResult);
Args cmd_args(command);
@@ -564,27 +535,21 @@ public:
// !WantsRawCommandString.
bool WantsCompletion() override { return true; }
- int HandleArgumentCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point, int max_return_elements,
- bool &word_complete,
- StringList &matches) override {
- std::string completion_str(input.GetArgumentAtIndex(cursor_index),
- cursor_char_position);
-
+ int HandleArgumentCompletion(
+ CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
// Attempting to complete variable name
- if (cursor_index < 2)
+ if (request.GetCursorIndex() < 2)
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(), match_start_point, max_return_elements,
- nullptr, word_complete, matches);
+ request, nullptr);
- return matches.GetSize();
+ return request.GetMatches().GetSize();
}
protected:
- bool DoExecute(const char *command, CommandReturnObject &result) override {
+ bool DoExecute(llvm::StringRef command,
+ CommandReturnObject &result) override {
result.SetStatus(eReturnStatusSuccessFinishNoResult);
Args cmd_args(command);
@@ -670,27 +635,21 @@ public:
// !WantsRawCommandString.
bool WantsCompletion() override { return true; }
- int HandleArgumentCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point, int max_return_elements,
- bool &word_complete,
- StringList &matches) override {
- std::string completion_str(input.GetArgumentAtIndex(cursor_index),
- cursor_char_position);
-
+ int HandleArgumentCompletion(
+ CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
// Attempting to complete variable name
- if (cursor_index < 2)
+ if (request.GetCursorIndex() < 2)
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(), match_start_point, max_return_elements,
- nullptr, word_complete, matches);
+ request, nullptr);
- return matches.GetSize();
+ return request.GetMatches().GetSize();
}
protected:
- bool DoExecute(const char *command, CommandReturnObject &result) override {
+ bool DoExecute(llvm::StringRef command,
+ CommandReturnObject &result) override {
result.SetStatus(eReturnStatusSuccessFinishNoResult);
Args cmd_args(command);
@@ -781,27 +740,21 @@ public:
// !WantsRawCommandString.
bool WantsCompletion() override { return true; }
- int HandleArgumentCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point, int max_return_elements,
- bool &word_complete,
- StringList &matches) override {
- std::string completion_str(input.GetArgumentAtIndex(cursor_index),
- cursor_char_position);
-
+ int HandleArgumentCompletion(
+ CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
// Attempting to complete variable name
- if (cursor_index < 2)
+ if (request.GetCursorIndex() < 2)
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(), match_start_point, max_return_elements,
- nullptr, word_complete, matches);
+ request, nullptr);
- return matches.GetSize();
+ return request.GetMatches().GetSize();
}
protected:
- bool DoExecute(const char *command, CommandReturnObject &result) override {
+ bool DoExecute(llvm::StringRef command,
+ CommandReturnObject &result) override {
result.SetStatus(eReturnStatusSuccessFinishNoResult);
Args cmd_args(command);
@@ -881,27 +834,21 @@ public:
// !WantsRawCommandString.
bool WantsCompletion() override { return true; }
- int HandleArgumentCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point, int max_return_elements,
- bool &word_complete,
- StringList &matches) override {
- std::string completion_str(input.GetArgumentAtIndex(cursor_index),
- cursor_char_position);
-
+ int HandleArgumentCompletion(
+ CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
// Attempting to complete variable name
- if (cursor_index < 2)
+ if (request.GetCursorIndex() < 2)
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(), match_start_point, max_return_elements,
- nullptr, word_complete, matches);
+ request, nullptr);
- return matches.GetSize();
+ return request.GetMatches().GetSize();
}
protected:
- bool DoExecute(const char *command, CommandReturnObject &result) override {
+ bool DoExecute(llvm::StringRef command,
+ CommandReturnObject &result) override {
result.SetStatus(eReturnStatusSuccessFinishNoResult);
Args cmd_args(command);
const size_t argc = cmd_args.GetArgumentCount();
@@ -920,8 +867,8 @@ protected:
return false;
}
- // Do not perform cmd_args.Shift() since StringRef is manipulating the
- // raw character string later on.
+ // Do not perform cmd_args.Shift() since StringRef is manipulating the raw
+ // character string later on.
// Split the raw command into var_name and value pair.
llvm::StringRef raw_str(command);
@@ -968,23 +915,16 @@ public:
~CommandObjectSettingsClear() override = default;
- int HandleArgumentCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point, int max_return_elements,
- bool &word_complete,
- StringList &matches) override {
- std::string completion_str(input.GetArgumentAtIndex(cursor_index),
- cursor_char_position);
-
+ int HandleArgumentCompletion(
+ CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
// Attempting to complete variable name
- if (cursor_index < 2)
+ if (request.GetCursorIndex() < 2)
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(), match_start_point, max_return_elements,
- nullptr, word_complete, matches);
+ request, nullptr);
- return matches.GetSize();
+ return request.GetMatches().GetSize();
}
protected:
diff --git a/source/Commands/CommandObjectSource.cpp b/source/Commands/CommandObjectSource.cpp
index 066cc59c5c31..19e2e441c241 100644
--- a/source/Commands/CommandObjectSource.cpp
+++ b/source/Commands/CommandObjectSource.cpp
@@ -22,6 +22,7 @@
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
@@ -91,8 +92,8 @@ class CommandObjectSourceInfo : public CommandObjectParsed {
break;
case 'a': {
- address = Args::StringToAddress(execution_context, option_arg,
- LLDB_INVALID_ADDRESS, &error);
+ address = OptionArgParser::ToAddress(execution_context, option_arg,
+ LLDB_INVALID_ADDRESS, &error);
} break;
case 's':
modules.push_back(std::string(option_arg));
@@ -147,16 +148,13 @@ public:
Options *GetOptions() override { return &m_options; }
protected:
- // Dump the line entries in each symbol context.
- // Return the number of entries found.
- // If module_list is set, only dump lines contained in one of the modules.
- // If file_spec is set, only dump lines in the file.
- // If the start_line option was specified, don't print lines less than
- // start_line.
+ // Dump the line entries in each symbol context. Return the number of entries
+ // found. If module_list is set, only dump lines contained in one of the
+ // modules. If file_spec is set, only dump lines in the file. If the
+ // start_line option was specified, don't print lines less than start_line.
// If the end_line option was specified, don't print lines greater than
- // end_line.
- // If the num_lines option was specified, dont print more than num_lines
- // entries.
+ // end_line. If the num_lines option was specified, dont print more than
+ // num_lines entries.
uint32_t DumpLinesInSymbolContexts(Stream &strm,
const SymbolContextList &sc_list,
const ModuleList &module_list,
@@ -221,14 +219,11 @@ protected:
}
// Dump the requested line entries for the file in the compilation unit.
- // Return the number of entries found.
- // If module_list is set, only dump lines contained in one of the modules.
- // If the start_line option was specified, don't print lines less than
- // start_line.
- // If the end_line option was specified, don't print lines greater than
- // end_line.
- // If the num_lines option was specified, dont print more than num_lines
- // entries.
+ // Return the number of entries found. If module_list is set, only dump lines
+ // contained in one of the modules. If the start_line option was specified,
+ // don't print lines less than start_line. If the end_line option was
+ // specified, don't print lines greater than end_line. If the num_lines
+ // option was specified, dont print more than num_lines entries.
uint32_t DumpFileLinesInCompUnit(Stream &strm, Module *module,
CompileUnit *cu, const FileSpec &file_spec) {
uint32_t start_line = m_options.start_line;
@@ -258,8 +253,8 @@ protected:
while (true) {
LineEntry line_entry;
- // Find the lowest index of a line entry with a line equal to
- // or higher than 'line'.
+ // Find the lowest index of a line entry with a line equal to or
+ // higher than 'line'.
uint32_t start_idx = 0;
start_idx = cu->FindLineEntry(start_idx, line, &cu_file_spec,
/*exact=*/false, &line_entry);
@@ -270,7 +265,8 @@ protected:
if (end_line > 0 && line_entry.line > end_line)
break;
- // Loop through to find any other entries for this line, dumping each.
+ // Loop through to find any other entries for this line, dumping
+ // each.
line = line_entry.line;
do {
num_matches++;
@@ -304,22 +300,18 @@ protected:
return num_matches;
}
- // Dump the requested line entries for the file in the module.
- // Return the number of entries found.
- // If module_list is set, only dump lines contained in one of the modules.
- // If the start_line option was specified, don't print lines less than
- // start_line.
- // If the end_line option was specified, don't print lines greater than
- // end_line.
- // If the num_lines option was specified, dont print more than num_lines
- // entries.
+ // Dump the requested line entries for the file in the module. Return the
+ // number of entries found. If module_list is set, only dump lines contained
+ // in one of the modules. If the start_line option was specified, don't print
+ // lines less than start_line. If the end_line option was specified, don't
+ // print lines greater than end_line. If the num_lines option was specified,
+ // dont print more than num_lines entries.
uint32_t DumpFileLinesInModule(Stream &strm, Module *module,
const FileSpec &file_spec) {
uint32_t num_matches = 0;
if (module) {
// Look through all the compilation units (CUs) in this module for ones
- // that
- // contain lines of code from this source file.
+ // that contain lines of code from this source file.
for (size_t i = 0; i < module->GetNumCompileUnits(); i++) {
// Look for a matching source file in this CU.
CompUnitSP cu_sp(module->GetCompileUnitAtIndex(i));
@@ -333,10 +325,8 @@ protected:
}
// Given an address and a list of modules, append the symbol contexts of all
- // line entries
- // containing the address found in the modules and return the count of
- // matches. If none
- // is found, return an error in 'error_strm'.
+ // line entries containing the address found in the modules and return the
+ // count of matches. If none is found, return an error in 'error_strm'.
size_t GetSymbolContextsForAddress(const ModuleList &module_list,
lldb::addr_t addr,
SymbolContextList &sc_list,
@@ -346,8 +336,8 @@ protected:
assert(module_list.GetSize() > 0);
Target *target = m_exe_ctx.GetTargetPtr();
if (target->GetSectionLoadList().IsEmpty()) {
- // The target isn't loaded yet, we need to lookup the file address in
- // all modules. Note: the module list option does not apply to addresses.
+ // The target isn't loaded yet, we need to lookup the file address in all
+ // modules. Note: the module list option does not apply to addresses.
const size_t num_modules = module_list.GetSize();
for (size_t i = 0; i < num_modules; ++i) {
ModuleSP module_sp(module_list.GetModuleAtIndex(i));
@@ -369,8 +359,8 @@ protected:
" not found in any modules.\n",
addr);
} else {
- // The target has some things loaded, resolve this address to a
- // compile unit + file + line and display
+ // The target has some things loaded, resolve this address to a compile
+ // unit + file + line and display
if (target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) {
ModuleSP module_sp(so_addr.GetModule());
// Check to make sure this module is in our list.
@@ -408,8 +398,8 @@ protected:
return num_matches;
}
- // Dump the line entries found in functions matching the name specified in the
- // option.
+ // Dump the line entries found in functions matching the name specified in
+ // the option.
bool DumpLinesInFunctions(CommandReturnObject &result) {
SymbolContextList sc_list_funcs;
ConstString name(m_options.symbol_name.c_str());
@@ -709,8 +699,8 @@ class CommandObjectSourceList : public CommandObjectParsed {
break;
case 'a': {
- address = Args::StringToAddress(execution_context, option_arg,
- LLDB_INVALID_ADDRESS, &error);
+ address = OptionArgParser::ToAddress(execution_context, option_arg,
+ LLDB_INVALID_ADDRESS, &error);
} break;
case 's':
modules.push_back(std::string(option_arg));
@@ -773,9 +763,9 @@ public:
const char *GetRepeatCommand(Args &current_command_args,
uint32_t index) override {
- // This is kind of gross, but the command hasn't been parsed yet so we can't
- // look at the option values for this invocation... I have to scan the
- // arguments directly.
+ // This is kind of gross, but the command hasn't been parsed yet so we
+ // can't look at the option values for this invocation... I have to scan
+ // the arguments directly.
auto iter =
llvm::find_if(current_command_args, [](const Args::ArgEntry &e) {
return e.ref == "-r" || e.ref == "--reverse";
@@ -863,11 +853,9 @@ protected:
}
// This is a little hacky, but the first line table entry for a function
- // points to the "{" that
- // starts the function block. It would be nice to actually get the
- // function
- // declaration in there too. So back up a bit, but not further than what
- // you're going to display.
+ // points to the "{" that starts the function block. It would be nice to
+ // actually get the function declaration in there too. So back up a bit,
+ // but not further than what you're going to display.
uint32_t extra_lines;
if (m_options.num_lines >= 10)
extra_lines = 5;
@@ -880,8 +868,7 @@ protected:
line_no = start_line - extra_lines;
// For fun, if the function is shorter than the number of lines we're
- // supposed to display,
- // only display the function...
+ // supposed to display, only display the function...
if (end_line != 0) {
if (m_options.num_lines > end_line - line_no)
m_options.num_lines = end_line - line_no + extra_lines;
@@ -912,14 +899,13 @@ protected:
return 0;
}
- // From Jim: The FindMatchingFunctions / FindMatchingFunctionSymbols functions
- // "take a possibly empty vector of strings which are names of modules, and
- // run the two search functions on the subset of the full module list that
- // matches the strings in the input vector". If we wanted to put these
- // somewhere,
- // there should probably be a module-filter-list that can be passed to the
- // various ModuleList::Find* calls, which would either be a vector of string
- // names or a ModuleSpecList.
+ // From Jim: The FindMatchingFunctions / FindMatchingFunctionSymbols
+ // functions "take a possibly empty vector of strings which are names of
+ // modules, and run the two search functions on the subset of the full module
+ // list that matches the strings in the input vector". If we wanted to put
+ // these somewhere, there should probably be a module-filter-list that can be
+ // passed to the various ModuleList::Find* calls, which would either be a
+ // vector of string names or a ModuleSpecList.
size_t FindMatchingFunctions(Target *target, const ConstString &name,
SymbolContextList &sc_list) {
// Displaying the source for a symbol:
@@ -996,8 +982,7 @@ protected:
size_t num_matches = FindMatchingFunctions(target, name, sc_list);
if (!num_matches) {
// If we didn't find any functions with that name, try searching for
- // symbols
- // that line up exactly with function addresses.
+ // symbols that line up exactly with function addresses.
SymbolContextList sc_list_symbols;
size_t num_symbol_matches =
FindMatchingFunctionSymbols(target, name, sc_list_symbols);
@@ -1064,8 +1049,8 @@ protected:
SymbolContextList sc_list;
if (target->GetSectionLoadList().IsEmpty()) {
- // The target isn't loaded yet, we need to lookup the file address
- // in all modules
+ // The target isn't loaded yet, we need to lookup the file address in
+ // all modules
const ModuleList &module_list = target->GetImages();
const size_t num_modules = module_list.GetSize();
for (size_t i = 0; i < num_modules; ++i) {
@@ -1090,8 +1075,8 @@ protected:
return false;
}
} else {
- // The target has some things loaded, resolve this address to a
- // compile unit + file + line and display
+ // The target has some things loaded, resolve this address to a compile
+ // unit + file + line and display
if (target->GetSectionLoadList().ResolveLoadAddress(m_options.address,
so_addr)) {
ModuleSP module_sp(so_addr.GetModule());
@@ -1168,11 +1153,10 @@ protected:
}
}
} else if (m_options.file_name.empty()) {
- // Last valid source manager context, or the current frame if no
- // valid last context in source manager.
- // One little trick here, if you type the exact same list command twice in
- // a row, it is
- // more likely because you typed it once, then typed it again
+ // Last valid source manager context, or the current frame if no valid
+ // last context in source manager. One little trick here, if you type the
+ // exact same list command twice in a row, it is more likely because you
+ // typed it once, then typed it again
if (m_options.start_line == 0) {
if (target->GetSourceManager().DisplayMoreWithLineNumbers(
&result.GetOutputStream(), m_options.num_lines,
diff --git a/source/Commands/CommandObjectStats.cpp b/source/Commands/CommandObjectStats.cpp
new file mode 100644
index 000000000000..9225a94b70d3
--- /dev/null
+++ b/source/Commands/CommandObjectStats.cpp
@@ -0,0 +1,107 @@
+//===-- CommandObjectStats.cpp ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CommandObjectStats.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+class CommandObjectStatsEnable : public CommandObjectParsed {
+public:
+ CommandObjectStatsEnable(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "enable",
+ "Enable statistics collection", nullptr,
+ eCommandProcessMustBePaused) {}
+
+ ~CommandObjectStatsEnable() override = default;
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget();
+
+ if (target->GetCollectingStats()) {
+ result.AppendError("statistics already enabled");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ target->SetCollectingStats(true);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+};
+
+class CommandObjectStatsDisable : public CommandObjectParsed {
+public:
+ CommandObjectStatsDisable(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "disable",
+ "Disable statistics collection", nullptr,
+ eCommandProcessMustBePaused) {}
+
+ ~CommandObjectStatsDisable() override = default;
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget();
+
+ if (!target->GetCollectingStats()) {
+ result.AppendError("need to enable statistics before disabling them");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ target->SetCollectingStats(false);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+};
+
+class CommandObjectStatsDump : public CommandObjectParsed {
+public:
+ CommandObjectStatsDump(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "dump", "Dump statistics results",
+ nullptr, eCommandProcessMustBePaused) {}
+
+ ~CommandObjectStatsDump() override = default;
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget();
+
+ uint32_t i = 0;
+ for (auto &stat : target->GetStatistics()) {
+ result.AppendMessageWithFormat(
+ "%s : %u\n",
+ lldb_private::GetStatDescription(static_cast<lldb_private::StatisticKind>(i))
+ .c_str(),
+ stat);
+ i += 1;
+ }
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+};
+
+CommandObjectStats::CommandObjectStats(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "statistics",
+ "Print statistics about a debugging session",
+ "statistics <subcommand> [<subcommand-options>]") {
+ LoadSubCommand("enable",
+ CommandObjectSP(new CommandObjectStatsEnable(interpreter)));
+ LoadSubCommand("disable",
+ CommandObjectSP(new CommandObjectStatsDisable(interpreter)));
+ LoadSubCommand("dump",
+ CommandObjectSP(new CommandObjectStatsDump(interpreter)));
+}
+
+CommandObjectStats::~CommandObjectStats() = default;
diff --git a/source/Commands/CommandObjectStats.h b/source/Commands/CommandObjectStats.h
new file mode 100644
index 000000000000..3c5c2c04db1f
--- /dev/null
+++ b/source/Commands/CommandObjectStats.h
@@ -0,0 +1,25 @@
+//===-- CommandObjectStats.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_CommandObjectStats_h_
+#define liblldb_CommandObjectStats_h_
+
+#include "lldb/Interpreter/CommandObject.h"
+#include "lldb/Interpreter/CommandObjectMultiword.h"
+
+namespace lldb_private {
+class CommandObjectStats : public CommandObjectMultiword {
+public:
+ CommandObjectStats(CommandInterpreter &interpreter);
+
+ ~CommandObjectStats() override;
+};
+} // namespace lldb_private
+
+#endif // liblldb_CommandObjectLanguage_h_
diff --git a/source/Commands/CommandObjectSyntax.cpp b/source/Commands/CommandObjectSyntax.cpp
deleted file mode 100644
index 2b83b1b8786b..000000000000
--- a/source/Commands/CommandObjectSyntax.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-//===-- CommandObjectSyntax.cpp ---------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "CommandObjectSyntax.h"
-#include "CommandObjectHelp.h"
-#include "lldb/Interpreter/Args.h"
-#include "lldb/Interpreter/CommandInterpreter.h"
-#include "lldb/Interpreter/CommandObjectMultiword.h"
-#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Interpreter/Options.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-//-------------------------------------------------------------------------
-// CommandObjectSyntax
-//-------------------------------------------------------------------------
-
-CommandObjectSyntax::CommandObjectSyntax(CommandInterpreter &interpreter)
- : CommandObjectParsed(
- interpreter, "syntax",
- "Shows the correct syntax for a given debugger command.",
- "syntax <command>") {
- CommandArgumentEntry arg;
- CommandArgumentData command_arg;
-
- // Define the first (and only) variant of this arg.
- command_arg.arg_type = eArgTypeCommandName;
- command_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument
- // entry.
- arg.push_back(command_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back(arg);
-}
-
-CommandObjectSyntax::~CommandObjectSyntax() = default;
-
-bool CommandObjectSyntax::DoExecute(Args &command,
- CommandReturnObject &result) {
- CommandObject::CommandMap::iterator pos;
- CommandObject *cmd_obj;
- const size_t argc = command.GetArgumentCount();
-
- if (argc == 0) {
- result.AppendError("Must call 'syntax' with a valid command.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- cmd_obj = m_interpreter.GetCommandObject(command[0].ref);
- bool all_okay = llvm::all_of(
- command.entries().drop_front(), [&cmd_obj](const Args::ArgEntry &e) {
- if (!cmd_obj || !cmd_obj->IsMultiwordObject())
- return false;
-
- if (!(cmd_obj = cmd_obj->GetSubcommandObject(e.ref)))
- return false;
-
- return true;
- });
-
- if (!all_okay) {
- std::string cmd_string;
- command.GetCommandString(cmd_string);
-
- StreamString error_msg_stream;
- const bool generate_apropos = true;
- const bool generate_type_lookup = false;
- CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage(
- &error_msg_stream, cmd_string, "", "", generate_apropos,
- generate_type_lookup);
- result.AppendErrorWithFormat("%s", error_msg_stream.GetData());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- Stream &output_strm = result.GetOutputStream();
- if (cmd_obj->GetOptions() != nullptr) {
- output_strm.Printf("\nSyntax: %s\n", cmd_obj->GetSyntax().str().c_str());
- output_strm.Printf(
- "(Try 'help %s' for more information on command options syntax.)\n",
- cmd_obj->GetCommandName().str().c_str());
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- } else {
- output_strm.Printf("\nSyntax: %s\n", cmd_obj->GetSyntax().str().c_str());
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- }
-
- return result.Succeeded();
-}
diff --git a/source/Commands/CommandObjectSyntax.h b/source/Commands/CommandObjectSyntax.h
deleted file mode 100644
index b65e9b1b750b..000000000000
--- a/source/Commands/CommandObjectSyntax.h
+++ /dev/null
@@ -1,37 +0,0 @@
-//===-- CommandObjectSyntax.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_CommandObjectSyntax_h_
-#define liblldb_CommandObjectSyntax_h_
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Interpreter/CommandObject.h"
-
-namespace lldb_private {
-
-//-------------------------------------------------------------------------
-// CommandObjectSyntax
-//-------------------------------------------------------------------------
-
-class CommandObjectSyntax : public CommandObjectParsed {
-public:
- CommandObjectSyntax(CommandInterpreter &interpreter);
-
- ~CommandObjectSyntax() override;
-
-protected:
- bool DoExecute(Args &command, CommandReturnObject &result) override;
-};
-
-} // namespace lldb_private
-
-#endif // liblldb_CommandObjectSyntax_h_
diff --git a/source/Commands/CommandObjectTarget.cpp b/source/Commands/CommandObjectTarget.cpp
index c83061d8de74..a9062c14b367 100644
--- a/source/Commands/CommandObjectTarget.cpp
+++ b/source/Commands/CommandObjectTarget.cpp
@@ -21,9 +21,9 @@
#include "lldb/Host/OptionParser.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Host/Symbols.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionGroupArchitecture.h"
#include "lldb/Interpreter/OptionGroupBoolean.h"
#include "lldb/Interpreter/OptionGroupFile.h"
@@ -45,10 +45,12 @@
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadSpec.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/Timer.h"
#include "llvm/Support/FileSystem.h"
@@ -193,20 +195,13 @@ public:
Options *GetOptions() override { return &m_option_group; }
- int HandleArgumentCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point, int max_return_elements,
- bool &word_complete,
- StringList &matches) override {
- std::string completion_str(input.GetArgumentAtIndex(cursor_index));
- completion_str.erase(cursor_char_position);
-
+ int HandleArgumentCompletion(
+ CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
- completion_str.c_str(), match_start_point, max_return_elements, nullptr,
- word_complete, matches);
- return matches.GetSize();
+ request, nullptr);
+ return request.GetMatches().GetSize();
}
protected:
@@ -256,7 +251,7 @@ protected:
FileSpec file_spec;
if (file_path)
- file_spec.SetFile(file_path, true);
+ file_spec.SetFile(file_path, true, FileSpec::Style::native);
bool must_set_platform_path = false;
@@ -272,10 +267,8 @@ protected:
if (target_sp) {
// Only get the platform after we create the target because we might
- // have
- // switched platforms depending on what the arguments were to
- // CreateTarget()
- // we can't rely on the selected platform.
+ // have switched platforms depending on what the arguments were to
+ // CreateTarget() we can't rely on the selected platform.
PlatformSP platform_sp = target_sp->GetPlatform();
@@ -366,8 +359,8 @@ protected:
&core_file));
if (process_sp) {
- // Seems weird that we Launch a core file, but that is
- // what we do!
+ // Seems weird that we Launch a core file, but that is what we
+ // do!
error = process_sp->LoadCore();
if (error.Fail()) {
@@ -616,8 +609,8 @@ protected:
target_list.DeleteTarget(target_sp);
target_sp->Destroy();
}
- // If "--clean" was specified, prune any orphaned shared modules from
- // the global shared module list
+ // If "--clean" was specified, prune any orphaned shared modules from the
+ // global shared module list
if (m_cleanup_option.GetOptionValue()) {
const bool mandatory = true;
ModuleList::RemoveOrphanSharedModules(mandatory);
@@ -752,7 +745,7 @@ public:
VariableList &variable_list) {
Target *target = static_cast<Target *>(baton);
if (target) {
- return target->GetImages().FindGlobalVariables(ConstString(name), true,
+ return target->GetImages().FindGlobalVariables(ConstString(name),
UINT32_MAX, variable_list);
}
return 0;
@@ -818,8 +811,8 @@ protected:
return false;
}
use_var_name = true;
- matches = target->GetImages().FindGlobalVariables(
- regex, true, UINT32_MAX, variable_list);
+ matches = target->GetImages().FindGlobalVariables(regex, UINT32_MAX,
+ variable_list);
} else {
Status error(Variable::GetValuesForVariableExpressionPath(
arg, m_exe_ctx.GetBestExecutionContextScope(),
@@ -947,8 +940,8 @@ protected:
llvm::StringRef(
".")); // Any global with at least one character
VariableList variable_list;
- sc.module_sp->FindGlobalVariables(all_globals_regex, append,
- UINT32_MAX, variable_list);
+ sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX,
+ variable_list);
DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
}
}
@@ -995,10 +988,9 @@ public:
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
+ // 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...
@@ -1109,10 +1101,9 @@ public:
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
+ // 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...
@@ -1386,7 +1377,12 @@ static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
strm.EOL();
}
ObjectFile *objfile = module->GetObjectFile();
- objfile->Dump(&strm);
+ if (objfile)
+ objfile->Dump(&strm);
+ else {
+ strm.Format("No object file for module: {0:F}\n",
+ module->GetFileSpec());
+ }
}
}
strm.IndentLess();
@@ -1632,8 +1628,8 @@ static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm,
strm.PutCString(":\n");
for (TypeSP type_sp : type_list.Types()) {
if (type_sp) {
- // Resolve the clang type so that any forward references
- // to types that haven't yet been parsed will get parsed.
+ // Resolve the clang type so that any forward references to types
+ // that haven't yet been parsed will get parsed.
type_sp->GetFullCompilerType();
type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
// Print all typedef chains
@@ -1683,8 +1679,8 @@ static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm,
TypeSP type_sp(type_list.GetTypeAtIndex(0));
if (type_sp) {
- // Resolve the clang type so that any forward references
- // to types that haven't yet been parsed will get parsed.
+ // Resolve the clang type so that any forward references to types that
+ // haven't yet been parsed will get parsed.
type_sp->GetFullCompilerType();
type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
// Print all typedef chains
@@ -1762,9 +1758,8 @@ static size_t FindModulesByName(Target *target, const char *module_name,
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
+ // 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
if (num_matches == 0) {
module_spec.GetArchitecture() = target->GetArchitecture();
ModuleList::FindSharedModules(module_spec, module_list);
@@ -1809,21 +1804,13 @@ public:
~CommandObjectTargetModulesModuleAutoComplete() override = default;
- int HandleArgumentCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point, int max_return_elements,
- bool &word_complete,
- StringList &matches) override {
- // Arguments are the standard module completer.
- std::string completion_str(input.GetArgumentAtIndex(cursor_index));
- completion_str.erase(cursor_char_position);
-
+ int HandleArgumentCompletion(
+ CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
- GetCommandInterpreter(), CommandCompletions::eModuleCompletion,
- completion_str.c_str(), match_start_point, max_return_elements, nullptr,
- word_complete, matches);
- return matches.GetSize();
+ GetCommandInterpreter(), CommandCompletions::eModuleCompletion, request,
+ nullptr);
+ return request.GetMatches().GetSize();
}
};
@@ -1858,21 +1845,13 @@ public:
~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
- int HandleArgumentCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point, int max_return_elements,
- bool &word_complete,
- StringList &matches) override {
- // Arguments are the standard source file completer.
- std::string completion_str(input.GetArgumentAtIndex(cursor_index));
- completion_str.erase(cursor_char_position);
-
+ int HandleArgumentCompletion(
+ CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion,
- completion_str.c_str(), match_start_point, max_return_elements, nullptr,
- word_complete, matches);
- return matches.GetSize();
+ request, nullptr);
+ return request.GetMatches().GetSize();
}
};
@@ -1982,7 +1961,7 @@ public:
switch (short_option) {
case 's':
- m_sort_order = (SortOrder)Args::StringToOptionEnum(
+ m_sort_order = (SortOrder)OptionArgParser::ToOptionEnum(
option_arg, GetDefinitions()[option_idx].enum_values,
eSortOrderNone, error);
break;
@@ -2408,20 +2387,13 @@ public:
Options *GetOptions() override { return &m_option_group; }
- int HandleArgumentCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point, int max_return_elements,
- bool &word_complete,
- StringList &matches) override {
- std::string completion_str(input.GetArgumentAtIndex(cursor_index));
- completion_str.erase(cursor_char_position);
-
+ int HandleArgumentCompletion(
+ CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
- completion_str.c_str(), match_start_point, max_return_elements, nullptr,
- word_complete, matches);
- return matches.GetSize();
+ request, nullptr);
+ return request.GetMatches().GetSize();
}
protected:
@@ -2604,8 +2576,7 @@ protected:
ModuleSpec module_spec;
bool search_using_module_spec = false;
- // Allow "load" option to work without --file or --uuid
- // option.
+ // Allow "load" option to work without --file or --uuid option.
if (load) {
if (!m_file_option.GetOptionValue().OptionWasSet() &&
!m_uuid_option_group.GetOptionValue().OptionWasSet()) {
@@ -2746,11 +2717,34 @@ protected:
process->Flush();
}
if (load) {
- Status error = module->LoadInMemory(*target, set_pc);
+ ProcessSP process = target->CalculateProcess();
+ Address file_entry = objfile->GetEntryPointAddress();
+ if (!process) {
+ result.AppendError("No process");
+ return false;
+ }
+ if (set_pc && !file_entry.IsValid()) {
+ result.AppendError("No entry address in object file");
+ return false;
+ }
+ std::vector<ObjectFile::LoadableData> loadables(
+ objfile->GetLoadableData(*target));
+ if (loadables.size() == 0) {
+ result.AppendError("No loadable sections");
+ return false;
+ }
+ Status error = process->WriteObjectFile(std::move(loadables));
if (error.Fail()) {
result.AppendError(error.AsCString());
return false;
}
+ if (set_pc) {
+ ThreadList &thread_list = process->GetThreadList();
+ ThreadSP curr_thread(thread_list.GetSelectedThread());
+ RegisterContextSP reg_context(
+ curr_thread->GetRegisterContext());
+ reg_context->SetPC(file_entry.GetLoadAddress(target));
+ }
}
} else {
module->GetFileSpec().GetPath(path, sizeof(path));
@@ -2861,8 +2855,8 @@ public:
if (short_option == 'g') {
m_use_global_module_list = true;
} else if (short_option == 'a') {
- m_module_addr = Args::StringToAddress(execution_context, option_arg,
- LLDB_INVALID_ADDRESS, &error);
+ m_module_addr = OptionArgParser::ToAddress(
+ execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
} else {
unsigned long width = 0;
option_arg.getAsInteger(0, width);
@@ -2904,9 +2898,8 @@ protected:
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
const bool use_global_module_list = m_options.m_use_global_module_list;
// Define a local module list here to ensure it lives longer than any
- // "locker"
- // object which might lock its contents below (through the "module_list_ptr"
- // variable).
+ // "locker" object which might lock its contents below (through the
+ // "module_list_ptr" variable).
ModuleList module_list;
if (target == nullptr && !use_global_module_list) {
result.AppendError("invalid target, create a debug target using the "
@@ -2954,10 +2947,9 @@ protected:
size_t num_modules = 0;
// This locker will be locked on the mutex in module_list_ptr if it is
- // non-nullptr.
- // Otherwise it will lock the AllocationModuleCollectionMutex when
- // accessing
- // the global module list directly.
+ // non-nullptr. Otherwise it will lock the
+ // AllocationModuleCollectionMutex when accessing the global module list
+ // directly.
std::unique_lock<std::recursive_mutex> guard(
Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
@@ -3227,8 +3219,8 @@ public:
case 'a': {
m_str = option_arg;
m_type = eLookupTypeAddress;
- m_addr = Args::StringToAddress(execution_context, option_arg,
- LLDB_INVALID_ADDRESS, &error);
+ m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
+ LLDB_INVALID_ADDRESS, &error);
if (m_addr == LLDB_INVALID_ADDRESS)
error.SetErrorStringWithFormat("invalid address string '%s'",
option_arg.str().c_str());
@@ -3543,8 +3535,8 @@ public:
switch (short_option) {
case 'a': {
m_type = eLookupTypeAddress;
- m_addr = Args::StringToAddress(execution_context, option_arg,
- LLDB_INVALID_ADDRESS, &error);
+ m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
+ LLDB_INVALID_ADDRESS, &error);
} break;
case 'o':
@@ -3559,7 +3551,7 @@ public:
break;
case 'f':
- m_file.SetFile(option_arg, false);
+ m_file.SetFile(option_arg, false, FileSpec::Style::native);
m_type = eLookupTypeFileLine;
break;
@@ -3805,9 +3797,9 @@ protected:
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.
+ // 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.
if (LookupHere(m_interpreter, result, syntax_error)) {
result.GetOutputStream().EOL();
num_successful_lookups++;
@@ -3989,20 +3981,13 @@ public:
~CommandObjectTargetSymbolsAdd() override = default;
- int HandleArgumentCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point, int max_return_elements,
- bool &word_complete,
- StringList &matches) override {
- std::string completion_str(input.GetArgumentAtIndex(cursor_index));
- completion_str.erase(cursor_char_position);
-
+ int HandleArgumentCompletion(
+ CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
- completion_str.c_str(), match_start_point, max_return_elements, nullptr,
- word_complete, matches);
- return matches.GetSize();
+ request, nullptr);
+ return request.GetMatches().GetSize();
}
Options *GetOptions() override { return &m_option_group; }
@@ -4019,10 +4004,9 @@ protected:
if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
}
- // We now have a module that represents a symbol file
- // that can be used for a module that might exist in the
- // current target, so we need to find that module in the
- // target
+ // We now have a module that represents a symbol file that can be used
+ // for a module that might exist in the current target, so we need to
+ // find that module in the target
ModuleList matching_module_list;
size_t num_matches = 0;
@@ -4048,8 +4032,7 @@ protected:
if (num_matches == 0) {
// No matches yet, iterate through the module specs to find a UUID
- // value that
- // we can match up to an image in our target
+ // value that we can match up to an image in our target
const size_t num_symfile_module_specs =
symfile_module_specs.GetSize();
for (size_t i = 0; i < num_symfile_module_specs && num_matches == 0;
@@ -4069,8 +4052,8 @@ protected:
}
}
- // Just try to match up the file by basename if we have no matches at this
- // point
+ // 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);
@@ -4082,7 +4065,8 @@ protected:
if (!filename_no_extension)
break;
- // Check if there was no extension to strip and the basename is the same
+ // Check if there was no extension to strip and the basename is the
+ // same
if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
break;
@@ -4101,9 +4085,9 @@ 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!
+ // 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 =
@@ -4121,8 +4105,8 @@ protected:
"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
+ // 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);
@@ -4298,7 +4282,8 @@ protected:
for (auto &entry : args.entries()) {
if (!entry.ref.empty()) {
- module_spec.GetSymbolFileSpec().SetFile(entry.ref, true);
+ module_spec.GetSymbolFileSpec().SetFile(entry.ref, true,
+ FileSpec::Style::native);
if (file_option_set) {
module_spec.GetFileSpec() =
m_file_option.GetOptionValue().GetCurrentValue();
diff --git a/source/Commands/CommandObjectThread.cpp b/source/Commands/CommandObjectThread.cpp
index b68aa920b582..3be559963df1 100644
--- a/source/Commands/CommandObjectThread.cpp
+++ b/source/Commands/CommandObjectThread.cpp
@@ -21,6 +21,7 @@
#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
@@ -103,8 +104,8 @@ public:
}
// Use tids instead of ThreadSPs to prevent deadlocking problems which
- // result from JIT-ing
- // code while iterating over the (locked) ThreadSP list.
+ // result from JIT-ing code while iterating over the (locked) ThreadSP
+ // list.
std::vector<lldb::tid_t> tids;
if (all_threads || m_unique_stacks) {
@@ -195,11 +196,10 @@ protected:
//
// If you return false, the iteration will stop, otherwise it will proceed.
// The result is set to m_success_return (defaults to
- // eReturnStatusSuccessFinishResult) before the iteration,
- // so you only need to set the return status in HandleOneThread if you want to
- // indicate an error.
- // If m_add_return is true, a blank line will be inserted between each of the
- // listings (except the last one.)
+ // eReturnStatusSuccessFinishResult) before the iteration, so you only need
+ // to set the return status in HandleOneThread if you want to indicate an
+ // error. If m_add_return is true, a blank line will be inserted between each
+ // of the listings (except the last one.)
virtual bool HandleOneThread(lldb::tid_t, CommandReturnObject &result) = 0;
@@ -290,7 +290,7 @@ public:
case 'e': {
bool success;
m_extended_backtrace =
- Args::StringToBoolean(option_arg, false, &success);
+ OptionArgParser::ToBoolean(option_arg, false, &success);
if (!success)
error.SetErrorStringWithFormat(
"invalid boolean value for option '%c'", short_option);
@@ -447,7 +447,8 @@ public:
switch (short_option) {
case 'a': {
bool success;
- bool avoid_no_debug = Args::StringToBoolean(option_arg, true, &success);
+ bool avoid_no_debug =
+ OptionArgParser::ToBoolean(option_arg, true, &success);
if (!success)
error.SetErrorStringWithFormat(
"invalid boolean value for option '%c'", short_option);
@@ -459,7 +460,8 @@ public:
case 'A': {
bool success;
- bool avoid_no_debug = Args::StringToBoolean(option_arg, true, &success);
+ bool avoid_no_debug =
+ OptionArgParser::ToBoolean(option_arg, true, &success);
if (!success)
error.SetErrorStringWithFormat(
"invalid boolean value for option '%c'", short_option);
@@ -483,7 +485,7 @@ public:
case 'm': {
OptionEnumValueElement *enum_values =
GetDefinitions()[option_idx].enum_values;
- m_run_mode = (lldb::RunMode)Args::StringToOptionEnum(
+ m_run_mode = (lldb::RunMode)OptionArgParser::ToOptionEnum(
option_arg, enum_values, eOnlyDuringStepping, error);
} break;
@@ -644,8 +646,7 @@ protected:
const lldb::RunMode stop_other_threads = m_options.m_run_mode;
// This is a bit unfortunate, but not all the commands in this command
- // object support
- // only while stepping, so I use the bool for them.
+ // object support only while stepping, so I use the bool for them.
bool bool_stop_other_threads;
if (m_options.m_run_mode == eAllThreads)
bool_stop_other_threads = false;
@@ -750,8 +751,8 @@ protected:
}
// If we got a new plan, then set it to be a master plan (User level Plans
- // should be master plans
- // so that they can be interruptible). Then resume the process.
+ // should be master plans so that they can be interruptible). Then resume
+ // the process.
if (new_plan_sp) {
new_plan_sp->SetIsMasterPlan(true);
@@ -782,11 +783,10 @@ protected:
}
// 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(iohandler_id, 2000);
+ // stack to the main command handler and show an (lldb) prompt before
+ // HandlePrivateEvent (from PrivateStateThread) has a chance to call
+ // PushProcessIOHandler().
+ process->SyncIOHandler(iohandler_id, std::chrono::seconds(2));
if (synchronous_execution) {
// If any state changed events had anything to say, add that to the
@@ -867,9 +867,9 @@ public:
(state == eStateSuspended)) {
const size_t argc = command.GetArgumentCount();
if (argc > 0) {
- // These two lines appear at the beginning of both blocks in
- // this if..else, but that is because we need to release the
- // lock before calling process->Resume below.
+ // These two lines appear at the beginning of both blocks in this
+ // if..else, but that is because we need to release the lock before
+ // calling process->Resume below.
std::lock_guard<std::recursive_mutex> guard(
process->GetThreadList().GetMutex());
const uint32_t num_threads = process->GetThreadList().GetSize();
@@ -928,9 +928,9 @@ public:
process->GetID());
}
} else {
- // These two lines appear at the beginning of both blocks in
- // this if..else, but that is because we need to release the
- // lock before calling process->Resume below.
+ // These two lines appear at the beginning of both blocks in this
+ // if..else, but that is because we need to release the lock before
+ // calling process->Resume below.
std::lock_guard<std::recursive_mutex> guard(
process->GetThreadList().GetMutex());
const uint32_t num_threads = process->GetThreadList().GetSize();
@@ -1030,7 +1030,7 @@ public:
switch (short_option) {
case 'a': {
- lldb::addr_t tmp_addr = Args::StringToAddress(
+ lldb::addr_t tmp_addr = OptionArgParser::ToAddress(
execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
if (error.Success())
m_until_addrs.push_back(tmp_addr);
@@ -1052,7 +1052,7 @@ public:
case 'm': {
OptionEnumValueElement *enum_values =
GetDefinitions()[option_idx].enum_values;
- lldb::RunMode run_mode = (lldb::RunMode)Args::StringToOptionEnum(
+ lldb::RunMode run_mode = (lldb::RunMode)OptionArgParser::ToOptionEnum(
option_arg, enum_values, eOnlyDuringStepping, error);
if (error.Success()) {
@@ -1192,8 +1192,8 @@ protected:
ThreadPlanSP new_plan_sp;
if (frame->HasDebugInformation()) {
- // Finally we got here... Translate the given line number to a bunch of
- // addresses:
+ // Finally we got here... Translate the given line number to a bunch
+ // of addresses:
SymbolContext sc(frame->GetSymbolContext(eSymbolContextCompUnit));
LineTable *line_table = nullptr;
if (sc.comp_unit)
@@ -1272,10 +1272,9 @@ protected:
abort_other_plans, &address_list.front(), address_list.size(),
m_options.m_stop_others, m_options.m_frame_idx);
// User level plans should be master plans so they can be interrupted
- // (e.g. by hitting a breakpoint)
- // and other plans executed by the user (stepping around the breakpoint)
- // and then a "continue"
- // will resume the original plan.
+ // (e.g. by hitting a breakpoint) and other plans executed by the user
+ // (stepping around the breakpoint) and then a "continue" will resume
+ // the original plan.
new_plan_sp->SetIsMasterPlan(true);
new_plan_sp->SetOkayToDiscard(false);
} else {
@@ -1541,7 +1540,8 @@ public:
switch (short_option) {
case 'x': {
bool success;
- bool tmp_value = Args::StringToBoolean(option_arg, false, &success);
+ bool tmp_value =
+ OptionArgParser::ToBoolean(option_arg, false, &success);
if (success)
m_from_expression = tmp_value;
else {
@@ -1603,12 +1603,13 @@ public:
Options *GetOptions() override { return &m_options; }
protected:
- bool DoExecute(const char *command, CommandReturnObject &result) override {
+ bool DoExecute(llvm::StringRef command,
+ CommandReturnObject &result) override {
// I am going to handle this by hand, because I don't want you to have to
// say:
// "thread return -- -5".
- if (command[0] == '-' && command[1] == 'x') {
- if (command && command[2] != '\0')
+ if (command.startswith("-x")) {
+ if (command.size() != 2U)
result.AppendWarning("Return values ignored when returning from user "
"called expressions");
@@ -1645,7 +1646,7 @@ protected:
return false;
}
- if (command && command[0] != '\0') {
+ if (!command.empty()) {
Target *target = m_exe_ctx.GetTargetPtr();
EvaluateExpressionOptions options;
@@ -1737,8 +1738,8 @@ public:
return Status("invalid line offset: '%s'.", option_arg.str().c_str());
break;
case 'a':
- m_load_addr = Args::StringToAddress(execution_context, option_arg,
- LLDB_INVALID_ADDRESS, &error);
+ m_load_addr = OptionArgParser::ToAddress(execution_context, option_arg,
+ LLDB_INVALID_ADDRESS, &error);
break;
case 'r':
m_force = true;
diff --git a/source/Commands/CommandObjectType.cpp b/source/Commands/CommandObjectType.cpp
index 2d4271cab362..6bcc334198fc 100644
--- a/source/Commands/CommandObjectType.cpp
+++ b/source/Commands/CommandObjectType.cpp
@@ -24,6 +24,7 @@
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionGroupFormat.h"
#include "lldb/Interpreter/OptionValueBoolean.h"
#include "lldb/Interpreter/OptionValueLanguage.h"
@@ -329,7 +330,7 @@ private:
switch (short_option) {
case 'C':
- m_cascade = Args::StringToBoolean(option_arg, true, &success);
+ m_cascade = OptionArgParser::ToBoolean(option_arg, true, &success);
if (!success)
error.SetErrorStringWithFormat("invalid value for cascade: %s",
option_arg.str().c_str());
@@ -571,7 +572,7 @@ private:
switch (short_option) {
case 'C':
- m_cascade = Args::StringToBoolean(option_value, true, &success);
+ m_cascade = OptionArgParser::ToBoolean(option_value, true, &success);
if (!success)
error.SetErrorStringWithFormat("invalid value for cascade: %s",
option_value.str().c_str());
@@ -1252,7 +1253,7 @@ Status CommandObjectTypeSummaryAdd::CommandOptions::SetOptionValue(
switch (short_option) {
case 'C':
- m_flags.SetCascades(Args::StringToBoolean(option_arg, true, &success));
+ m_flags.SetCascades(OptionArgParser::ToBoolean(option_arg, true, &success));
if (!success)
error.SetErrorStringWithFormat("invalid value for cascade: %s",
option_arg.str().c_str());
@@ -1420,8 +1421,8 @@ bool CommandObjectTypeSummaryAdd::Execute_ScriptSummary(
return result.Succeeded();
}
- // if I am here, script_format must point to something good, so I can add that
- // as a script summary to all interested parties
+ // if I am here, script_format must point to something good, so I can add
+ // that as a script summary to all interested parties
Status error;
@@ -2520,7 +2521,7 @@ private:
switch (short_option) {
case 'C':
- m_cascade = Args::StringToBoolean(option_arg, true, &success);
+ m_cascade = OptionArgParser::ToBoolean(option_arg, true, &success);
if (!success)
error.SetErrorStringWithFormat("invalid value for cascade: %s",
option_arg.str().c_str());
@@ -2756,9 +2757,8 @@ static OptionDefinition g_type_lookup_options[] = {
class CommandObjectTypeLookup : public CommandObjectRaw {
protected:
// this function is allowed to do a more aggressive job at guessing languages
- // than the expression parser
- // is comfortable with - so leave the original call alone and add one that is
- // specific to type lookup
+ // than the expression parser is comfortable with - so leave the original
+ // call alone and add one that is specific to type lookup
lldb::LanguageType GuessLanguage(StackFrame *frame) {
lldb::LanguageType lang_type = lldb::eLanguageTypeUnknown;
@@ -2862,9 +2862,9 @@ public:
return m_cmd_help_long;
}
- bool DoExecute(const char *raw_command_line,
+ bool DoExecute(llvm::StringRef raw_command_line,
CommandReturnObject &result) override {
- if (!raw_command_line || !raw_command_line[0]) {
+ if (raw_command_line.empty()) {
result.SetError(
"type lookup cannot be invoked without a type name as argument");
return false;
@@ -2873,42 +2873,13 @@ public:
auto exe_ctx = GetCommandInterpreter().GetExecutionContext();
m_option_group.NotifyOptionParsingStarting(&exe_ctx);
- const char *name_of_type = nullptr;
+ OptionsWithRaw args(raw_command_line);
+ const char *name_of_type = args.GetRawPart().c_str();
- if (raw_command_line[0] == '-') {
- // We have some options and these options MUST end with --.
- const char *end_options = nullptr;
- const char *s = raw_command_line;
- while (s && s[0]) {
- end_options = ::strstr(s, "--");
- if (end_options) {
- end_options += 2; // Get past the "--"
- if (::isspace(end_options[0])) {
- name_of_type = end_options;
- while (::isspace(*name_of_type))
- ++name_of_type;
- break;
- }
- }
- s = end_options;
- }
-
- if (end_options) {
- Args args(
- llvm::StringRef(raw_command_line, end_options - raw_command_line));
- if (!ParseOptions(args, result))
- return false;
-
- Status error(m_option_group.NotifyOptionParsingFinished(&exe_ctx));
- if (error.Fail()) {
- result.AppendError(error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
- }
- if (nullptr == name_of_type)
- name_of_type = raw_command_line;
+ if (args.HasArgs())
+ if (!ParseOptionsAndNotify(args.GetArgs(), result, m_option_group,
+ exe_ctx))
+ return false;
// TargetSP
// target_sp(GetCommandInterpreter().GetDebugger().GetSelectedTarget());
@@ -2933,9 +2904,8 @@ public:
}
// This is not the most efficient way to do this, but we support very few
- // languages
- // so the cost of the sort is going to be dwarfed by the actual lookup
- // anyway
+ // languages so the cost of the sort is going to be dwarfed by the actual
+ // lookup anyway
if (StackFrame *frame = m_exe_ctx.GetFramePtr()) {
guessed_language = GuessLanguage(frame);
if (guessed_language != eLanguageTypeUnknown) {
@@ -3024,7 +2994,8 @@ public:
~CommandObjectFormatterInfo() override = default;
protected:
- bool DoExecute(const char *command, CommandReturnObject &result) override {
+ bool DoExecute(llvm::StringRef command,
+ CommandReturnObject &result) override {
TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
Thread *thread = GetDefaultThread();
if (!thread) {
@@ -3047,16 +3018,16 @@ protected:
m_discovery_function(*result_valobj_sp);
if (formatter_sp) {
std::string description(formatter_sp->GetDescription());
- result.AppendMessageWithFormat(
- "%s applied to (%s) %s is: %s\n", m_formatter_name.c_str(),
- result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>"),
- command, description.c_str());
+ result.GetOutputStream()
+ << m_formatter_name << " applied to ("
+ << result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>")
+ << ") " << command << " is: " << description << "\n";
result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
} else {
- result.AppendMessageWithFormat(
- "no %s applies to (%s) %s\n", m_formatter_name.c_str(),
- result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>"),
- command);
+ result.GetOutputStream()
+ << "no " << m_formatter_name << " applies to ("
+ << result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>")
+ << ") " << command << "\n";
result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
}
return true;
diff --git a/source/Commands/CommandObjectWatchpoint.cpp b/source/Commands/CommandObjectWatchpoint.cpp
index 9c84c992e715..96ae18b35743 100644
--- a/source/Commands/CommandObjectWatchpoint.cpp
+++ b/source/Commands/CommandObjectWatchpoint.cpp
@@ -74,8 +74,8 @@ static int32_t WithRSAIndex(llvm::StringRef Arg) {
return -1;
}
-// Return true if wp_ids is successfully populated with the watch ids.
-// False otherwise.
+// Return true if wp_ids is successfully populated with the watch ids. False
+// otherwise.
bool CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
Target *target, Args &args, std::vector<uint32_t> &wp_ids) {
// Pre-condition: args.GetArgumentCount() > 0.
@@ -111,8 +111,8 @@ bool CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
if (!second.empty())
StrRefArgs.push_back(second);
}
- // Now process the canonical list and fill in the vector of uint32_t's.
- // If there is any error, return false and the client should ignore wp_ids.
+ // Now process the canonical list and fill in the vector of uint32_t's. If
+ // there is any error, return false and the client should ignore wp_ids.
uint32_t beg, end, id;
size_t size = StrRefArgs.size();
bool in_range = false;
@@ -838,7 +838,7 @@ protected:
VariableList &variable_list) {
Target *target = static_cast<Target *>(baton);
if (target) {
- return target->GetImages().FindGlobalVariables(ConstString(name), true,
+ return target->GetImages().FindGlobalVariables(ConstString(name),
UINT32_MAX, variable_list);
}
return 0;
@@ -848,8 +848,8 @@ protected:
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
StackFrame *frame = m_exe_ctx.GetFramePtr();
- // If no argument is present, issue an error message. There's no way to set
- // a watchpoint.
+ // If no argument is present, issue an error message. There's no way to
+ // set a watchpoint.
if (command.GetArgumentCount() <= 0) {
result.GetErrorStream().Printf("error: required argument missing; "
"specify your program variable to watch "
@@ -863,8 +863,8 @@ protected:
m_option_watchpoint.watch_type = OptionGroupWatchpoint::eWatchWrite;
}
- // We passed the sanity check for the command.
- // Proceed to set the watchpoint now.
+ // We passed the sanity check for the command. Proceed to set the
+ // watchpoint now.
lldb::addr_t addr = 0;
size_t size = 0;
@@ -1026,7 +1026,7 @@ Examples:
Options *GetOptions() override { return &m_option_group; }
protected:
- bool DoExecute(const char *raw_command,
+ bool DoExecute(llvm::StringRef raw_command,
CommandReturnObject &result) override {
auto exe_ctx = GetCommandInterpreter().GetExecutionContext();
m_option_group.NotifyOptionParsingStarting(
@@ -1035,46 +1035,18 @@ protected:
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
StackFrame *frame = m_exe_ctx.GetFramePtr();
- Args command(raw_command);
- const char *expr = nullptr;
- if (raw_command[0] == '-') {
- // We have some options and these options MUST end with --.
- const char *end_options = nullptr;
- const char *s = raw_command;
- while (s && s[0]) {
- end_options = ::strstr(s, "--");
- if (end_options) {
- end_options += 2; // Get past the "--"
- if (::isspace(end_options[0])) {
- expr = end_options;
- while (::isspace(*expr))
- ++expr;
- break;
- }
- }
- s = end_options;
- }
+ OptionsWithRaw args(raw_command);
- if (end_options) {
- Args args(llvm::StringRef(raw_command, end_options - raw_command));
- if (!ParseOptions(args, result))
- return false;
-
- Status error(m_option_group.NotifyOptionParsingFinished(&exe_ctx));
- if (error.Fail()) {
- result.AppendError(error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
- }
+ llvm::StringRef expr = args.GetRawPart();
- if (expr == nullptr)
- expr = raw_command;
+ if (args.HasArgs())
+ if (!ParseOptionsAndNotify(args.GetArgs(), result, m_option_group,
+ exe_ctx))
+ return false;
- // If no argument is present, issue an error message. There's no way to set
- // a watchpoint.
- if (command.GetArgumentCount() == 0) {
+ // If no argument is present, issue an error message. There's no way to
+ // set a watchpoint.
+ if (raw_command.trim().empty()) {
result.GetErrorStream().Printf("error: required argument missing; "
"specify an expression to evaulate into "
"the address to watch for\n");
@@ -1087,8 +1059,8 @@ protected:
m_option_watchpoint.watch_type = OptionGroupWatchpoint::eWatchWrite;
}
- // We passed the sanity check for the command.
- // Proceed to set the watchpoint now.
+ // We passed the sanity check for the command. Proceed to set the
+ // watchpoint now.
lldb::addr_t addr = 0;
size_t size = 0;
@@ -1107,7 +1079,7 @@ protected:
if (expr_result != eExpressionCompleted) {
result.GetErrorStream().Printf(
"error: expression evaluation of address to watch failed\n");
- result.GetErrorStream().Printf("expression evaluated: %s\n", expr);
+ result.GetErrorStream() << "expression evaluated: \n" << expr << "\n";
result.SetStatus(eReturnStatusFailed);
return false;
}
diff --git a/source/Commands/CommandObjectWatchpointCommand.cpp b/source/Commands/CommandObjectWatchpointCommand.cpp
index ec7e4a1f9cde..74015a433831 100644
--- a/source/Commands/CommandObjectWatchpointCommand.cpp
+++ b/source/Commands/CommandObjectWatchpointCommand.cpp
@@ -22,6 +22,7 @@
#include "lldb/Host/OptionParser.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
@@ -253,11 +254,10 @@ are no syntax errors may indicate that a function was declared but never called.
std::unique_ptr<WatchpointOptions::CommandData> data_ap(
new WatchpointOptions::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 watchpoint
- // command list)
- // while the latter is used for Python to interpret during the actual
- // callback.
+ // It's necessary to set both user_source and script_source to the
+ // oneliner. The former is used to generate callback description (as in
+ // watchpoint 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;
@@ -286,8 +286,8 @@ are no syntax errors may indicate that a function was declared but never called.
CommandReturnObject result;
Debugger &debugger = target->GetDebugger();
// Rig up the results secondary output stream to the debugger's, so the
- // output will come out synchronously
- // if the debugger is set up that way.
+ // output will come out synchronously if the debugger is set up that
+ // way.
StreamSP output_stream(debugger.GetAsyncOutputStream());
StreamSP error_stream(debugger.GetAsyncErrorStream());
@@ -331,7 +331,7 @@ are no syntax errors may indicate that a function was declared but never called.
break;
case 's':
- m_script_language = (lldb::ScriptLanguage)Args::StringToOptionEnum(
+ m_script_language = (lldb::ScriptLanguage)OptionArgParser::ToOptionEnum(
option_arg, GetDefinitions()[option_idx].enum_values,
eScriptLanguageNone, error);
@@ -341,7 +341,8 @@ are no syntax errors may indicate that a function was declared but never called.
case 'e': {
bool success = false;
- m_stop_on_error = Args::StringToBoolean(option_arg, false, &success);
+ m_stop_on_error =
+ OptionArgParser::ToBoolean(option_arg, false, &success);
if (!success)
error.SetErrorStringWithFormat(
"invalid value for stop-on-error: \"%s\"",
@@ -439,20 +440,19 @@ protected:
if (wp_options == nullptr)
continue;
- // If we are using script language, get the script interpreter
- // in order to set or collect command callback. Otherwise, call
- // the methods associated with this object.
+ // 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()->SetWatchpointCommandCallback(
wp_options, m_options.m_one_liner.c_str());
}
- // Special handling for using a Python function by name
- // instead of extending the watchpoint callback data structures, we
- // just automatize
- // what the user would do manually: make their watchpoint command be a
- // function call
+ // Special handling for using a Python function by name instead of
+ // extending the watchpoint callback data structures, we just
+ // automatize what the user would do manually: make their watchpoint
+ // command be a function call
else if (!m_options.m_function_name.empty()) {
std::string oneliner(m_options.m_function_name);
oneliner += "(frame, wp, internal_dict)";
@@ -669,7 +669,7 @@ CommandObjectWatchpointCommand::CommandObjectWatchpointCommand(
: CommandObjectMultiword(
interpreter, "command",
"Commands for adding, removing and examining LLDB commands "
- "executed when the watchpoint is hit (watchpoint 'commmands').",
+ "executed when the watchpoint is hit (watchpoint 'commands').",
"command <sub-command> [<sub-command-options>] <watchpoint-id>") {
CommandObjectSP add_command_object(
new CommandObjectWatchpointCommandAdd(interpreter));
diff --git a/source/Core/Address.cpp b/source/Core/Address.cpp
index 54b485ce0354..f183245f7d36 100644
--- a/source/Core/Address.cpp
+++ b/source/Core/Address.cpp
@@ -141,8 +141,8 @@ static bool ReadAddress(ExecutionContextScope *exe_scope,
deref_so_addr))
return true;
} else {
- // If we were not running, yet able to read an integer, we must
- // have a module
+ // If we were not running, yet able to read an integer, we must have a
+ // module
ModuleSP module_sp(address.GetModule());
assert(module_sp);
@@ -151,8 +151,8 @@ static bool ReadAddress(ExecutionContextScope *exe_scope,
}
// We couldn't make "deref_addr" into a section offset value, but we were
- // able to read the address, so we return a section offset address with
- // no section and "deref_addr" as the offset (address).
+ // able to read the address, so we return a section offset address with no
+ // section and "deref_addr" as the offset (address).
deref_so_addr.SetRawAddress(deref_addr);
return true;
}
@@ -278,12 +278,12 @@ addr_t Address::GetFileAddress() const {
// Section isn't resolved, we can't return a valid file address
return LLDB_INVALID_ADDRESS;
}
- // We have a valid file range, so we can return the file based
- // address by adding the file base address to our offset
+ // We have a valid file range, so we can return the file based address by
+ // adding the file base address to our offset
return sect_file_addr + m_offset;
} else if (SectionWasDeletedPrivate()) {
- // Used to have a valid section but it got deleted so the
- // offset doesn't mean anything without the section
+ // Used to have a valid section but it got deleted so the offset doesn't
+ // mean anything without the section
return LLDB_INVALID_ADDRESS;
}
// No section, we just return the offset since it is the value in this case
@@ -297,21 +297,21 @@ addr_t Address::GetLoadAddress(Target *target) const {
addr_t sect_load_addr = section_sp->GetLoadBaseAddress(target);
if (sect_load_addr != LLDB_INVALID_ADDRESS) {
- // We have a valid file range, so we can return the file based
- // address by adding the file base address to our offset
+ // We have a valid file range, so we can return the file based address
+ // by adding the file base address to our offset
return sect_load_addr + m_offset;
}
}
} else if (SectionWasDeletedPrivate()) {
- // Used to have a valid section but it got deleted so the
- // offset doesn't mean anything without the section
+ // Used to have a valid section but it got deleted so the offset doesn't
+ // mean anything without the section
return LLDB_INVALID_ADDRESS;
} else {
// We don't have a section so the offset is the load address
return m_offset;
}
- // The section isn't resolved or an invalid target was passed in
- // so we can't return a valid load address.
+ // The section isn't resolved or an invalid target was passed in so we can't
+ // return a valid load address.
return LLDB_INVALID_ADDRESS;
}
@@ -351,7 +351,7 @@ addr_t Address::GetOpcodeLoadAddress(Target *target,
AddressClass addr_class) const {
addr_t code_addr = GetLoadAddress(target);
if (code_addr != LLDB_INVALID_ADDRESS) {
- if (addr_class == eAddressClassInvalid)
+ if (addr_class == AddressClass::eInvalid)
addr_class = GetAddressClass();
code_addr = target->GetOpcodeLoadAddress(code_addr, addr_class);
}
@@ -363,7 +363,7 @@ bool Address::SetOpcodeLoadAddress(lldb::addr_t load_addr, Target *target,
bool allow_section_end) {
if (SetLoadAddress(load_addr, target, allow_section_end)) {
if (target) {
- if (addr_class == eAddressClassInvalid)
+ if (addr_class == AddressClass::eInvalid)
addr_class = GetAddressClass();
m_offset = target->GetOpcodeLoadAddress(m_offset, addr_class);
}
@@ -375,16 +375,15 @@ bool Address::SetOpcodeLoadAddress(lldb::addr_t load_addr, Target *target,
bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
DumpStyle fallback_style, uint32_t addr_size) const {
// If the section was nullptr, only load address is going to work unless we
- // are
- // trying to deref a pointer
+ // are trying to deref a pointer
SectionSP section_sp(GetSection());
if (!section_sp && style != DumpStyleResolvedPointerDescription)
style = DumpStyleLoadAddress;
ExecutionContext exe_ctx(exe_scope);
Target *target = exe_ctx.GetTargetPtr();
- // If addr_byte_size is UINT32_MAX, then determine the correct address
- // byte size for the process or default to the size of addr_t
+ // If addr_byte_size is UINT32_MAX, then determine the correct address byte
+ // size for the process or default to the size of addr_t
if (addr_size == UINT32_MAX) {
if (target)
addr_size = target->GetArchitecture().GetAddressByteSize();
@@ -439,7 +438,7 @@ bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
/*
* MIPS:
* Display address in compressed form for MIPS16 or microMIPS
- * if the address belongs to eAddressClassCodeAlternateISA.
+ * if the address belongs to AddressClass::eCodeAlternateISA.
*/
if (target) {
const llvm::Triple::ArchType llvm_arch =
@@ -651,15 +650,15 @@ bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
}
}
if (show_stop_context) {
- // We have a function or a symbol from the same
- // sections as this address.
+ // We have a function or a symbol from the same sections as this
+ // address.
sc.DumpStopContext(s, exe_scope, *this, show_fullpaths,
show_module, show_inlined_frames,
show_function_arguments, show_function_name);
} else {
- // We found a symbol but it was in a different
- // section so it isn't the symbol we should be
- // showing, just show the section name + offset
+ // We found a symbol but it was in a different section so it
+ // isn't the symbol we should be showing, just show the section
+ // name + offset
Dump(s, exe_scope, DumpStyleSectionNameOffset);
}
}
@@ -680,10 +679,10 @@ bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
module_sp->ResolveSymbolContextForAddress(
*this, eSymbolContextEverything | eSymbolContextVariable, sc);
if (sc.symbol) {
- // If we have just a symbol make sure it is in the same section
- // as our address. If it isn't, then we might have just found
- // the last symbol that came before the address that we are
- // looking up that has nothing to do with our address lookup.
+ // If we have just a symbol make sure it is in the same section as
+ // our address. If it isn't, then we might have just found the last
+ // symbol that came before the address that we are looking up that
+ // has nothing to do with our address lookup.
if (sc.symbol->ValueIsAddress() &&
sc.symbol->GetAddressRef().GetSection() != GetSection())
sc.symbol = nullptr;
@@ -771,14 +770,11 @@ bool Address::SectionWasDeletedPrivate() const {
lldb::SectionWP empty_section_wp;
// If either call to "std::weak_ptr::owner_before(...) value returns true,
- // this
- // indicates that m_section_wp once contained (possibly still does) a
- // reference
- // to a valid shared pointer. This helps us know if we had a valid reference
- // to
- // a section which is now invalid because the module it was in was
- // unloaded/deleted,
- // or if the address doesn't have a valid reference to a section.
+ // this indicates that m_section_wp once contained (possibly still does) a
+ // reference to a valid shared pointer. This helps us know if we had a valid
+ // reference to a section which is now invalid because the module it was in
+ // was unloaded/deleted, or if the address doesn't have a valid reference to
+ // a section.
return empty_section_wp.owner_before(m_section_wp) ||
m_section_wp.owner_before(empty_section_wp);
}
@@ -914,8 +910,8 @@ int Address::CompareModulePointerAndOffset(const Address &a, const Address &b) {
return -1;
if (a_module > b_module)
return +1;
- // Modules are the same, just compare the file address since they should
- // be unique
+ // Modules are the same, just compare the file address since they should be
+ // unique
addr_t a_file_addr = a.GetFileAddress();
addr_t b_file_addr = b.GetFileAddress();
if (a_file_addr < b_file_addr)
@@ -926,24 +922,23 @@ int Address::CompareModulePointerAndOffset(const Address &a, const Address &b) {
}
size_t Address::MemorySize() const {
- // Noting special for the memory size of a single Address object,
- // it is just the size of itself.
+ // Noting special for the memory size of a single Address object, it is just
+ // the size of itself.
return sizeof(Address);
}
//----------------------------------------------------------------------
// NOTE: Be careful using this operator. It can correctly compare two
-// addresses from the same Module correctly. It can't compare two
-// addresses from different modules in any meaningful way, but it will
-// compare the module pointers.
+// addresses from the same Module correctly. It can't compare two addresses
+// from different modules in any meaningful way, but it will compare the module
+// pointers.
//
// To sum things up:
-// - works great for addresses within the same module
-// - it works for addresses across multiple modules, but don't expect the
+// - works great for addresses within the same module - it works for addresses
+// across multiple modules, but don't expect the
// address results to make much sense
//
-// This basically lets Address objects be used in ordered collection
-// classes.
+// This basically lets Address objects be used in ordered collection classes.
//----------------------------------------------------------------------
bool lldb_private::operator<(const Address &lhs, const Address &rhs) {
@@ -955,8 +950,8 @@ bool lldb_private::operator<(const Address &lhs, const Address &rhs) {
// Addresses are in the same module, just compare the file addresses
return lhs.GetFileAddress() < rhs.GetFileAddress();
} else {
- // The addresses are from different modules, just use the module
- // pointer value to get consistent ordering
+ // The addresses are from different modules, just use the module pointer
+ // value to get consistent ordering
return lhs_module < rhs_module;
}
}
@@ -970,8 +965,8 @@ bool lldb_private::operator>(const Address &lhs, const Address &rhs) {
// Addresses are in the same module, just compare the file addresses
return lhs.GetFileAddress() > rhs.GetFileAddress();
} else {
- // The addresses are from different modules, just use the module
- // pointer value to get consistent ordering
+ // The addresses are from different modules, just use the module pointer
+ // value to get consistent ordering
return lhs_module > rhs_module;
}
}
@@ -997,7 +992,7 @@ AddressClass Address::GetAddressClass() const {
return obj_file->GetAddressClass(GetFileAddress());
}
}
- return eAddressClassUnknown;
+ return AddressClass::eUnknown;
}
bool Address::SetLoadAddress(lldb::addr_t load_addr, Target *target,
diff --git a/source/Core/AddressResolverName.cpp b/source/Core/AddressResolverName.cpp
index 9935362e0e98..c3dab6d10810 100644
--- a/source/Core/AddressResolverName.cpp
+++ b/source/Core/AddressResolverName.cpp
@@ -62,9 +62,8 @@ AddressResolverName::~AddressResolverName() = default;
// FIXME: Right now we look at the module level, and call the module's
// "FindFunctions".
// Greg says he will add function tables, maybe at the CompileUnit level to
-// accelerate function
-// lookup. At that point, we should switch the depth to CompileUnit, and look
-// in these tables.
+// accelerate function lookup. At that point, we should switch the depth to
+// CompileUnit, and look in these tables.
Searcher::CallbackReturn
AddressResolverName::SearchCallback(SearchFilter &filter,
diff --git a/source/Core/Broadcaster.cpp b/source/Core/Broadcaster.cpp
index 7a4932c4987e..198434b46c29 100644
--- a/source/Core/Broadcaster.cpp
+++ b/source/Core/Broadcaster.cpp
@@ -74,9 +74,8 @@ Broadcaster::BroadcasterImpl::GetListeners() {
void Broadcaster::BroadcasterImpl::Clear() {
std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
- // Make sure the listener forgets about this broadcaster. We do
- // this in the broadcaster in case the broadcaster object initiates
- // the removal.
+ // Make sure the listener forgets about this broadcaster. We do this in the
+ // broadcaster in case the broadcaster object initiates the removal.
for (auto &pair : GetListeners())
pair.first->BroadcasterWillDestruct(&m_broadcaster);
diff --git a/source/Core/CMakeLists.txt b/source/Core/CMakeLists.txt
index cac56e29fc19..927a0dcc2ec1 100644
--- a/source/Core/CMakeLists.txt
+++ b/source/Core/CMakeLists.txt
@@ -18,6 +18,7 @@ add_lldb_library(lldbCore
Debugger.cpp
Disassembler.cpp
DumpDataExtractor.cpp
+ DumpRegisterValue.cpp
DynamicLoader.cpp
EmulateInstruction.cpp
Event.cpp
@@ -69,7 +70,6 @@ add_lldb_library(lldbCore
lldbPluginProcessUtility
lldbPluginCPlusPlusLanguage
lldbPluginObjCLanguage
- lldbPluginObjectFileJIT
${LLDB_CURSES_LIBS}
LINK_COMPONENTS
diff --git a/source/Core/Communication.cpp b/source/Core/Communication.cpp
index 38ab902ab4b7..5ca338639de0 100644
--- a/source/Core/Communication.cpp
+++ b/source/Core/Communication.cpp
@@ -97,15 +97,15 @@ ConnectionStatus Communication::Disconnect(Status *error_ptr) {
lldb::ConnectionSP connection_sp(m_connection_sp);
if (connection_sp) {
ConnectionStatus status = connection_sp->Disconnect(error_ptr);
- // We currently don't protect connection_sp with any mutex for
- // multi-threaded environments. So lets not nuke our connection class
- // without putting some multi-threaded protections in. We also probably
- // don't want to pay for the overhead it might cause if every time we
- // access the connection we have to take a lock.
+ // We currently don't protect connection_sp with any mutex for multi-
+ // threaded environments. So lets not nuke our connection class without
+ // putting some multi-threaded protections in. We also probably don't want
+ // to pay for the overhead it might cause if every time we access the
+ // connection we have to take a lock.
//
- // This unique pointer will cleanup after itself when this object goes away,
- // so there is no need to currently have it destroy itself immediately
- // upon disconnnect.
+ // This unique pointer will cleanup after itself when this object goes
+ // away, so there is no need to currently have it destroy itself
+ // immediately upon disconnect.
// connection_sp.reset();
return status;
}
@@ -240,8 +240,8 @@ bool Communication::JoinReadThread(Status *error_ptr) {
size_t Communication::GetCachedBytes(void *dst, size_t dst_len) {
std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);
if (!m_bytes.empty()) {
- // If DST is nullptr and we have a thread, then return the number
- // of bytes that are available so the caller can call again
+ // If DST is nullptr and we have a thread, then return the number of bytes
+ // that are available so the caller can call again
if (dst == nullptr)
return m_bytes.size();
@@ -337,8 +337,7 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) {
case eConnectionStatusInterrupted: // Synchronization signal from
// SynchronizeWithReadThread()
// The connection returns eConnectionStatusInterrupted only when there is
- // no
- // input pending to be read, so we can signal that.
+ // no input pending to be read, so we can signal that.
comm->BroadcastEvent(eBroadcastBitNoMorePendingInput);
break;
case eConnectionStatusNoConnection: // No connection
diff --git a/source/Core/Debugger.cpp b/source/Core/Debugger.cpp
index a4d78151c75f..972d0bc0a6d7 100644
--- a/source/Core/Debugger.cpp
+++ b/source/Core/Debugger.cpp
@@ -14,6 +14,7 @@
#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/Listener.h" // for Listener
#include "lldb/Core/Mangled.h" // for Mangled
+#include "lldb/Core/ModuleList.h" // for Mangled
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/State.h"
#include "lldb/Core/StreamAsynchronousIO.h"
@@ -47,7 +48,7 @@
#include "lldb/Utility/StreamCallback.h"
#include "lldb/Utility/StreamString.h"
-#if defined(LLVM_ON_WIN32)
+#if defined(_WIN32)
#include "lldb/Host/windows/PosixApi.h" // for PATH_MAX
#endif
@@ -166,13 +167,15 @@ OptionEnumValueElement g_language_enumerators[] = {
"}${addr-file-or-load}{ " \
"<${function.concrete-only-addr-offset-no-padding}>}: "
-// gdb's disassembly format can be emulated with
-// ${current-pc-arrow}${addr-file-or-load}{
-// <${function.name-without-args}${function.concrete-only-addr-offset-no-padding}>}:
+// gdb's disassembly format can be emulated with ${current-pc-arrow}${addr-
+// file-or-load}{ <${function.name-without-args}${function.concrete-only-addr-
+// offset-no-padding}>}:
// lldb's original format for disassembly would look like this format string -
-// {${function.initial-function}{${module.file.basename}`}{${function.name-without-args}}:\n}{${function.changed}\n{${module.file.basename}`}{${function.name-without-args}}:\n}{${current-pc-arrow}
-// }{${addr-file-or-load}}:
+// {${function.initial-function}{${module.file.basename}`}{${function.name-
+// without-
+// args}}:\n}{${function.changed}\n{${module.file.basename}`}{${function.name-
+// without-args}}:\n}{${current-pc-arrow} }{${addr-file-or-load}}:
#define DEFAULT_STOP_SHOW_COLUMN_ANSI_PREFIX "${ansi.underline}"
#define DEFAULT_STOP_SHOW_COLUMN_ANSI_SUFFIX "${ansi.normal}"
@@ -589,9 +592,9 @@ bool Debugger::LoadPlugin(const FileSpec &spec, Status &error) {
return true;
}
} else {
- // The g_load_plugin_callback is registered in SBDebugger::Initialize()
- // and if the public API layer isn't available (code is linking against
- // all of the internal LLDB static libraries), then we can't load plugins
+ // The g_load_plugin_callback is registered in SBDebugger::Initialize() and
+ // if the public API layer isn't available (code is linking against all of
+ // the internal LLDB static libraries), then we can't load plugins
error.SetErrorString("Public API layer is not available");
}
return false;
@@ -602,8 +605,8 @@ LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
const FileSpec &file_spec) {
Status error;
- static ConstString g_dylibext("dylib");
- static ConstString g_solibext("so");
+ static ConstString g_dylibext(".dylib");
+ static ConstString g_solibext(".so");
if (!baton)
return FileSpec::eEnumerateDirectoryResultQuit;
@@ -611,8 +614,8 @@ LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
Debugger *debugger = (Debugger *)baton;
namespace fs = llvm::sys::fs;
- // If we have a regular file, a symbolic link or unknown file type, try
- // and process the file. We must handle unknown as sometimes the directory
+ // If we have a regular file, a symbolic link or unknown file type, try and
+ // process the file. We must handle unknown as sometimes the directory
// enumeration might be enumerating a file system that doesn't have correct
// file type information.
if (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file ||
@@ -632,9 +635,9 @@ LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
} else if (ft == fs::file_type::directory_file ||
ft == fs::file_type::symlink_file ||
ft == fs::file_type::type_unknown) {
- // 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 enumerating a file system that doesn't have correct file type
+ // 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
+ // enumerating a file system that doesn't have correct file type
// information.
return FileSpec::eEnumerateDirectoryResultEnter;
}
@@ -643,19 +646,18 @@ LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
}
void Debugger::InstanceInitialize() {
- FileSpec dir_spec;
const bool find_directories = true;
const bool find_files = true;
const bool find_other = true;
char dir_path[PATH_MAX];
- if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec)) {
+ if (FileSpec dir_spec = HostInfo::GetSystemPluginDir()) {
if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) {
FileSpec::EnumerateDirectory(dir_path, find_directories, find_files,
find_other, LoadPluginCallback, this);
}
}
- if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec)) {
+ if (FileSpec dir_spec = HostInfo::GetUserPluginDir()) {
if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) {
FileSpec::EnumerateDirectory(dir_path, find_directories, find_files,
find_other, LoadPluginCallback, this);
@@ -774,6 +776,9 @@ Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton)
m_collection_sp->AppendProperty(
ConstString("platform"), ConstString("Platform settings."), true,
Platform::GetGlobalPlatformProperties()->GetValueProperties());
+ m_collection_sp->AppendProperty(
+ ConstString("symbols"), ConstString("Symbol lookup and cache settings."),
+ true, ModuleList::GetGlobalModuleListProperties().GetValueProperties());
if (m_command_interpreter_ap) {
m_collection_sp->AppendProperty(
ConstString("interpreter"),
@@ -796,10 +801,9 @@ Debugger::~Debugger() { Clear(); }
void Debugger::Clear() {
//----------------------------------------------------------------------
- // Make sure we call this function only once. With the C++ global
- // destructor chain having a list of debuggers and with code that can be
- // running on other threads, we need to ensure this doesn't happen
- // multiple times.
+ // Make sure we call this function only once. With the C++ global destructor
+ // chain having a list of debuggers and with code that can be running on
+ // other threads, we need to ensure this doesn't happen multiple times.
//
// The following functions call Debugger::Clear():
// Debugger::~Debugger();
@@ -824,8 +828,7 @@ void Debugger::Clear() {
m_broadcaster_manager_sp->Clear();
// Close the input file _before_ we close the input read communications
- // class
- // as it does NOT own the input file, our m_input_file does.
+ // class as it does NOT own the input file, our m_input_file does.
m_terminal_state.Clear();
if (m_input_file_sp)
m_input_file_sp->GetFile().Close();
@@ -861,8 +864,8 @@ void Debugger::SetInputFileHandle(FILE *fh, bool tranfer_ownership) {
if (!in_file.IsValid())
in_file.SetStream(stdin, true);
- // Save away the terminal state if that is relevant, so that we can restore it
- // in RestoreInputState.
+ // Save away the terminal state if that is relevant, so that we can restore
+ // it in RestoreInputState.
SaveInputTerminalState();
}
@@ -876,8 +879,8 @@ void Debugger::SetOutputFileHandle(FILE *fh, bool tranfer_ownership) {
if (!out_file.IsValid())
out_file.SetStream(stdout, false);
- // do not create the ScriptInterpreter just for setting the output file handle
- // as the constructor will know how to do the right thing on its own
+ // do not create the ScriptInterpreter just for setting the output file
+ // handle as the constructor will know how to do the right thing on its own
const bool can_create = false;
ScriptInterpreter *script_interpreter =
GetCommandInterpreter().GetScriptInterpreter(can_create);
@@ -1023,11 +1026,10 @@ void Debugger::RunIOHandler(const IOHandlerSP &reader_sp) {
void Debugger::AdoptTopIOHandlerFilesIfInvalid(StreamFileSP &in,
StreamFileSP &out,
StreamFileSP &err) {
- // Before an IOHandler runs, it must have in/out/err streams.
- // This function is called when one ore more of the streams
- // are nullptr. We use the top input reader's in/out/err streams,
- // or fall back to the debugger file handles, or we fall back
- // onto stdin/stdout/stderr as a last resort.
+ // Before an IOHandler runs, it must have in/out/err streams. This function
+ // is called when one ore more of the streams are nullptr. We use the top
+ // input reader's in/out/err streams, or fall back to the debugger file
+ // handles, or we fall back onto stdin/stdout/stderr as a last resort.
std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
IOHandlerSP top_reader_sp(m_input_reader_stack.Top());
@@ -1083,8 +1085,8 @@ void Debugger::PushIOHandler(const IOHandlerSP &reader_sp) {
m_input_reader_stack.Push(reader_sp);
reader_sp->Activate();
- // Interrupt the top input reader to it will exit its Run() function
- // and let this new input reader take over
+ // 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();
top_reader_sp->Cancel();
@@ -1097,8 +1099,8 @@ bool Debugger::PopIOHandler(const IOHandlerSP &pop_reader_sp) {
std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
- // The reader on the stop of the stack is done, so let the next
- // read on the stack refresh its prompt and if there is one...
+ // The reader on the stop of the stack is done, so let the next read on the
+ // stack refresh its prompt and if there is one...
if (m_input_reader_stack.IsEmpty())
return false;
@@ -1162,75 +1164,6 @@ DebuggerSP Debugger::FindDebuggerWithID(lldb::user_id_t id) {
return debugger_sp;
}
-#if 0
-static void
-TestPromptFormats (StackFrame *frame)
-{
- if (frame == nullptr)
- return;
-
- StreamString s;
- const char *prompt_format =
- "{addr = '${addr}'\n}"
- "{addr-file-or-load = '${addr-file-or-load}'\n}"
- "{current-pc-arrow = '${current-pc-arrow}'\n}"
- "{process.id = '${process.id}'\n}"
- "{process.name = '${process.name}'\n}"
- "{process.file.basename = '${process.file.basename}'\n}"
- "{process.file.fullpath = '${process.file.fullpath}'\n}"
- "{thread.id = '${thread.id}'\n}"
- "{thread.index = '${thread.index}'\n}"
- "{thread.name = '${thread.name}'\n}"
- "{thread.queue = '${thread.queue}'\n}"
- "{thread.stop-reason = '${thread.stop-reason}'\n}"
- "{target.arch = '${target.arch}'\n}"
- "{module.file.basename = '${module.file.basename}'\n}"
- "{module.file.fullpath = '${module.file.fullpath}'\n}"
- "{file.basename = '${file.basename}'\n}"
- "{file.fullpath = '${file.fullpath}'\n}"
- "{frame.index = '${frame.index}'\n}"
- "{frame.pc = '${frame.pc}'\n}"
- "{frame.sp = '${frame.sp}'\n}"
- "{frame.fp = '${frame.fp}'\n}"
- "{frame.flags = '${frame.flags}'\n}"
- "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
- "{frame.reg.rip = '${frame.reg.rip}'\n}"
- "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
- "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
- "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
- "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
- "{frame.reg.carp = '${frame.reg.carp}'\n}"
- "{function.id = '${function.id}'\n}"
- "{function.changed = '${function.changed}'\n}"
- "{function.initial-function = '${function.initial-function}'\n}"
- "{function.name = '${function.name}'\n}"
- "{function.name-without-args = '${function.name-without-args}'\n}"
- "{function.name-with-args = '${function.name-with-args}'\n}"
- "{function.addr-offset = '${function.addr-offset}'\n}"
- "{function.concrete-only-addr-offset-no-padding = '${function.concrete-only-addr-offset-no-padding}'\n}"
- "{function.line-offset = '${function.line-offset}'\n}"
- "{function.pc-offset = '${function.pc-offset}'\n}"
- "{line.file.basename = '${line.file.basename}'\n}"
- "{line.file.fullpath = '${line.file.fullpath}'\n}"
- "{line.number = '${line.number}'\n}"
- "{line.start-addr = '${line.start-addr}'\n}"
- "{line.end-addr = '${line.end-addr}'\n}"
-;
-
- SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
- ExecutionContext exe_ctx;
- frame->CalculateExecutionContext(exe_ctx);
- if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s))
- {
- printf("%s\n", s.GetData());
- }
- else
- {
- printf ("what we got: %s\n", s.GetData());
- }
-}
-#endif
-
bool Debugger::FormatDisassemblerAddress(const FormatEntity::Entry *format,
const SymbolContext *sc,
const SymbolContext *prev_sc,
@@ -1262,8 +1195,8 @@ bool Debugger::FormatDisassemblerAddress(const FormatEntity::Entry *format,
}
}
}
- // The first context on a list of instructions will have a prev_sc that
- // has no Function or Symbol -- if SymbolContext had an IsValid() method, it
+ // The first context on a list of instructions will have a prev_sc that has
+ // no Function or Symbol -- if SymbolContext had an IsValid() method, it
// would return false. But we do get a prev_sc pointer.
if ((sc && (sc->function || sc->symbol)) && prev_sc &&
(prev_sc->function == nullptr && prev_sc->symbol == nullptr)) {
@@ -1307,8 +1240,8 @@ bool Debugger::EnableLog(llvm::StringRef channel,
if (log_options & LLDB_LOG_OPTION_APPEND)
flags |= llvm::sys::fs::F_Append;
int FD;
- if (std::error_code ec =
- llvm::sys::fs::openFileForWrite(log_file, FD, flags)) {
+ if (std::error_code ec = llvm::sys::fs::openFileForWrite(
+ log_file, FD, llvm::sys::fs::CD_CreateAlways, flags)) {
error_stream << "Unable to open log file: " << ec.message();
return false;
}
@@ -1529,8 +1462,8 @@ void Debugger::HandleProcessEvent(const EventSP &event_sp) {
}
void Debugger::HandleThreadEvent(const EventSP &event_sp) {
- // At present the only thread event we handle is the Frame Changed event,
- // and all we do for that is just reprint the thread status for that thread.
+ // At present the only thread event we handle is the Frame Changed event, and
+ // all we do for that is just reprint the thread status for that thread.
using namespace lldb;
const uint32_t event_type = event_sp->GetType();
const bool stop_format = true;
@@ -1583,8 +1516,8 @@ void Debugger::DefaultEventHandler() {
CommandInterpreter::eBroadcastBitAsynchronousOutputData |
CommandInterpreter::eBroadcastBitAsynchronousErrorData);
- // Let the thread that spawned us know that we have started up and
- // that we are now listening to all required events so no events get missed
+ // Let the thread that spawned us know that we have started up and that we
+ // are now listening to all required events so no events get missed
m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening);
bool done = false;
@@ -1649,27 +1582,28 @@ lldb::thread_result_t Debugger::EventHandlerThread(lldb::thread_arg_t arg) {
bool Debugger::StartEventHandlerThread() {
if (!m_event_handler_thread.IsJoinable()) {
- // We must synchronize with the DefaultEventHandler() thread to ensure
- // it is up and running and listening to events before we return from
- // this function. We do this by listening to events for the
+ // We must synchronize with the DefaultEventHandler() thread to ensure it
+ // is up and running and listening to events before we return from this
+ // function. We do this by listening to events for the
// eBroadcastBitEventThreadIsListening from the m_sync_broadcaster
- ListenerSP listener_sp(
- Listener::MakeListener("lldb.debugger.event-handler"));
+ ConstString full_name("lldb.debugger.event-handler");
+ ListenerSP listener_sp(Listener::MakeListener(full_name.AsCString()));
listener_sp->StartListeningForEvents(&m_sync_broadcaster,
eBroadcastBitEventThreadIsListening);
+ auto thread_name =
+ full_name.GetLength() < llvm::get_max_thread_name_length() ?
+ full_name.AsCString() : "dbg.evt-handler";
+
// Use larger 8MB stack for this thread
- m_event_handler_thread = ThreadLauncher::LaunchThread(
- "lldb.debugger.event-handler", EventHandlerThread, this, nullptr,
- g_debugger_event_thread_stack_bytes);
+ m_event_handler_thread = ThreadLauncher::LaunchThread(thread_name,
+ EventHandlerThread, this, nullptr, g_debugger_event_thread_stack_bytes);
- // Make sure DefaultEventHandler() is running and listening to events before
- // we return
- // from this function. We are only listening for events of type
- // eBroadcastBitEventThreadIsListening so we don't need to check the event,
- // we just need
- // to wait an infinite amount of time for it (nullptr timeout as the first
- // parameter)
+ // Make sure DefaultEventHandler() is running and listening to events
+ // before we return from this function. We are only listening for events of
+ // type eBroadcastBitEventThreadIsListening so we don't need to check the
+ // event, we just need to wait an infinite amount of time for it (nullptr
+ // timeout as the first parameter)
lldb::EventSP event_sp;
listener_sp->GetEvent(event_sp, llvm::None);
}
diff --git a/source/Core/Disassembler.cpp b/source/Core/Disassembler.cpp
index 6d463d552da6..d41a19465280 100644
--- a/source/Core/Disassembler.cpp
+++ b/source/Core/Disassembler.cpp
@@ -96,8 +96,8 @@ DisassemblerSP Disassembler::FindPluginForTarget(const TargetSP target_sp,
const char *plugin_name) {
if (target_sp && flavor == nullptr) {
// FIXME - we don't have the mechanism in place to do per-architecture
- // settings. But since we know that for now
- // we only support flavors on x86 & x86_64,
+ // settings. But since we know that for now we only support flavors on x86
+ // & x86_64,
if (arch.GetTriple().getArch() == llvm::Triple::x86 ||
arch.GetTriple().getArch() == llvm::Triple::x86_64)
flavor = target_sp->GetDisassemblyFlavor();
@@ -108,19 +108,19 @@ DisassemblerSP Disassembler::FindPluginForTarget(const TargetSP target_sp,
static void ResolveAddress(const ExecutionContext &exe_ctx, const Address &addr,
Address &resolved_addr) {
if (!addr.IsSectionOffset()) {
- // If we weren't passed in a section offset address range,
- // try and resolve it to something
+ // If we weren't passed in a section offset address range, try and resolve
+ // it to something
Target *target = exe_ctx.GetTargetPtr();
if (target) {
- if (target->GetSectionLoadList().IsEmpty()) {
- target->GetImages().ResolveFileAddress(addr.GetOffset(), resolved_addr);
- } else {
- target->GetSectionLoadList().ResolveLoadAddress(addr.GetOffset(),
- resolved_addr);
- }
- // We weren't able to resolve the address, just treat it as a
- // raw address
- if (resolved_addr.IsValid())
+ bool is_resolved =
+ target->GetSectionLoadList().IsEmpty() ?
+ target->GetImages().ResolveFileAddress(addr.GetOffset(),
+ resolved_addr) :
+ target->GetSectionLoadList().ResolveLoadAddress(addr.GetOffset(),
+ resolved_addr);
+
+ // We weren't able to resolve the address, just treat it as a raw address
+ if (is_resolved && resolved_addr.IsValid())
return;
}
}
@@ -410,15 +410,13 @@ bool Disassembler::PrintInstructions(Disassembler *disasm_ptr,
disassembly_format = &format;
}
- // First pass: step through the list of instructions,
- // find how long the initial addresses strings are, insert padding
- // in the second pass so the opcodes all line up nicely.
+ // First pass: step through the list of instructions, find how long the
+ // initial addresses strings are, insert padding in the second pass so the
+ // opcodes all line up nicely.
// Also build up the source line mapping if this is mixed source & assembly
- // mode.
- // Calculate the source line for each assembly instruction (eliding inlined
- // functions
- // which the user wants to skip).
+ // mode. Calculate the source line for each assembly instruction (eliding
+ // inlined functions which the user wants to skip).
std::map<FileSpec, std::set<uint32_t>> source_lines_seen;
Symbol *previous_symbol = nullptr;
@@ -495,17 +493,13 @@ bool Disassembler::PrintInstructions(Disassembler *disasm_ptr,
if (mixed_source_and_assembly) {
// If we've started a new function (non-inlined), print all of the
- // source lines from the
- // function declaration until the first line table entry - typically
- // the opening curly brace of
- // the function.
+ // source lines from the function declaration until the first line
+ // table entry - typically the opening curly brace of the function.
if (previous_symbol != sc.symbol) {
- // The default disassembly format puts an extra blank line between
- // functions - so
- // when we're displaying the source context for a function, we
- // don't want to add
- // a blank line after the source context or we'll end up with two
- // of them.
+ // The default disassembly format puts an extra blank line
+ // between functions - so when we're displaying the source
+ // context for a function, we don't want to add a blank line
+ // after the source context or we'll end up with two of them.
if (previous_symbol != nullptr)
source_lines_to_display.print_source_context_end_eol = false;
@@ -520,9 +514,9 @@ bool Disassembler::PrintInstructions(Disassembler *disasm_ptr,
func_decl_line);
if (func_decl_file == prologue_end_line.file ||
func_decl_file == prologue_end_line.original_file) {
- // Add all the lines between the function declaration
- // and the first non-prologue source line to the list
- // of lines to print.
+ // Add all the lines between the function declaration and
+ // the first non-prologue source line to the list of lines
+ // to print.
for (uint32_t lineno = func_decl_line;
lineno <= prologue_end_line.line; lineno++) {
SourceLine this_line;
@@ -530,8 +524,8 @@ bool Disassembler::PrintInstructions(Disassembler *disasm_ptr,
this_line.line = lineno;
source_lines_to_display.lines.push_back(this_line);
}
- // Mark the last line as the "current" one. Usually
- // this is the open curly brace.
+ // Mark the last line as the "current" one. Usually this
+ // is the open curly brace.
if (source_lines_to_display.lines.size() > 0)
source_lines_to_display.current_source_line =
source_lines_to_display.lines.size() - 1;
@@ -542,8 +536,8 @@ bool Disassembler::PrintInstructions(Disassembler *disasm_ptr,
current_source_line_range);
}
- // If we've left a previous source line's address range, print a new
- // source line
+ // If we've left a previous source line's address range, print a
+ // new source line
if (!current_source_line_range.ContainsFileAddress(addr)) {
sc.GetAddressRange(scope, 0, use_inline_block_range,
current_source_line_range);
@@ -558,8 +552,8 @@ bool Disassembler::PrintInstructions(Disassembler *disasm_ptr,
// Only print this source line if it is different from the
// last source line we printed. There may have been inlined
// functions between these lines that we elided, resulting in
- // the same line being printed twice in a row for a contiguous
- // block of assembly instructions.
+ // the same line being printed twice in a row for a
+ // contiguous block of assembly instructions.
if (this_line != previous_line) {
std::vector<uint32_t> previous_lines;
@@ -683,7 +677,7 @@ Instruction::Instruction(const Address &address, AddressClass addr_class)
Instruction::~Instruction() = default;
AddressClass Instruction::GetAddressClass() {
- if (m_address_class == eAddressClassInvalid)
+ if (m_address_class == AddressClass::eInvalid)
m_address_class = m_address.GetAddressClass();
return m_address_class;
}
@@ -710,16 +704,16 @@ void Instruction::Dump(lldb_private::Stream *s, uint32_t max_opcode_byte_size,
if (show_bytes) {
if (m_opcode.GetType() == Opcode::eTypeBytes) {
- // x86_64 and i386 are the only ones that use bytes right now so
- // pad out the byte dump to be able to always show 15 bytes (3 chars each)
- // plus a space
+ // x86_64 and i386 are the only ones that use bytes right now so pad out
+ // the byte dump to be able to always show 15 bytes (3 chars each) plus a
+ // space
if (max_opcode_byte_size > 0)
m_opcode.Dump(&ss, max_opcode_byte_size * 3 + 1);
else
m_opcode.Dump(&ss, 15 * 3 + 1);
} else {
- // Else, we have ARM or MIPS which can show up to a uint32_t
- // 0x00000000 (10 spaces) plus two for padding...
+ // Else, we have ARM or MIPS which can show up to a uint32_t 0x00000000
+ // (10 spaces) plus two for padding...
if (max_opcode_byte_size > 0)
m_opcode.Dump(&ss, max_opcode_byte_size * 3 + 1);
else
@@ -903,7 +897,8 @@ OptionValueSP Instruction::ReadDictionary(FILE *in_file, Stream *out_stream) {
option_value_sp.reset();
return option_value_sp;
}
- // We've used the data_type to read an array; re-set the type to Invalid
+ // We've used the data_type to read an array; re-set the type to
+ // Invalid
data_type = OptionValue::eTypeInvalid;
} else if ((value[0] == '0') && (value[1] == 'x')) {
value_sp = std::make_shared<OptionValueUInt64>(0, 0);
@@ -1107,9 +1102,9 @@ InstructionList::GetIndexOfNextBranchInstruction(uint32_t start,
}
}
- // Hexagon needs the first instruction of the packet with the branch.
- // Go backwards until we find an instruction marked end-of-packet, or
- // until we hit start.
+ // Hexagon needs the first instruction of the packet with the branch. Go
+ // backwards until we find an instruction marked end-of-packet, or until we
+ // hit start.
if (target.GetArchitecture().GetTriple().getArch() == llvm::Triple::hexagon) {
// If we didn't find a branch, find the last packet start.
if (next_branch == UINT32_MAX) {
@@ -1128,8 +1123,8 @@ InstructionList::GetIndexOfNextBranchInstruction(uint32_t start,
// If we have an error reading memory, return start
if (!error.Success())
return start;
- // check if this is the last instruction in a packet
- // bits 15:14 will be 11b or 00b for a duplex
+ // check if this is the last instruction in a packet bits 15:14 will be
+ // 11b or 00b for a duplex
if (((inst_bytes & 0xC000) == 0xC000) ||
((inst_bytes & 0xC000) == 0x0000)) {
// instruction after this should be the start of next packet
@@ -1257,8 +1252,7 @@ Disassembler::Disassembler(const ArchSpec &arch, const char *flavor)
m_flavor.assign(flavor);
// If this is an arm variant that can only include thumb (T16, T32)
- // instructions, force the arch triple to be "thumbv.." instead of
- // "armv..."
+ // instructions, force the arch triple to be "thumbv.." instead of "armv..."
if (arch.IsAlwaysThumbInstructions()) {
std::string thumb_arch_name(arch.GetTriple().getArchName().str());
// Replace "arm" with "thumb" so we get all thumb variants correct
@@ -1285,7 +1279,7 @@ const InstructionList &Disassembler::GetInstructionList() const {
//----------------------------------------------------------------------
PseudoInstruction::PseudoInstruction()
- : Instruction(Address(), eAddressClassUnknown), m_description() {}
+ : Instruction(Address(), AddressClass::eUnknown), m_description() {}
PseudoInstruction::~PseudoInstruction() = default;
diff --git a/source/Core/DumpDataExtractor.cpp b/source/Core/DumpDataExtractor.cpp
index e564e86478fc..049f4d3805a1 100644
--- a/source/Core/DumpDataExtractor.cpp
+++ b/source/Core/DumpDataExtractor.cpp
@@ -239,8 +239,8 @@ lldb::offset_t lldb_private::DumpDataExtractor(
if (item_byte_size <= 8) {
uint64_t uval64 = DE.GetMaxU64Bitfield(&offset, item_byte_size,
item_bit_size, item_bit_offset);
- // Avoid std::bitset<64>::to_string() since it is missing in
- // earlier C++ libraries
+ // Avoid std::bitset<64>::to_string() since it is missing in earlier
+ // C++ libraries
std::string binary_value(64, '0');
std::bitset<64> bits(uval64);
for (uint32_t i = 0; i < 64; ++i)
@@ -263,8 +263,8 @@ lldb::offset_t lldb_private::DumpDataExtractor(
s->Printf("%2.2x", DE.GetU8(&offset));
}
- // Put an extra space between the groups of bytes if more than one
- // is being dumped in a group (item_byte_size is more than 1).
+ // Put an extra space between the groups of bytes if more than one is
+ // being dumped in a group (item_byte_size is more than 1).
if (item_byte_size > 1)
s->PutChar(' ');
break;
@@ -279,8 +279,7 @@ lldb::offset_t lldb_private::DumpDataExtractor(
return offset;
}
- // If we are only printing one character surround it with single
- // quotes
+ // If we are only printing one character surround it with single quotes
if (item_count == 1 && item_format == eFormatChar)
s->PutChar('\'');
@@ -583,8 +582,10 @@ lldb::offset_t lldb_private::DumpDataExtractor(
} else if (item_bit_size == ast->getTypeSize(ast->LongDoubleTy)) {
const auto &semantics =
ast->getFloatTypeSemantics(ast->LongDoubleTy);
- const auto byte_size =
- (llvm::APFloat::getSizeInBits(semantics) + 7) / 8;
+
+ offset_t byte_size = item_byte_size;
+ if (&semantics == &llvm::APFloatBase::x87DoubleExtended())
+ byte_size = (llvm::APFloat::getSizeInBits(semantics) + 7) / 8;
llvm::APInt apint;
if (GetAPInt(DE, &offset, byte_size, apint)) {
@@ -691,10 +692,9 @@ lldb::offset_t lldb_private::DumpDataExtractor(
break;
// please keep the single-item formats below in sync with
- // FormatManager::GetSingleItemFormat
- // if you fail to do so, users will start getting different outputs
- // depending on internal
- // implementation details they should not care about ||
+ // FormatManager::GetSingleItemFormat if you fail to do so, users will
+ // start getting different outputs depending on internal implementation
+ // details they should not care about ||
case eFormatVectorOfChar: // ||
s->PutChar('{'); // \/
offset =
diff --git a/source/Core/DumpRegisterValue.cpp b/source/Core/DumpRegisterValue.cpp
new file mode 100644
index 000000000000..99334ca78a6d
--- /dev/null
+++ b/source/Core/DumpRegisterValue.cpp
@@ -0,0 +1,79 @@
+//===-- DumpRegisterValue.cpp -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Core/DumpRegisterValue.h"
+#include "lldb/Core/DumpDataExtractor.h"
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/StreamString.h"
+#include "lldb/lldb-private-types.h"
+
+using namespace lldb;
+
+bool lldb_private::DumpRegisterValue(const RegisterValue &reg_val, Stream *s,
+ const RegisterInfo *reg_info,
+ bool prefix_with_name,
+ bool prefix_with_alt_name, Format format,
+ uint32_t reg_name_right_align_at) {
+ DataExtractor data;
+ if (reg_val.GetData(data)) {
+ bool name_printed = false;
+ // For simplicity, alignment of the register name printing applies only in
+ // the most common case where:
+ //
+ // prefix_with_name^prefix_with_alt_name is true
+ //
+ StreamString format_string;
+ if (reg_name_right_align_at && (prefix_with_name ^ prefix_with_alt_name))
+ format_string.Printf("%%%us", reg_name_right_align_at);
+ else
+ format_string.Printf("%%s");
+ std::string fmt = format_string.GetString();
+ if (prefix_with_name) {
+ if (reg_info->name) {
+ s->Printf(fmt.c_str(), reg_info->name);
+ name_printed = true;
+ } else if (reg_info->alt_name) {
+ s->Printf(fmt.c_str(), reg_info->alt_name);
+ prefix_with_alt_name = false;
+ name_printed = true;
+ }
+ }
+ if (prefix_with_alt_name) {
+ if (name_printed)
+ s->PutChar('/');
+ if (reg_info->alt_name) {
+ s->Printf(fmt.c_str(), reg_info->alt_name);
+ name_printed = true;
+ } else if (!name_printed) {
+ // No alternate name but we were asked to display a name, so show the
+ // main name
+ s->Printf(fmt.c_str(), reg_info->name);
+ name_printed = true;
+ }
+ }
+ if (name_printed)
+ s->PutCString(" = ");
+
+ if (format == eFormatDefault)
+ format = reg_info->format;
+
+ DumpDataExtractor(data, s,
+ 0, // Offset in "data"
+ format, // Format to use when dumping
+ reg_info->byte_size, // item_byte_size
+ 1, // item_count
+ UINT32_MAX, // num_per_line
+ LLDB_INVALID_ADDRESS, // base_addr
+ 0, // item_bit_size
+ 0); // item_bit_offset
+ return true;
+ }
+ return false;
+}
diff --git a/source/Core/DynamicLoader.cpp b/source/Core/DynamicLoader.cpp
index 5477498dadc8..16f1ffca1a20 100644
--- a/source/Core/DynamicLoader.cpp
+++ b/source/Core/DynamicLoader.cpp
@@ -64,8 +64,8 @@ DynamicLoader::DynamicLoader(Process *process) : m_process(process) {}
DynamicLoader::~DynamicLoader() = default;
//----------------------------------------------------------------------
-// Accessosors to the global setting as to whether to stop at image
-// (shared library) loading/unloading.
+// Accessosors to the global setting as to whether to stop at image (shared
+// library) loading/unloading.
//----------------------------------------------------------------------
bool DynamicLoader::GetStopWhenImagesChange() const {
@@ -86,8 +86,8 @@ ModuleSP DynamicLoader::GetTargetExecutable() {
executable->GetArchitecture());
auto module_sp = std::make_shared<Module>(module_spec);
- // Check if the executable has changed and set it to the target executable
- // if they differ.
+ // Check if the executable has changed and set it to the target
+ // executable if they differ.
if (module_sp && module_sp->GetUUID().IsValid() &&
executable->GetUUID().IsValid()) {
if (module_sp->GetUUID() != executable->GetUUID())
@@ -99,8 +99,8 @@ ModuleSP DynamicLoader::GetTargetExecutable() {
if (!executable) {
executable = target.GetSharedModule(module_spec);
if (executable.get() != target.GetExecutableModulePointer()) {
- // Don't load dependent images since we are in dyld where we will know
- // and find out about all images that are loaded
+ // Don't load dependent images since we are in dyld where we will
+ // know and find out about all images that are loaded
const bool get_dependent_images = false;
target.SetExecutableModule(executable, get_dependent_images);
}
@@ -177,8 +177,8 @@ ModuleSP DynamicLoader::LoadModuleAtAddress(const FileSpec &file,
bool check_alternative_file_name = true;
if (base_addr_is_offset) {
// Try to fetch the load address of the file from the process as we need
- // absolute load
- // address to read the file out of the memory instead of a load bias.
+ // absolute load address to read the file out of the memory instead of a
+ // load bias.
bool is_loaded = false;
lldb::addr_t load_addr;
Status error = m_process->GetFileLoadAddress(file, is_loaded, load_addr);
@@ -188,9 +188,8 @@ ModuleSP DynamicLoader::LoadModuleAtAddress(const FileSpec &file,
}
}
- // We failed to find the module based on its name. Lets try to check if we can
- // find a
- // different name based on the memory region info.
+ // We failed to find the module based on its name. Lets try to check if we
+ // can find a different name based on the memory region info.
if (check_alternative_file_name) {
MemoryRegionInfo memory_info;
Status error = m_process->GetMemoryRegionInfo(base_addr, memory_info);
diff --git a/source/Core/EmulateInstruction.cpp b/source/Core/EmulateInstruction.cpp
index 2ee2c79de270..469022119c9e 100644
--- a/source/Core/EmulateInstruction.cpp
+++ b/source/Core/EmulateInstruction.cpp
@@ -10,6 +10,7 @@
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Core/Address.h"
+#include "lldb/Core/DumpRegisterValue.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/StreamFile.h"
@@ -361,7 +362,7 @@ bool EmulateInstruction::WriteRegisterDefault(EmulateInstruction *instruction,
const RegisterValue &reg_value) {
StreamFile strm(stdout, false);
strm.Printf(" Write to Register (name = %s, value = ", reg_info->name);
- reg_value.Dump(&strm, reg_info, false, false, eFormatDefault);
+ DumpRegisterValue(reg_value, &strm, reg_info, false, false, eFormatDefault);
strm.PutCString(", context = ");
context.Dump(strm, instruction);
strm.EOL();
diff --git a/source/Core/Event.cpp b/source/Core/Event.cpp
index 8d351d8ba1a5..3ebad7acdef7 100644
--- a/source/Core/Event.cpp
+++ b/source/Core/Event.cpp
@@ -10,7 +10,6 @@
#include "lldb/Core/Event.h"
#include "lldb/Core/Broadcaster.h"
-#include "lldb/Core/DumpDataExtractor.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/Stream.h"
@@ -134,14 +133,13 @@ const ConstString &EventDataBytes::GetFlavor() const {
void EventDataBytes::Dump(Stream *s) const {
size_t num_printable_chars =
std::count_if(m_bytes.begin(), m_bytes.end(), isprint);
- if (num_printable_chars == m_bytes.size()) {
- s->Printf("\"%s\"", m_bytes.c_str());
- } else if (!m_bytes.empty()) {
- DataExtractor data;
- data.SetData(m_bytes.data(), m_bytes.size(), endian::InlHostByteOrder());
- DumpDataExtractor(data, s, 0, eFormatBytes, 1, m_bytes.size(), 32,
- LLDB_INVALID_ADDRESS, 0, 0);
- }
+ if (num_printable_chars == m_bytes.size())
+ s->Format("\"{0}\"", m_bytes);
+ else
+ s->Format("{0:$[ ]@[x-2]}", llvm::make_range(
+ reinterpret_cast<const uint8_t *>(m_bytes.data()),
+ reinterpret_cast<const uint8_t *>(m_bytes.data() +
+ m_bytes.size())));
}
const void *EventDataBytes::GetBytes() const {
diff --git a/source/Core/FileLineResolver.cpp b/source/Core/FileLineResolver.cpp
index 36f37f4a14d5..7f0f440252e7 100644
--- a/source/Core/FileLineResolver.cpp
+++ b/source/Core/FileLineResolver.cpp
@@ -54,8 +54,8 @@ FileLineResolver::SearchCallback(SearchFilter &filter, SymbolContext &context,
while (file_idx != UINT32_MAX) {
line_table->FineLineEntriesForFileIndex(file_idx, append,
m_sc_list);
- // Get the next file index in case we have multiple file
- // entries for the same file
+ // Get the next file index in case we have multiple file entries
+ // for the same file
file_idx = cu->GetSupportFiles().FindFileIndex(file_idx + 1,
m_file_spec, false);
}
diff --git a/source/Core/FileSpecList.cpp b/source/Core/FileSpecList.cpp
index 5b0bdac654e1..66e27b197447 100644
--- a/source/Core/FileSpecList.cpp
+++ b/source/Core/FileSpecList.cpp
@@ -42,11 +42,10 @@ void FileSpecList::Append(const FileSpec &file_spec) {
}
//------------------------------------------------------------------
-// Only append the "file_spec" if this list doesn't already contain
-// it.
+// Only append the "file_spec" if this list doesn't already contain it.
//
-// Returns true if "file_spec" was added, false if this list already
-// contained a copy of "file_spec".
+// Returns true if "file_spec" was added, false if this list already contained
+// a copy of "file_spec".
//------------------------------------------------------------------
bool FileSpecList::AppendIfUnique(const FileSpec &file_spec) {
collection::iterator end = m_files.end();
@@ -75,18 +74,18 @@ void FileSpecList::Dump(Stream *s, const char *separator_cstr) const {
}
//------------------------------------------------------------------
-// Find the index of the file in the file spec list that matches
-// "file_spec" starting "start_idx" entries into the file spec list.
+// Find the index of the file in the file spec list that matches "file_spec"
+// starting "start_idx" entries into the file spec list.
//
-// Returns the valid index of the file that matches "file_spec" if
-// it is found, else std::numeric_limits<uint32_t>::max() is returned.
+// Returns the valid index of the file that matches "file_spec" if it is found,
+// else std::numeric_limits<uint32_t>::max() is returned.
//------------------------------------------------------------------
size_t FileSpecList::FindFileIndex(size_t start_idx, const FileSpec &file_spec,
- bool full, bool remove_dots) const {
+ bool full) const {
const size_t num_files = m_files.size();
- // When looking for files, we will compare only the filename if the
- // FILE_SPEC argument is empty
+ // When looking for files, we will compare only the filename if the FILE_SPEC
+ // argument is empty
bool compare_filename_only = file_spec.GetDirectory().IsEmpty();
for (size_t idx = start_idx; idx < num_files; ++idx) {
@@ -96,7 +95,7 @@ size_t FileSpecList::FindFileIndex(size_t start_idx, const FileSpec &file_spec,
file_spec.IsCaseSensitive() || m_files[idx].IsCaseSensitive()))
return idx;
} else {
- if (FileSpec::Equal(m_files[idx], file_spec, full, remove_dots))
+ if (FileSpec::Equal(m_files[idx], file_spec, full))
return idx;
}
}
@@ -106,8 +105,8 @@ size_t FileSpecList::FindFileIndex(size_t start_idx, const FileSpec &file_spec,
}
//------------------------------------------------------------------
-// Returns the FileSpec object at index "idx". If "idx" is out of
-// range, then an empty FileSpec object will be returned.
+// Returns the FileSpec object at index "idx". If "idx" is out of range, then
+// an empty FileSpec object will be returned.
//------------------------------------------------------------------
const FileSpec &FileSpecList::GetFileSpecAtIndex(size_t idx) const {
if (idx < m_files.size())
@@ -123,11 +122,10 @@ const FileSpec *FileSpecList::GetFileSpecPointerAtIndex(size_t idx) const {
}
//------------------------------------------------------------------
-// Return the size in bytes that this object takes in memory. This
-// returns the size in bytes of this object's member variables and
-// any FileSpec objects its member variables contain, the result
-// doesn't not include the string values for the directories any
-// filenames as those are in shared string pools.
+// Return the size in bytes that this object takes in memory. This returns the
+// size in bytes of this object's member variables and any FileSpec objects its
+// member variables contain, the result doesn't not include the string values
+// for the directories any filenames as those are in shared string pools.
//------------------------------------------------------------------
size_t FileSpecList::MemorySize() const {
size_t mem_size = sizeof(FileSpecList);
diff --git a/source/Core/FormatEntity.cpp b/source/Core/FormatEntity.cpp
index 0cb74cc7658d..2257b7e273e8 100644
--- a/source/Core/FormatEntity.cpp
+++ b/source/Core/FormatEntity.cpp
@@ -12,6 +12,7 @@
#include "lldb/Core/Address.h"
#include "lldb/Core/AddressRange.h" // for AddressRange
#include "lldb/Core/Debugger.h"
+#include "lldb/Core/DumpRegisterValue.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/RegisterValue.h" // for RegisterValue
#include "lldb/Core/ValueObject.h"
@@ -467,10 +468,9 @@ static bool DumpAddressOffsetFromFunction(Stream &s, const SymbolContext *sc,
if (sc->function) {
func_addr = sc->function->GetAddressRange().GetBaseAddress();
if (sc->block && !concrete_only) {
- // Check to make sure we aren't in an inline
- // function. If we are, use the inline block
- // range that contains "format_addr" since
- // blocks can be discontiguous.
+ // Check to make sure we aren't in an inline function. If we are, use
+ // the inline block range that contains "format_addr" since blocks
+ // can be discontiguous.
Block *inline_block = sc->block->GetContainingInlinedBlock();
AddressRange inline_range;
if (inline_block &&
@@ -622,7 +622,7 @@ static bool DumpRegister(Stream &s, StackFrame *frame, RegisterKind reg_kind,
if (reg_info) {
RegisterValue reg_value;
if (reg_ctx->ReadRegister(reg_info, reg_value)) {
- reg_value.Dump(&s, reg_info, false, false, format);
+ DumpRegisterValue(reg_value, &s, reg_info, false, false, format);
return true;
}
}
@@ -822,8 +822,7 @@ static bool DumpValue(Stream &s, const SymbolContext *sc,
if (do_deref_pointer && !is_array_range) {
// I have not deref-ed yet, let's do it
// this happens when we are not going through
- // GetValueForVariableExpressionPath
- // to get to the target ValueObject
+ // GetValueForVariableExpressionPath to get to the target ValueObject
Status error;
target = target->Dereference(error).get();
if (error.Fail()) {
@@ -842,9 +841,9 @@ static bool DumpValue(Stream &s, const SymbolContext *sc,
return false;
}
- // we do not want to use the summary for a bitfield of type T:n
- // if we were originally dealing with just a T - that would get
- // us into an endless recursion
+ // we do not want to use the summary for a bitfield of type T:n if we were
+ // originally dealing with just a T - that would get us into an endless
+ // recursion
if (target->IsBitfield() && was_var_indexed) {
// TODO: check for a (T:n)-specific summary - we should still obey that
StreamString bitfield_name;
@@ -905,8 +904,7 @@ static bool DumpValue(Stream &s, const SymbolContext *sc,
}
// if directly trying to print ${var}, and this is an aggregate, display a
- // nice
- // type @ location message
+ // nice type @ location message
if (is_aggregate && was_plain_var) {
s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
return true;
@@ -1021,7 +1019,7 @@ static bool DumpRegister(Stream &s, StackFrame *frame, const char *reg_name,
if (reg_info) {
RegisterValue reg_value;
if (reg_ctx->ReadRegister(reg_info, reg_value)) {
- reg_value.Dump(&s, reg_info, false, false, format);
+ DumpRegisterValue(reg_value, &s, reg_info, false, false, format);
return true;
}
}
@@ -1142,8 +1140,8 @@ bool FormatEntity::Format(const Entry &entry, Stream &s,
if (!success)
break;
}
- // Only if all items in a scope succeed, then do we
- // print the output into the main stream
+ // Only if all items in a scope succeed, then do we print the output into
+ // the main stream
if (success)
s.Write(scope_stream.GetString().data(), scope_stream.GetString().size());
}
@@ -1206,9 +1204,8 @@ bool FormatEntity::Format(const Entry &entry, Stream &s,
// Watch for the special "tid" format...
if (entry.printf_format == "tid") {
// TODO(zturner): Rather than hardcoding this to be platform
- // specific, it should be controlled by a
- // setting and the default value of the setting can be different
- // depending on the platform.
+ // specific, it should be controlled by a setting and the default
+ // value of the setting can be different depending on the platform.
Target &target = thread->GetProcess()->GetTarget();
ArchSpec arch(target.GetArchitecture());
llvm::Triple::OSType ostype = arch.IsValid()
@@ -1914,9 +1911,9 @@ static Status ParseEntry(const llvm::StringRef &format_str,
error.SetErrorStringWithFormat("%s", error_strm.GetData());
} else if (sep_char == ':') {
// Any value whose separator is a with a ':' means this value has a
- // string argument
- // that needs to be stored in the entry (like "${script.var:}").
- // In this case the string value is the empty string which is ok.
+ // string argument that needs to be stored in the entry (like
+ // "${script.var:}"). In this case the string value is the empty
+ // string which is ok.
} else {
error.SetErrorStringWithFormat("%s", "invalid entry definitions");
}
@@ -1926,8 +1923,7 @@ static Status ParseEntry(const llvm::StringRef &format_str,
error = ParseEntry(value, entry_def, entry);
} else if (sep_char == ':') {
// Any value whose separator is a with a ':' means this value has a
- // string argument
- // that needs to be stored in the entry (like
+ // string argument that needs to be stored in the entry (like
// "${script.var:modulename.function}")
entry.string = value.str();
} else {
@@ -2065,17 +2061,17 @@ Status FormatEntity::ParseInternal(llvm::StringRef &format, Entry &parent_entry,
case '0':
// 1 to 3 octal chars
{
- // Make a string that can hold onto the initial zero char,
- // up to 3 octal digits, and a terminating NULL.
+ // Make a string that can hold onto the initial zero char, up to 3
+ // octal digits, and a terminating NULL.
char oct_str[5] = {0, 0, 0, 0, 0};
int i;
for (i = 0; (format[i] >= '0' && format[i] <= '7') && i < 4; ++i)
oct_str[i] = format[i];
- // We don't want to consume the last octal character since
- // the main for loop will do this for us, so we advance p by
- // one less than i (even if i is zero)
+ // We don't want to consume the last octal character since the main
+ // for loop will do this for us, so we advance p by one less than i
+ // (even if i is zero)
format = format.drop_front(i);
unsigned long octal_value = ::strtoul(oct_str, nullptr, 8);
if (octal_value <= UINT8_MAX) {
@@ -2115,8 +2111,8 @@ Status FormatEntity::ParseInternal(llvm::StringRef &format, Entry &parent_entry,
break;
default:
- // Just desensitize any other character by just printing what
- // came after the '\'
+ // Just desensitize any other character by just printing what came
+ // after the '\'
parent_entry.AppendChar(desens_char);
break;
}
@@ -2142,10 +2138,9 @@ Status FormatEntity::ParseInternal(llvm::StringRef &format, Entry &parent_entry,
if (!variable_format.empty()) {
entry.printf_format = variable_format.str();
- // If the format contains a '%' we are going to assume this is
- // a printf style format. So if you want to format your thread ID
- // using "0x%llx" you can use:
- // ${thread.id%0x%llx}
+ // If the format contains a '%' we are going to assume this is a
+ // printf style format. So if you want to format your thread ID
+ // using "0x%llx" you can use: ${thread.id%0x%llx}
//
// If there is no '%' in the format, then it is assumed to be a
// LLDB format name, or one of the extended formats specified in
@@ -2264,9 +2259,9 @@ Status FormatEntity::ParseInternal(llvm::StringRef &format, Entry &parent_entry,
return error;
}
}
- // Check if this entry just wants to insert a constant string
- // value into the parent_entry, if so, insert the string with
- // AppendText, else append the entry to the parent_entry.
+ // Check if this entry just wants to insert a constant string value
+ // into the parent_entry, if so, insert the string with AppendText,
+ // else append the entry to the parent_entry.
if (entry.type == Entry::Type::InsertString)
parent_entry.AppendText(entry.string.c_str());
else
@@ -2350,12 +2345,12 @@ static void AddMatches(const FormatEntity::Entry::Definition *def,
}
}
-size_t FormatEntity::AutoComplete(llvm::StringRef str, int match_start_point,
- int max_return_elements, bool &word_complete,
- StringList &matches) {
- word_complete = false;
- str = str.drop_front(match_start_point);
- matches.Clear();
+size_t FormatEntity::AutoComplete(CompletionRequest &request) {
+ llvm::StringRef str = request.GetCursorArgumentPrefix().str();
+
+ request.SetWordComplete(false);
+ str = str.drop_front(request.GetMatchStartPoint());
+ request.GetMatches().Clear();
const size_t dollar_pos = str.rfind('$');
if (dollar_pos == llvm::StringRef::npos)
@@ -2365,7 +2360,7 @@ size_t FormatEntity::AutoComplete(llvm::StringRef str, int match_start_point,
if (dollar_pos == str.size() - 1) {
std::string match = str.str();
match.append("{");
- matches.AppendString(match);
+ request.GetMatches().AppendString(match);
return 1;
}
@@ -2383,8 +2378,8 @@ size_t FormatEntity::AutoComplete(llvm::StringRef str, int match_start_point,
llvm::StringRef partial_variable(str.substr(dollar_pos + 2));
if (partial_variable.empty()) {
// Suggest all top level entites as we are just past "${"
- AddMatches(&g_root, str, llvm::StringRef(), matches);
- return matches.GetSize();
+ AddMatches(&g_root, str, llvm::StringRef(), request.GetMatches());
+ return request.GetMatches().GetSize();
}
// We have a partially specified variable, find it
@@ -2400,19 +2395,19 @@ size_t FormatEntity::AutoComplete(llvm::StringRef str, int match_start_point,
// Exact match
if (n > 0) {
// "${thread.info" <TAB>
- matches.AppendString(MakeMatch(str, "."));
+ request.GetMatches().AppendString(MakeMatch(str, "."));
} else {
// "${thread.id" <TAB>
- matches.AppendString(MakeMatch(str, "}"));
- word_complete = true;
+ request.GetMatches().AppendString(MakeMatch(str, "}"));
+ request.SetWordComplete(true);
}
} else if (remainder.equals(".")) {
// "${thread." <TAB>
- AddMatches(entry_def, str, llvm::StringRef(), matches);
+ AddMatches(entry_def, str, llvm::StringRef(), request.GetMatches());
} else {
// We have a partial match
// "${thre" <TAB>
- AddMatches(entry_def, str, remainder, matches);
+ AddMatches(entry_def, str, remainder, request.GetMatches());
}
- return matches.GetSize();
+ return request.GetMatches().GetSize();
}
diff --git a/source/Core/IOHandler.cpp b/source/Core/IOHandler.cpp
index 103b5ecde94a..8474e4b8c564 100644
--- a/source/Core/IOHandler.cpp
+++ b/source/Core/IOHandler.cpp
@@ -67,6 +67,7 @@
#include <assert.h> // for assert
#include <ctype.h> // for isspace
#include <errno.h> // for EINTR, errno
+#include <locale.h> // for setlocale
#include <stdint.h> // for uint32_t, UINT32_MAX
#include <stdio.h> // for size_t, fprintf, feof
#include <string.h> // for strlen
@@ -238,27 +239,21 @@ int IOHandlerDelegate::IOHandlerComplete(IOHandler &io_handler,
matches);
case Completion::Expression: {
- bool word_complete = false;
- const char *word_start = cursor;
- if (cursor > current_line)
- --word_start;
- while (word_start > current_line && !isspace(*word_start))
- --word_start;
+ CompletionRequest request(current_line, current_line - cursor,
+ skip_first_n_matches, max_matches, matches);
CommandCompletions::InvokeCommonCompletionCallbacks(
io_handler.GetDebugger().GetCommandInterpreter(),
- CommandCompletions::eVariablePathCompletion, word_start,
- skip_first_n_matches, max_matches, nullptr, word_complete, matches);
+ CommandCompletions::eVariablePathCompletion, request, nullptr);
- size_t num_matches = matches.GetSize();
+ size_t num_matches = request.GetMatches().GetSize();
if (num_matches > 0) {
std::string common_prefix;
- matches.LongestCommonPrefix(common_prefix);
- const size_t partial_name_len = strlen(word_start);
+ request.GetMatches().LongestCommonPrefix(common_prefix);
+ const size_t partial_name_len = request.GetCursorArgumentPrefix().size();
- // If we matched a unique single command, add a space...
- // Only do this if the completer told us this was a complete word,
- // however...
- if (num_matches == 1 && word_complete) {
+ // If we matched a unique single command, add a space... Only do this if
+ // the completer told us this was a complete word, however...
+ if (num_matches == 1 && request.GetWordComplete()) {
common_prefix.push_back(' ');
}
common_prefix.erase(0, partial_name_len);
@@ -320,8 +315,7 @@ IOHandlerEditline::IOHandlerEditline(
const char *indent_chars = delegate.IOHandlerGetFixIndentationCharacters();
if (indent_chars) {
// The delegate does support indentation, hook it up so when any
- // indentation
- // character is typed, the delegate gets a chance to fix it
+ // indentation character is typed, the delegate gets a chance to fix it
m_editline_ap->SetFixIndentationCallback(FixIndentationCallback, this,
indent_chars);
}
@@ -407,8 +401,8 @@ bool IOHandlerEditline::GetLine(std::string &line, bool &interrupted) {
}
}
m_editing = false;
- // We might have gotten a newline on a line by itself
- // make sure to return true in this case.
+ // We might have gotten a newline on a line by itself make sure to return
+ // true in this case.
return got_line;
} else {
// No more input file, we are done...
@@ -544,9 +538,8 @@ bool IOHandlerEditline::GetLines(StringList &lines, bool &interrupted) {
return success;
}
-// Each IOHandler gets to run until it is done. It should read data
-// from the "in" and place output into "out" and "err and return
-// when done.
+// Each IOHandler gets to run until it is done. It should read data from the
+// "in" and place output into "out" and "err and return when done.
void IOHandlerEditline::Run() {
std::string line;
while (IsActive()) {
@@ -634,8 +627,7 @@ void IOHandlerEditline::PrintAsync(Stream *stream, const char *s, size_t len) {
}
}
-// we may want curses to be disabled for some builds
-// for instance, windows
+// we may want curses to be disabled for some builds for instance, windows
#ifndef LLDB_DISABLE_CURSES
#define KEY_RETURN 10
@@ -737,9 +729,8 @@ struct Rect {
origin.y += h;
}
- // Return a status bar rectangle which is the last line of
- // this rectangle. This rectangle will be modified to not
- // include the status bar area.
+ // Return a status bar rectangle which is the last line of this rectangle.
+ // This rectangle will be modified to not include the status bar area.
Rect MakeStatusBar() {
Rect status_bar;
if (size.height > 1) {
@@ -752,9 +743,8 @@ struct Rect {
return status_bar;
}
- // Return a menubar rectangle which is the first line of
- // this rectangle. This rectangle will be modified to not
- // include the menubar area.
+ // Return a menubar rectangle which is the first line of this rectangle. This
+ // rectangle will be modified to not include the menubar area.
Rect MakeMenuBar() {
Rect menubar;
if (size.height > 1) {
@@ -1203,12 +1193,10 @@ public:
return result;
}
- // Then check for any windows that want any keys
- // that weren't handled. This is typically only
- // for a menubar.
- // Make a copy of the subwindows in case any HandleChar()
- // functions muck with the subwindows. If we don't do this,
- // we can crash when iterating over the subwindows.
+ // Then check for any windows that want any keys that weren't handled. This
+ // is typically only for a menubar. Make a copy of the subwindows in case
+ // any HandleChar() functions muck with the subwindows. If we don't do
+ // this, we can crash when iterating over the subwindows.
Windows subwindows(m_subwindows);
for (auto subwindow_sp : subwindows) {
if (!subwindow_sp->m_can_activate) {
@@ -1395,8 +1383,8 @@ public:
}
MenuActionResult Action() {
- // Call the recursive action so it can try to handle it
- // with the menu delegate, and if not, try our parent menu
+ // Call the recursive action so it can try to handle it with the menu
+ // delegate, and if not, try our parent menu
return ActionPrivate(*this);
}
@@ -1665,9 +1653,9 @@ HandleCharResult Menu::WindowDelegateHandleChar(Window &window, int key) {
}
if (run_menu_sp) {
- // Run the action on this menu in case we need to populate the
- // menu with dynamic content and also in case check marks, and
- // any other menu decorations need to be calculated
+ // Run the action on this menu in case we need to populate the menu with
+ // dynamic content and also in case check marks, and any other menu
+ // decorations need to be calculated
if (run_menu_sp->Action() == MenuActionResult::Quit)
return eQuitApplication;
@@ -1781,12 +1769,11 @@ public:
bool done = false;
int delay_in_tenths_of_a_second = 1;
- // Alas the threading model in curses is a bit lame so we need to
- // resort to polling every 0.5 seconds. We could poll for stdin
- // ourselves and then pass the keys down but then we need to
- // translate all of the escape sequences ourselves. So we resort to
- // polling for input because we need to receive async process events
- // while in this loop.
+ // Alas the threading model in curses is a bit lame so we need to resort to
+ // polling every 0.5 seconds. We could poll for stdin ourselves and then
+ // pass the keys down but then we need to translate all of the escape
+ // sequences ourselves. So we resort to polling for input because we need
+ // to receive async process events while in this loop.
halfdelay(delay_in_tenths_of_a_second); // Poll using some number of tenths
// of seconds seconds when calling
@@ -1807,9 +1794,9 @@ public:
while (!done) {
if (update) {
m_window_sp->Draw(false);
- // All windows should be calling Window::DeferredRefresh() instead
- // of Window::Refresh() so we can do a single update and avoid
- // any screen blinking
+ // All windows should be calling Window::DeferredRefresh() instead of
+ // Window::Refresh() so we can do a single update and avoid any screen
+ // blinking
update_panels();
// Cursor hiding isn't working on MacOSX, so hide it in the top left
@@ -1821,8 +1808,8 @@ public:
}
#if defined(__APPLE__)
- // Terminal.app doesn't map its function keys correctly, F1-F4 default to:
- // \033OP, \033OQ, \033OR, \033OS, so lets take care of this here if
+ // Terminal.app doesn't map its function keys correctly, F1-F4 default
+ // to: \033OP, \033OQ, \033OR, \033OS, so lets take care of this here if
// possible
int ch;
if (escape_chars.empty())
@@ -1985,8 +1972,8 @@ struct Row {
parent->DrawTreeForChild(window, this, 0);
if (might_have_children) {
- // It we can get UTF8 characters to work we should try to use the "symbol"
- // UTF8 string below
+ // It we can get UTF8 characters to work we should try to use the
+ // "symbol" UTF8 string below
// const char *symbol = "";
// if (row.expanded)
// symbol = "\xe2\x96\xbd ";
@@ -1994,14 +1981,14 @@ struct Row {
// symbol = "\xe2\x96\xb7 ";
// window.PutCString (symbol);
- // The ACS_DARROW and ACS_RARROW don't look very nice they are just a
- // 'v' or '>' character...
+ // The ACS_DARROW and ACS_RARROW don't look very nice they are just a 'v'
+ // or '>' character...
// if (expanded)
// window.PutChar (ACS_DARROW);
// else
// window.PutChar (ACS_RARROW);
- // Since we can't find any good looking right arrow/down arrow
- // symbols, just use a diamond...
+ // Since we can't find any good looking right arrow/down arrow symbols,
+ // just use a diamond...
window.PutChar(ACS_DIAMOND);
window.PutChar(ACS_HLINE);
}
@@ -2101,9 +2088,8 @@ public:
const bool expanded = IsExpanded();
- // The root item must calculate its children,
- // or we must calculate the number of children
- // if the item is expanded
+ // The root item must calculate its children, or we must calculate the
+ // number of children if the item is expanded
if (m_parent == nullptr || expanded)
GetNumChildren();
@@ -2136,8 +2122,7 @@ public:
if (m_might_have_children) {
// It we can get UTF8 characters to work we should try to use the
- // "symbol"
- // UTF8 string below
+ // "symbol" UTF8 string below
// const char *symbol = "";
// if (row.expanded)
// symbol = "\xe2\x96\xbd ";
@@ -2151,8 +2136,8 @@ public:
// window.PutChar (ACS_DARROW);
// else
// window.PutChar (ACS_RARROW);
- // Since we can't find any good looking right arrow/down arrow
- // symbols, just use a diamond...
+ // Since we can't find any good looking right arrow/down arrow symbols,
+ // just use a diamond...
window.PutChar(ACS_DIAMOND);
window.PutChar(ACS_HLINE);
}
@@ -2175,8 +2160,8 @@ public:
if (IsExpanded()) {
for (auto &item : m_children) {
- // If we displayed all the rows and item.Draw() returns
- // false we are done drawing and can exit this for loop
+ // If we displayed all the rows and item.Draw() returns false we are
+ // done drawing and can exit this for loop
if (!item.Draw(window, first_visible_row, selected_row_idx, row_idx,
num_rows_left))
break;
@@ -2286,10 +2271,9 @@ public:
m_num_rows = 0;
m_root.CalculateRowIndexes(m_num_rows);
- // If we unexpanded while having something selected our
- // total number of rows is less than the num visible rows,
- // then make sure we show all the rows by setting the first
- // visible row accordingly.
+ // If we unexpanded while having something selected our total number of
+ // rows is less than the num visible rows, then make sure we show all the
+ // rows by setting the first visible row accordingly.
if (m_first_visible_row > 0 && m_num_rows < num_visible_rows)
m_first_visible_row = 0;
@@ -2695,10 +2679,9 @@ public:
const int num_visible_rows = NumVisibleRows();
const int num_rows = CalculateTotalNumberRows(m_rows);
- // If we unexpanded while having something selected our
- // total number of rows is less than the num visible rows,
- // then make sure we show all the rows by setting the first
- // visible row accordingly.
+ // If we unexpanded while having something selected our total number of
+ // rows is less than the num visible rows, then make sure we show all the
+ // rows by setting the first visible row accordingly.
if (m_first_visible_row > 0 && num_rows < num_visible_rows)
m_first_visible_row = 0;
@@ -2714,8 +2697,8 @@ public:
// Get the selected row
m_selected_row = GetRowForRowIndex(m_selected_row_idx);
- // Keep the cursor on the selected row so the highlight and the cursor
- // are always on the same line
+ // Keep the cursor on the selected row so the highlight and the cursor are
+ // always on the same line
if (m_selected_row)
window.MoveCursor(m_selected_row->x, m_selected_row->y);
@@ -3127,8 +3110,8 @@ public:
if (process && process->IsAlive())
return true; // Don't do any updating if we are running
else {
- // Update the values with an empty list if there
- // is no process or the process isn't alive anymore
+ // Update the values with an empty list if there is no process or the
+ // process isn't alive anymore
SetValues(value_list);
}
}
@@ -3392,8 +3375,8 @@ HandleCharResult HelpDialogDelegate::WindowDelegateHandleChar(Window &window,
if (num_lines <= num_visible_lines) {
done = true;
- // If we have all lines visible and don't need scrolling, then any
- // key press will cause us to exit
+ // If we have all lines visible and don't need scrolling, then any key
+ // press will cause us to exit
} else {
switch (key) {
case KEY_UP:
@@ -3606,8 +3589,8 @@ public:
case eMenuID_Process: {
// Populate the menu with all of the threads if the process is stopped
- // when
- // the Process menu gets selected and is about to display its submenu.
+ // when the Process menu gets selected and is about to display its
+ // submenu.
Menus &submenus = menu.GetSubmenus();
ExecutionContext exe_ctx =
m_debugger.GetCommandInterpreter().GetExecutionContext();
@@ -3642,8 +3625,8 @@ public:
nullptr, menu_char, thread_sp->GetID())));
}
} else if (submenus.size() > 7) {
- // Remove the separator and any other thread submenu items
- // that were previously added
+ // Remove the separator and any other thread submenu items that were
+ // previously added
submenus.erase(submenus.begin() + 7, submenus.end());
}
// Since we are adding and removing items we need to recalculate the name
@@ -3671,8 +3654,8 @@ public:
registers_bounds.size.width = source_bounds.size.width;
registers_window_sp->SetBounds(registers_bounds);
} else {
- // We have no registers window showing so give the bottom
- // area back to the source view
+ // We have no registers window showing so give the bottom area back
+ // to the source view
source_window_sp->Resize(source_bounds.size.width,
source_bounds.size.height +
variables_bounds.size.height);
@@ -3721,8 +3704,8 @@ public:
registers_window_sp->GetWidth(),
variables_bounds.size.height);
} else {
- // We have no variables window showing so give the bottom
- // area back to the source view
+ // We have no variables window showing so give the bottom area back
+ // to the source view
source_window_sp->Resize(source_bounds.size.width,
source_bounds.size.height +
registers_window_sp->GetHeight());
@@ -3731,9 +3714,9 @@ public:
} else {
Rect new_regs_rect;
if (variables_window_sp) {
- // We have a variables window, split it into two columns
- // where the left hand side will be the variables and the
- // right hand side will be the registers
+ // We have a variables window, split it into two columns where the
+ // left hand side will be the variables and the right hand side will
+ // be the registers
const Rect variables_bounds = variables_window_sp->GetBounds();
Rect new_vars_rect;
variables_bounds.VerticalSplitPercentage(0.50, new_vars_rect,
@@ -3945,8 +3928,8 @@ public:
m_selected_line = m_pc_line;
if (m_file_sp && m_file_sp->FileSpecMatches(m_sc.line_entry.file)) {
- // Same file, nothing to do, we should either have the
- // lines or not (source file missing)
+ // Same file, nothing to do, we should either have the lines or not
+ // (source file missing)
if (m_selected_line >= static_cast<size_t>(m_first_visible_line)) {
if (m_selected_line >= m_first_visible_line + num_visible_lines)
m_first_visible_line = m_selected_line - 10;
@@ -4627,8 +4610,8 @@ void IOHandlerCursesGUI::Activate() {
WindowSP menubar_window_sp =
main_window_sp->CreateSubWindow("Menubar", menubar_bounds, false);
- // Let the menubar get keys if the active window doesn't handle the
- // keys that are typed so it can respond to menubar key presses.
+ // Let the menubar get keys if the active window doesn't handle the keys
+ // that are typed so it can respond to menubar key presses.
menubar_window_sp->SetCanBeActive(
false); // Don't let the menubar become the active window
menubar_window_sp->SetDelegate(menubar_sp);
diff --git a/source/Core/Listener.cpp b/source/Core/Listener.cpp
index 1afa11649b59..a39ce6121b32 100644
--- a/source/Core/Listener.cpp
+++ b/source/Core/Listener.cpp
@@ -304,11 +304,9 @@ bool Listener::FindNextEventInternal(
if (remove) {
m_events.erase(pos);
- // Unlock the event queue here. We've removed this event and are about to
- // return
- // it so it should be okay to get the next event off the queue here - and
- // it might
- // be useful to do that in the "DoOnRemoval".
+ // Unlock the event queue here. We've removed this event and are about
+ // to return it so it should be okay to get the next event off the queue
+ // here - and it might be useful to do that in the "DoOnRemoval".
lock.unlock();
event_sp->DoOnRemoval();
}
@@ -434,8 +432,8 @@ Listener::StartListeningForEventSpec(BroadcasterManagerSP manager_sp,
if (!manager_sp)
return 0;
- // The BroadcasterManager mutex must be locked before m_broadcasters_mutex
- // to avoid violating the lock hierarchy (manager before broadcasters).
+ // The BroadcasterManager mutex must be locked before m_broadcasters_mutex to
+ // avoid violating the lock hierarchy (manager before broadcasters).
std::lock_guard<std::recursive_mutex> manager_guard(
manager_sp->m_manager_mutex);
std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
diff --git a/source/Core/Mangled.cpp b/source/Core/Mangled.cpp
index 211a0c32cee7..545ac51c870f 100644
--- a/source/Core/Mangled.cpp
+++ b/source/Core/Mangled.cpp
@@ -16,34 +16,24 @@
#pragma comment(lib, "dbghelp.lib")
#endif
-#ifdef LLDB_USE_BUILTIN_DEMANGLER
-// Provide a fast-path demangler implemented in FastDemangle.cpp until it can
-// replace the existing C++ demangler with a complete implementation
-#include "lldb/Utility/FastDemangle.h"
-#include "llvm/Demangle/Demangle.h"
-#else
-// FreeBSD9-STABLE requires this to know about size_t in cxxabi.
-#include <cstddef>
-#include <cxxabi.h>
-#endif
-
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Logging.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/Timer.h"
-#include "lldb/lldb-enumerations.h" // for LanguageType
+#include "lldb/lldb-enumerations.h"
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
#include "Plugins/Language/ObjC/ObjCLanguage.h"
-#include "llvm/ADT/StringRef.h" // for StringRef
-#include "llvm/Support/Compiler.h" // for LLVM_PRETT...
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Demangle/Demangle.h"
+#include "llvm/Support/Compiler.h"
-#include <mutex> // for mutex, loc...
-#include <string> // for string
-#include <utility> // for pair
+#include <mutex>
+#include <string>
+#include <utility>
#include <stdlib.h>
#include <string.h>
@@ -90,10 +80,8 @@ get_demangled_name_without_arguments(ConstString mangled,
g_most_recent_mangled_to_name_sans_args;
// Need to have the mangled & demangled names we're currently examining as
- // statics
- // so we can return a const ref to them at the end of the func if we don't
- // have
- // anything better.
+ // statics so we can return a const ref to them at the end of the func if we
+ // don't have anything better.
static ConstString g_last_mangled;
static ConstString g_last_demangled;
@@ -142,8 +130,8 @@ get_demangled_name_without_arguments(ConstString mangled,
Mangled::Mangled() : m_mangled(), m_demangled() {}
//----------------------------------------------------------------------
-// Constructor with an optional string and a boolean indicating if it is
-// the mangled version.
+// Constructor with an optional string and a boolean indicating if it is the
+// mangled version.
//----------------------------------------------------------------------
Mangled::Mangled(const ConstString &s, bool mangled)
: m_mangled(), m_demangled() {
@@ -172,8 +160,8 @@ Mangled::Mangled(llvm::StringRef name) {
Mangled::~Mangled() {}
//----------------------------------------------------------------------
-// Convert to pointer operator. This allows code to check any Mangled
-// objects to see if they contain anything valid using code such as:
+// Convert to pointer operator. This allows code to check any Mangled objects
+// to see if they contain anything valid using code such as:
//
// Mangled mangled(...);
// if (mangled)
@@ -184,8 +172,8 @@ Mangled::operator void *() const {
}
//----------------------------------------------------------------------
-// Logical NOT operator. This allows code to check any Mangled
-// objects to see if they are invalid using code such as:
+// Logical NOT operator. This allows code to check any Mangled objects to see
+// if they are invalid using code such as:
//
// Mangled mangled(...);
// if (!file_spec)
@@ -211,9 +199,8 @@ int Mangled::Compare(const Mangled &a, const Mangled &b) {
}
//----------------------------------------------------------------------
-// Set the string value in this objects. If "mangled" is true, then
-// the mangled named is set with the new value in "s", else the
-// demangled name is set.
+// Set the string value in this objects. If "mangled" is true, then the mangled
+// named is set with the new value in "s", else the demangled name is set.
//----------------------------------------------------------------------
void Mangled::SetValue(const ConstString &s, bool mangled) {
if (s) {
@@ -246,16 +233,15 @@ void Mangled::SetValue(const ConstString &name) {
}
//----------------------------------------------------------------------
-// Generate the demangled name on demand using this accessor. Code in
-// this class will need to use this accessor if it wishes to decode
-// the demangled name. The result is cached and will be kept until a
-// new string value is supplied to this object, or until the end of the
-// object's lifetime.
+// Generate the demangled name on demand using this accessor. Code in this
+// class will need to use this accessor if it wishes to decode the demangled
+// name. The result is cached and will be kept until a new string value is
+// supplied to this object, or until the end of the object's lifetime.
//----------------------------------------------------------------------
const ConstString &
Mangled::GetDemangledName(lldb::LanguageType language) const {
- // Check to make sure we have a valid mangled name and that we
- // haven't already decoded our mangled name.
+ // Check to make sure we have a valid mangled name and that we haven't
+ // already decoded our mangled name.
if (m_mangled && !m_demangled) {
// We need to generate and cache the demangled name.
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
@@ -299,19 +285,15 @@ Mangled::GetDemangledName(lldb::LanguageType language) const {
break;
}
case eManglingSchemeItanium: {
-#ifdef LLDB_USE_BUILTIN_DEMANGLER
- if (log)
- log->Printf("demangle itanium: %s", mangled_name);
- // Try to use the fast-path demangler first for the
- // performance win, falling back to the full demangler only
- // when necessary
- demangled_name = FastDemangle(mangled_name, m_mangled.GetLength());
- if (!demangled_name)
- demangled_name =
- llvm::itaniumDemangle(mangled_name, NULL, NULL, NULL);
-#else
- demangled_name = abi::__cxa_demangle(mangled_name, NULL, NULL, NULL);
-#endif
+ llvm::ItaniumPartialDemangler IPD;
+ bool demangle_err = IPD.partialDemangle(mangled_name);
+ if (!demangle_err) {
+ // Default buffer and size (realloc is used in case it's too small).
+ size_t demangled_size = 80;
+ demangled_name = static_cast<char *>(::malloc(demangled_size));
+ demangled_name = IPD.finishDemangle(demangled_name, &demangled_size);
+ }
+
if (log) {
if (demangled_name)
log->Printf("demangled itanium: %s -> \"%s\"", mangled_name,
@@ -331,8 +313,8 @@ Mangled::GetDemangledName(lldb::LanguageType language) const {
}
}
if (!m_demangled) {
- // Set the demangled string to the empty string to indicate we
- // tried to parse it once and failed.
+ // Set the demangled string to the empty string to indicate we tried to
+ // parse it once and failed.
m_demangled.SetCString("");
}
}
@@ -370,8 +352,8 @@ ConstString Mangled::GetName(lldb::LanguageType language,
return get_demangled_name_without_arguments(m_mangled, demangled);
}
if (preference == ePreferDemangled) {
- // Call the accessor to make sure we get a demangled name in case
- // it hasn't been demangled yet...
+ // Call the accessor to make sure we get a demangled name in case it hasn't
+ // been demangled yet...
if (demangled)
return demangled;
return m_mangled;
@@ -380,8 +362,8 @@ ConstString Mangled::GetName(lldb::LanguageType language,
}
//----------------------------------------------------------------------
-// Dump a Mangled object to stream "s". We don't force our
-// demangled name to be computed currently (we don't use the accessor).
+// Dump a Mangled object to stream "s". We don't force our demangled name to be
+// computed currently (we don't use the accessor).
//----------------------------------------------------------------------
void Mangled::Dump(Stream *s) const {
if (m_mangled) {
@@ -394,8 +376,8 @@ void Mangled::Dump(Stream *s) const {
}
//----------------------------------------------------------------------
-// Dumps a debug version of this string with extra object and state
-// information to stream "s".
+// Dumps a debug version of this string with extra object and state information
+// to stream "s".
//----------------------------------------------------------------------
void Mangled::DumpDebug(Stream *s) const {
s->Printf("%*p: Mangled mangled = ", static_cast<int>(sizeof(void *) * 2),
@@ -406,21 +388,21 @@ void Mangled::DumpDebug(Stream *s) const {
}
//----------------------------------------------------------------------
-// Return the size in byte that this object takes in memory. The size
-// includes the size of the objects it owns, and not the strings that
-// it references because they are shared strings.
+// Return the size in byte that this object takes in memory. The size includes
+// the size of the objects it owns, and not the strings that it references
+// because they are shared strings.
//----------------------------------------------------------------------
size_t Mangled::MemorySize() const {
return m_mangled.MemorySize() + m_demangled.MemorySize();
}
//----------------------------------------------------------------------
-// We "guess" the language because we can't determine a symbol's language
-// from it's name. For example, a Pascal symbol can be mangled using the
-// C++ Itanium scheme, and defined in a compilation unit within the same
-// module as other C++ units. In addition, different targets could have
-// different ways of mangling names from a given language, likewise the
-// compilation units within those targets.
+// We "guess" the language because we can't determine a symbol's language from
+// it's name. For example, a Pascal symbol can be mangled using the C++
+// Itanium scheme, and defined in a compilation unit within the same module as
+// other C++ units. In addition, different targets could have different ways
+// of mangling names from a given language, likewise the compilation units
+// within those targets.
//----------------------------------------------------------------------
lldb::LanguageType Mangled::GuessLanguage() const {
ConstString mangled = GetMangledName();
@@ -433,7 +415,7 @@ lldb::LanguageType Mangled::GuessLanguage() const {
return lldb::eLanguageTypeObjC;
}
} else {
- // ObjC names aren't really mangled, so they won't necessarily be in the
+ // ObjC names aren't really mangled, so they won't necessarily be in the
// mangled name slot.
ConstString demangled_name = GetDemangledName(lldb::eLanguageTypeUnknown);
if (demangled_name
diff --git a/source/Core/Module.cpp b/source/Core/Module.cpp
index 8f80be45f1b0..3b1a4fd7be0f 100644
--- a/source/Core/Module.cpp
+++ b/source/Core/Module.cpp
@@ -38,6 +38,7 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Logging.h" // for GetLogIfAn...
#include "lldb/Utility/RegularExpression.h"
@@ -46,13 +47,12 @@
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
-#if defined(LLVM_ON_WIN32)
+#if defined(_WIN32)
#include "lldb/Host/windows/PosixApi.h" // for PATH_MAX
#endif
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
#include "Plugins/Language/ObjC/ObjCLanguage.h"
-#include "Plugins/ObjectFile/JIT/ObjectFileJIT.h"
#include "llvm/ADT/STLExtras.h" // for make_unique
#include "llvm/Support/Compiler.h" // for LLVM_PRETT...
@@ -79,21 +79,17 @@ class VariableList;
using namespace lldb;
using namespace lldb_private;
-// Shared pointers to modules track module lifetimes in
-// targets and in the global module, but this collection
-// will track all module objects that are still alive
+// Shared pointers to modules track module lifetimes in targets and in the
+// global module, but this collection will track all module objects that are
+// still alive
typedef std::vector<Module *> ModuleCollection;
static ModuleCollection &GetModuleCollection() {
// This module collection needs to live past any module, so we could either
- // make it a
- // shared pointer in each module or just leak is. Since it is only an empty
- // vector by
- // the time all the modules have gone away, we just leak it for now. If we
- // decide this
- // is a big problem we can introduce a Finalize method that will tear
- // everything down in
- // a predictable order.
+ // make it a shared pointer in each module or just leak is. Since it is only
+ // an empty vector by the time all the modules have gone away, we just leak
+ // it for now. If we decide this is a big problem we can introduce a
+ // Finalize method that will tear everything down in a predictable order.
static ModuleCollection *g_module_collection = nullptr;
if (g_module_collection == nullptr)
@@ -104,9 +100,9 @@ static ModuleCollection &GetModuleCollection() {
std::recursive_mutex &Module::GetAllocationModuleCollectionMutex() {
// NOTE: The mutex below must be leaked since the global module list in
- // the ModuleList class will get torn at some point, and we can't know
- // if it will tear itself down before the "g_module_collection_mutex" below
- // will. So we leak a Mutex object below to safeguard against that
+ // the ModuleList class will get torn at some point, and we can't know if it
+ // will tear itself down before the "g_module_collection_mutex" below will.
+ // So we leak a Mutex object below to safeguard against that
static std::recursive_mutex *g_module_collection_mutex = nullptr;
if (g_module_collection_mutex == nullptr)
@@ -151,8 +147,8 @@ Module::Module(const ModuleSpec &module_spec)
: module_spec.GetObjectName().AsCString(""),
module_spec.GetObjectName().IsEmpty() ? "" : ")");
- // First extract all module specifications from the file using the local
- // file path. If there are no specifications, then don't fill anything in
+ // First extract all module specifications from the file using the local file
+ // path. If there are no specifications, then don't fill anything in
ModuleSpecList modules_specs;
if (ObjectFile::GetModuleSpecifications(module_spec.GetFileSpec(), 0, 0,
modules_specs) == 0)
@@ -160,9 +156,8 @@ Module::Module(const ModuleSpec &module_spec)
// Now make sure that one of the module specifications matches what we just
// extract. We might have a module specification that specifies a file
- // "/usr/lib/dyld"
- // with UUID XXX, but we might have a local version of "/usr/lib/dyld" that
- // has
+ // "/usr/lib/dyld" with UUID XXX, but we might have a local version of
+ // "/usr/lib/dyld" that has
// UUID YYY and we don't want those to match. If they don't match, just don't
// fill any ivars in so we don't accidentally grab the wrong file later since
// they don't match...
@@ -177,8 +172,8 @@ Module::Module(const ModuleSpec &module_spec)
m_mod_time =
FileSystem::GetModificationTime(matching_module_spec.GetFileSpec());
- // Copy the architecture from the actual spec if we got one back, else use the
- // one that was specified
+ // Copy the architecture from the actual spec if we got one back, else use
+ // the one that was specified
if (matching_module_spec.GetArchitecture().IsValid())
m_arch = matching_module_spec.GetArchitecture();
else if (module_spec.GetArchitecture().IsValid())
@@ -210,9 +205,9 @@ Module::Module(const ModuleSpec &module_spec)
else
m_object_name = module_spec.GetObjectName();
- // Always trust the object offset (file offset) and object modification
- // time (for mod time in a BSD static archive) of from the matching
- // module specification
+ // Always trust the object offset (file offset) and object modification time
+ // (for mod time in a BSD static archive) of from the matching module
+ // specification
m_object_offset = matching_module_spec.GetObjectOffset();
m_object_mod_time = matching_module_spec.GetObjectModificationTime();
}
@@ -253,8 +248,8 @@ Module::Module()
}
Module::~Module() {
- // Lock our module down while we tear everything down to make sure
- // we don't get any access to the module while it is being destroyed
+ // Lock our module down while we tear everything down to make sure we don't
+ // get any access to the module while it is being destroyed
std::lock_guard<std::recursive_mutex> guard(m_mutex);
// Scope for locker below...
{
@@ -308,9 +303,8 @@ ObjectFile *Module::GetMemoryObjectFile(const lldb::ProcessSP &process_sp,
m_object_name.SetString(s.GetString());
// Once we get the object file, update our module with the object
- // file's
- // architecture since it might differ in vendor/os if some parts were
- // unknown.
+ // file's architecture since it might differ in vendor/os if some
+ // parts were unknown.
m_objfile_sp->GetArchitecture(m_arch);
} else {
error.SetErrorString("unable to find suitable object file plug-in");
@@ -327,20 +321,30 @@ ObjectFile *Module::GetMemoryObjectFile(const lldb::ProcessSP &process_sp,
}
const lldb_private::UUID &Module::GetUUID() {
- if (!m_did_parse_uuid.load()) {
+ if (!m_did_set_uuid.load()) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
- if (!m_did_parse_uuid.load()) {
+ if (!m_did_set_uuid.load()) {
ObjectFile *obj_file = GetObjectFile();
if (obj_file != nullptr) {
obj_file->GetUUID(&m_uuid);
- m_did_parse_uuid = true;
+ m_did_set_uuid = true;
}
}
}
return m_uuid;
}
+void Module::SetUUID(const lldb_private::UUID &uuid) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (!m_did_set_uuid) {
+ m_uuid = uuid;
+ m_did_set_uuid = true;
+ } else {
+ lldbassert(0 && "Attempting to overwrite the existing module UUID");
+ }
+}
+
TypeSystem *Module::GetTypeSystemForLanguage(LanguageType language) {
return m_type_system_map.GetTypeSystemForLanguage(language, this, true);
}
@@ -441,8 +445,8 @@ uint32_t Module::ResolveSymbolContextForAddress(
// Make sure the section matches this module before we try and match anything
if (section_sp && section_sp->GetModule().get() == this) {
- // If the section offset based address resolved itself, then this
- // is the right module.
+ // If the section offset based address resolved itself, then this is the
+ // right module.
sc.module_sp = shared_from_this();
resolved_flags |= eSymbolContextModule;
@@ -450,8 +454,8 @@ uint32_t Module::ResolveSymbolContextForAddress(
if (!sym_vendor)
return resolved_flags;
- // Resolve the compile unit, function, block, line table or line
- // entry if requested.
+ // Resolve the compile unit, function, block, line table or line entry if
+ // requested.
if (resolve_scope & eSymbolContextCompUnit ||
resolve_scope & eSymbolContextFunction ||
resolve_scope & eSymbolContextBlock ||
@@ -461,8 +465,8 @@ uint32_t Module::ResolveSymbolContextForAddress(
sym_vendor->ResolveSymbolContext(so_addr, resolve_scope, sc);
}
- // Resolve the symbol if requested, but don't re-look it up if we've already
- // found it.
+ // Resolve the symbol if requested, but don't re-look it up if we've
+ // already found it.
if (resolve_scope & eSymbolContextSymbol &&
!(resolved_flags & eSymbolContextSymbol)) {
Symtab *symtab = sym_vendor->GetSymtab();
@@ -491,12 +495,11 @@ uint32_t Module::ResolveSymbolContextForAddress(
if (sc.symbol) {
if (sc.symbol->IsSynthetic()) {
- // We have a synthetic symbol so lets check if the object file
- // from the symbol file in the symbol vendor is different than
- // the object file for the module, and if so search its symbol
- // table to see if we can come up with a better symbol. For example
- // dSYM files on MacOSX have an unstripped symbol table inside of
- // them.
+ // We have a synthetic symbol so lets check if the object file from
+ // the symbol file in the symbol vendor is different than the
+ // object file for the module, and if so search its symbol table to
+ // see if we can come up with a better symbol. For example dSYM
+ // files on MacOSX have an unstripped symbol table inside of them.
ObjectFile *symtab_objfile = symtab->GetObjectFile();
if (symtab_objfile && symtab_objfile->IsStripped()) {
SymbolFile *symfile = sym_vendor->GetSymbolFile();
@@ -522,10 +525,8 @@ uint32_t Module::ResolveSymbolContextForAddress(
}
// For function symbols, so_addr may be off by one. This is a convention
- // consistent
- // with FDE row indices in eh_frame sections, but requires extra logic here
- // to permit
- // symbol lookup for disassembly and unwind.
+ // consistent with FDE row indices in eh_frame sections, but requires extra
+ // logic here to permit symbol lookup for disassembly and unwind.
if (resolve_scope & eSymbolContextSymbol &&
!(resolved_flags & eSymbolContextSymbol) && resolve_tail_call_address &&
so_addr.IsSectionOffset()) {
@@ -542,10 +543,9 @@ uint32_t Module::ResolveSymbolContextForAddress(
if (addr_range.GetBaseAddress().GetSection() ==
so_addr.GetSection()) {
// If the requested address is one past the address range of a
- // function (i.e. a tail call),
- // or the decremented address is the start of a function (i.e. some
- // forms of trampoline),
- // indicate that the symbol has been resolved.
+ // function (i.e. a tail call), or the decremented address is the
+ // start of a function (i.e. some forms of trampoline), indicate
+ // that the symbol has been resolved.
if (so_addr.GetOffset() ==
addr_range.GetBaseAddress().GetOffset() ||
so_addr.GetOffset() ==
@@ -599,21 +599,21 @@ uint32_t Module::ResolveSymbolContextsForFileSpec(const FileSpec &file_spec,
size_t Module::FindGlobalVariables(const ConstString &name,
const CompilerDeclContext *parent_decl_ctx,
- bool append, size_t max_matches,
+ size_t max_matches,
VariableList &variables) {
SymbolVendor *symbols = GetSymbolVendor();
if (symbols)
- return symbols->FindGlobalVariables(name, parent_decl_ctx, append,
- max_matches, variables);
+ return symbols->FindGlobalVariables(name, parent_decl_ctx, max_matches,
+ variables);
return 0;
}
-size_t Module::FindGlobalVariables(const RegularExpression &regex, bool append,
+size_t Module::FindGlobalVariables(const RegularExpression &regex,
size_t max_matches,
VariableList &variables) {
SymbolVendor *symbols = GetSymbolVendor();
if (symbols)
- return symbols->FindGlobalVariables(regex, append, max_matches, variables);
+ return symbols->FindGlobalVariables(regex, max_matches, variables);
return 0;
}
@@ -677,25 +677,22 @@ Module::LookupInfo::LookupInfo(const ConstString &name, uint32_t name_type_mask,
if (name_type_mask & eFunctionNameTypeMethod ||
name_type_mask & eFunctionNameTypeBase) {
// If they've asked for a CPP method or function name and it can't be
- // that, we don't
- // even need to search for CPP methods or names.
+ // that, we don't even need to search for CPP methods or names.
CPlusPlusLanguage::MethodName cpp_method(name);
if (cpp_method.IsValid()) {
basename = cpp_method.GetBasename();
if (!cpp_method.GetQualifiers().empty()) {
// There is a "const" or other qualifier following the end of the
- // function parens,
- // this can't be a eFunctionNameTypeBase
+ // function parens, this can't be a eFunctionNameTypeBase
m_name_type_mask &= ~(eFunctionNameTypeBase);
if (m_name_type_mask == eFunctionNameTypeNone)
return;
}
} else {
// If the CPP method parser didn't manage to chop this up, try to fill
- // in the base name if we can.
- // If a::b::c is passed in, we need to just look up "c", and then we'll
- // filter the result later.
+ // in the base name if we can. If a::b::c is passed in, we need to just
+ // look up "c", and then we'll filter the result later.
CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
basename);
}
@@ -724,19 +721,15 @@ Module::LookupInfo::LookupInfo(const ConstString &name, uint32_t name_type_mask,
}
if (!basename.empty()) {
- // The name supplied was a partial C++ path like "a::count". In this case we
- // want to do a
- // lookup on the basename "count" and then make sure any matching results
- // contain "a::count"
- // so that it would match "b::a::count" and "a::count". This is why we set
- // "match_name_after_lookup"
- // to true
+ // The name supplied was a partial C++ path like "a::count". In this case
+ // we want to do a lookup on the basename "count" and then make sure any
+ // matching results contain "a::count" so that it would match "b::a::count"
+ // and "a::count". This is why we set "match_name_after_lookup" to true
m_lookup_name.SetString(basename);
m_match_name_after_lookup = true;
} else {
// The name is already correct, just use the exact name as supplied, and we
- // won't need
- // to check if any matches contain "name"
+ // won't need to check if any matches contain "name"
m_lookup_name = name;
m_match_name_after_lookup = false;
}
@@ -770,8 +763,8 @@ void Module::LookupInfo::Prune(SymbolContextList &sc_list,
while (i < sc_list.GetSize()) {
if (!sc_list.GetContextAtIndex(i, sc))
break;
- // Make sure the mangled and demangled names don't match before we try
- // to pull anything out
+ // Make sure the mangled and demangled names don't match before we try to
+ // pull anything out
ConstString mangled_name(sc.GetFunctionName(Mangled::ePreferMangled));
ConstString full_name(sc.GetFunctionName());
if (mangled_name != m_name && full_name != m_name)
@@ -867,7 +860,8 @@ size_t Module::FindFunctions(const RegularExpression &regex,
if (symbols) {
symbols->FindFunctions(regex, include_inlines, append, sc_list);
- // Now check our symbol table for symbols that are code symbols if requested
+ // Now check our symbol table for symbols that are code symbols if
+ // requested
if (include_symbols) {
Symtab *symtab = symbols->GetSymtab();
if (symtab) {
@@ -882,7 +876,8 @@ size_t Module::FindFunctions(const RegularExpression &regex,
size_t num_functions_added_to_sc_list =
end_functions_added_index - start_size;
if (num_functions_added_to_sc_list == 0) {
- // No functions were added, just symbols, so we can just append them
+ // No functions were added, just symbols, so we can just append
+ // them
for (size_t i = 0; i < num_matches; ++i) {
sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
SymbolType sym_type = sc.symbol->GetType();
@@ -1001,6 +996,7 @@ size_t Module::FindTypes(
const bool append = true;
TypeClass type_class = eTypeClassAny;
TypeMap typesmap;
+
if (Type::GetTypeScopeAndBasename(type_name_cstr, type_scope, type_basename,
type_class)) {
// Check if "name" starts with "::" which means the qualified type starts
@@ -1019,17 +1015,23 @@ size_t Module::FindTypes(
} else {
// The type is not in a namespace/class scope, just search for it by
// basename
- if (type_class != eTypeClassAny) {
+ if (type_class != eTypeClassAny && !type_basename.empty()) {
// The "type_name_cstr" will have been modified if we have a valid type
- // class
- // prefix (like "struct", "class", "union", "typedef" etc).
+ // class prefix (like "struct", "class", "union", "typedef" etc).
FindTypes_Impl(sc, ConstString(type_basename), nullptr, append,
- max_matches, searched_symbol_files, typesmap);
- typesmap.RemoveMismatchedTypes(type_class);
+ UINT_MAX, searched_symbol_files, typesmap);
+ typesmap.RemoveMismatchedTypes(type_scope, type_basename, type_class,
+ exact_match);
num_matches = typesmap.GetSize();
} else {
- num_matches = FindTypes_Impl(sc, name, nullptr, append, max_matches,
+ num_matches = FindTypes_Impl(sc, name, nullptr, append, UINT_MAX,
searched_symbol_files, typesmap);
+ if (exact_match) {
+ std::string name_str(name.AsCString(""));
+ typesmap.RemoveMismatchedTypes(type_scope, name_str, type_class,
+ exact_match);
+ num_matches = typesmap.GetSize();
+ }
}
}
if (num_matches > 0)
@@ -1057,8 +1059,8 @@ SymbolVendor *Module::GetSymbolVendor(bool can_create,
void Module::SetFileSpecAndObjectName(const FileSpec &file,
const ConstString &object_name) {
- // Container objects whose paths do not specify a file directly can call
- // this function to correct the file and object names.
+ // Container objects whose paths do not specify a file directly can call this
+ // function to correct the file and object names.
m_file = file;
m_mod_time = FileSystem::GetModificationTime(file);
m_object_name = object_name;
@@ -1258,12 +1260,10 @@ ObjectFile *Module::GetObjectFile() {
file_size - m_object_offset, data_sp, data_offset);
if (m_objfile_sp) {
// Once we get the object file, update our module with the object
- // file's
- // architecture since it might differ in vendor/os if some parts were
- // unknown. But since the matching arch might already be more
- // specific
- // than the generic COFF architecture, only merge in those values that
- // overwrite unspecified unknown values.
+ // file's architecture since it might differ in vendor/os if some
+ // parts were unknown. But since the matching arch might already be
+ // more specific than the generic COFF architecture, only merge in
+ // those values that overwrite unspecified unknown values.
ArchSpec new_arch;
m_objfile_sp->GetArchitecture(new_arch);
m_arch.MergeFrom(new_arch);
@@ -1278,7 +1278,7 @@ ObjectFile *Module::GetObjectFile() {
}
SectionList *Module::GetSectionList() {
- // Populate m_unified_sections_ap with sections from objfile.
+ // Populate m_sections_ap with sections from objfile.
if (!m_sections_ap) {
ObjectFile *obj_file = GetObjectFile();
if (obj_file != nullptr)
@@ -1297,7 +1297,6 @@ void Module::SectionFileAddressesChanged() {
}
SectionList *Module::GetUnifiedSectionList() {
- // Populate m_unified_sections_ap with sections from objfile.
if (!m_sections_ap)
m_sections_ap = llvm::make_unique<SectionList>();
return m_sections_ap.get();
@@ -1428,9 +1427,8 @@ void Module::SetSymbolFileFileSpec(const FileSpec &file) {
if (section_list && symbol_file) {
ObjectFile *obj_file = symbol_file->GetObjectFile();
// Make sure we have an object file and that the symbol vendor's objfile
- // isn't
- // the same as the module's objfile before we remove any sections for
- // it...
+ // isn't the same as the module's objfile before we remove any sections
+ // for it...
if (obj_file) {
// Check to make sure we aren't trying to specify the file we already
// have
@@ -1445,8 +1443,7 @@ void Module::SetSymbolFileFileSpec(const FileSpec &file) {
obj_file->ClearSymtab();
// The symbol file might be a directory bundle ("/tmp/a.out.dSYM")
- // instead
- // of a full path to the symbol file within the bundle
+ // instead of a full path to the symbol file within the bundle
// ("/tmp/a.out.dSYM/Contents/Resources/DWARF/a.out"). So we need to
// check this
@@ -1473,8 +1470,7 @@ void Module::SetSymbolFileFileSpec(const FileSpec &file) {
}
}
// Keep all old symbol files around in case there are any lingering type
- // references in
- // any SBValue objects that might have been handed out.
+ // references in any SBValue objects that might have been handed out.
m_old_symfiles.push_back(std::move(m_symfile_ap));
}
m_symfile_spec = file;
@@ -1644,37 +1640,10 @@ bool Module::RemapSourceFile(llvm::StringRef path,
return m_source_mappings.RemapPath(path, new_path);
}
-uint32_t Module::GetVersion(uint32_t *versions, uint32_t num_versions) {
- ObjectFile *obj_file = GetObjectFile();
- if (obj_file)
- return obj_file->GetVersion(versions, num_versions);
-
- if (versions != nullptr && num_versions != 0) {
- for (uint32_t i = 0; i < num_versions; ++i)
- versions[i] = LLDB_INVALID_MODULE_VERSION;
- }
- return 0;
-}
-
-ModuleSP
-Module::CreateJITModule(const lldb::ObjectFileJITDelegateSP &delegate_sp) {
- if (delegate_sp) {
- // Must create a module and place it into a shared pointer before
- // we can create an object file since it has a std::weak_ptr back
- // to the module, so we need to control the creation carefully in
- // this static function
- ModuleSP module_sp(new Module());
- module_sp->m_objfile_sp =
- std::make_shared<ObjectFileJIT>(module_sp, delegate_sp);
- if (module_sp->m_objfile_sp) {
- // Once we get the object file, update our module with the object file's
- // architecture since it might differ in vendor/os if some parts were
- // unknown.
- module_sp->m_objfile_sp->GetArchitecture(module_sp->m_arch);
- }
- return module_sp;
- }
- return ModuleSP();
+llvm::VersionTuple Module::GetVersion() {
+ if (ObjectFile *obj_file = GetObjectFile())
+ return obj_file->GetVersion();
+ return llvm::VersionTuple();
}
bool Module::GetIsDynamicLinkEditor() {
@@ -1685,7 +1654,3 @@ bool Module::GetIsDynamicLinkEditor() {
return false;
}
-
-Status Module::LoadInMemory(Target &target, bool set_pc) {
- return m_objfile_sp->LoadInMemory(target, set_pc);
-}
diff --git a/source/Core/ModuleList.cpp b/source/Core/ModuleList.cpp
index 3970052b7bf3..d2896da1adca 100644
--- a/source/Core/ModuleList.cpp
+++ b/source/Core/ModuleList.cpp
@@ -13,6 +13,9 @@
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Symbols.h"
+#include "lldb/Interpreter/OptionValueProperties.h"
+#include "lldb/Interpreter/OptionValueFileSpec.h"
+#include "lldb/Interpreter/Property.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h" // for SymbolContextList, SymbolCon...
#include "lldb/Symbol/VariableList.h"
@@ -23,7 +26,7 @@
#include "lldb/Utility/UUID.h" // for UUID, operator!=, operator==
#include "lldb/lldb-defines.h" // for LLDB_INVALID_INDEX32
-#if defined(LLVM_ON_WIN32)
+#if defined(_WIN32)
#include "lldb/Host/windows/PosixApi.h" // for PATH_MAX
#endif
@@ -31,6 +34,7 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Threading.h"
#include "llvm/Support/raw_ostream.h" // for fs
+#include "clang/Driver/Driver.h"
#include <chrono> // for operator!=, time_point
#include <memory> // for shared_ptr
@@ -60,6 +64,51 @@ class TypeList;
using namespace lldb;
using namespace lldb_private;
+namespace {
+
+PropertyDefinition g_properties[] = {
+ {"enable-external-lookup", OptionValue::eTypeBoolean, true, true, nullptr,
+ nullptr,
+ "Control the use of external tools or libraries to locate symbol files. "
+ "On macOS, Spotlight is used to locate a matching .dSYM bundle based on "
+ "the UUID of the executable."},
+ {"clang-modules-cache-path", OptionValue::eTypeFileSpec, true, 0, nullptr,
+ nullptr,
+ "The path to the clang modules cache directory (-fmodules-cache-path)."},
+ {nullptr, OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr}};
+
+enum { ePropertyEnableExternalLookup, ePropertyClangModulesCachePath };
+
+} // namespace
+
+ModuleListProperties::ModuleListProperties() {
+ m_collection_sp.reset(new OptionValueProperties(ConstString("symbols")));
+ m_collection_sp->Initialize(g_properties);
+
+ llvm::SmallString<128> path;
+ clang::driver::Driver::getDefaultModuleCachePath(path);
+ SetClangModulesCachePath(path);
+}
+
+bool ModuleListProperties::GetEnableExternalLookup() const {
+ const uint32_t idx = ePropertyEnableExternalLookup;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_properties[idx].default_uint_value != 0);
+}
+
+FileSpec ModuleListProperties::GetClangModulesCachePath() const {
+ return m_collection_sp
+ ->GetPropertyAtIndexAsOptionValueFileSpec(nullptr, false,
+ ePropertyClangModulesCachePath)
+ ->GetCurrentValue();
+}
+
+bool ModuleListProperties::SetClangModulesCachePath(llvm::StringRef path) {
+ return m_collection_sp->SetPropertyAtIndexAsString(
+ nullptr, ePropertyClangModulesCachePath, path);
+}
+
+
ModuleList::ModuleList()
: m_modules(), m_modules_mutex(), m_notifier(nullptr) {}
@@ -83,8 +132,8 @@ const ModuleList &ModuleList::operator=(const ModuleList &rhs) {
// in thread A: | in thread B:
// x = y; | y = x;
//
- // This establishes correct(same) lock taking order and thus
- // avoids priority inversion.
+ // This establishes correct(same) lock taking order and thus avoids
+ // priority inversion.
if (uintptr_t(this) > uintptr_t(&rhs)) {
std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex);
std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_modules_mutex);
@@ -383,27 +432,26 @@ size_t ModuleList::FindCompileUnits(const FileSpec &path, bool append,
return sc_list.GetSize();
}
-size_t ModuleList::FindGlobalVariables(const ConstString &name, bool append,
+size_t ModuleList::FindGlobalVariables(const ConstString &name,
size_t max_matches,
VariableList &variable_list) const {
size_t initial_size = variable_list.GetSize();
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos) {
- (*pos)->FindGlobalVariables(name, nullptr, append, max_matches,
- variable_list);
+ (*pos)->FindGlobalVariables(name, nullptr, max_matches, variable_list);
}
return variable_list.GetSize() - initial_size;
}
size_t ModuleList::FindGlobalVariables(const RegularExpression &regex,
- bool append, size_t max_matches,
+ size_t max_matches,
VariableList &variable_list) const {
size_t initial_size = variable_list.GetSize();
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos) {
- (*pos)->FindGlobalVariables(regex, append, max_matches, variable_list);
+ (*pos)->FindGlobalVariables(regex, max_matches, variable_list);
}
return variable_list.GetSize() - initial_size;
}
@@ -496,8 +544,8 @@ ModuleList::FindTypes(const SymbolContext &sc, const ConstString &name,
size_t total_matches = 0;
collection::const_iterator pos, end = m_modules.end();
if (sc.module_sp) {
- // The symbol context "sc" contains a module so we want to search that
- // one first if it is in our list...
+ // The symbol context "sc" contains a module so we want to search that one
+ // first if it is in our list...
for (pos = m_modules.begin(); pos != end; ++pos) {
if (sc.module_sp.get() == (*pos).get()) {
total_matches +=
@@ -514,8 +562,8 @@ ModuleList::FindTypes(const SymbolContext &sc, const ConstString &name,
SymbolContext world_sc;
for (pos = m_modules.begin(); pos != end; ++pos) {
// Search the module if the module is not equal to the one in the symbol
- // context "sc". If "sc" contains a empty module shared pointer, then
- // the comparison will always be true (valid_module_ptr != nullptr).
+ // context "sc". If "sc" contains a empty module shared pointer, then the
+ // comparison will always be true (valid_module_ptr != nullptr).
if (sc.module_sp.get() != (*pos).get())
total_matches +=
(*pos)->FindTypes(world_sc, name, name_is_fully_qualified,
@@ -673,17 +721,32 @@ size_t ModuleList::GetIndexForModule(const Module *module) const {
return LLDB_INVALID_INDEX32;
}
-static ModuleList &GetSharedModuleList() {
- static ModuleList *g_shared_module_list = nullptr;
+namespace {
+struct SharedModuleListInfo {
+ ModuleList module_list;
+ ModuleListProperties module_list_properties;
+};
+}
+static SharedModuleListInfo &GetSharedModuleListInfo()
+{
+ static SharedModuleListInfo *g_shared_module_list_info = nullptr;
static llvm::once_flag g_once_flag;
llvm::call_once(g_once_flag, []() {
// NOTE: Intentionally leak the module list so a program doesn't have to
// cleanup all modules and object files as it exits. This just wastes time
// doing a bunch of cleanup that isn't required.
- if (g_shared_module_list == nullptr)
- g_shared_module_list = new ModuleList(); // <--- Intentional leak!!!
+ if (g_shared_module_list_info == nullptr)
+ g_shared_module_list_info = new SharedModuleListInfo();
});
- return *g_shared_module_list;
+ return *g_shared_module_list_info;
+}
+
+static ModuleList &GetSharedModuleList() {
+ return GetSharedModuleListInfo().module_list;
+}
+
+ModuleListProperties &ModuleList::GetGlobalModuleListProperties() {
+ return GetSharedModuleListInfo().module_list_properties;
}
bool ModuleList::ModuleIsInCache(const Module *module_ptr) {
@@ -727,8 +790,8 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec,
const ArchSpec &arch = module_spec.GetArchitecture();
// Make sure no one else can try and get or create a module while this
- // function is actively working on it by doing an extra lock on the
- // global mutex list.
+ // function is actively working on it by doing an extra lock on the global
+ // mutex list.
if (!always_create) {
ModuleList matching_module_list;
const size_t num_matching_modules =
@@ -751,8 +814,8 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec,
shared_module_list.Remove(module_sp);
module_sp.reset();
} else {
- // The module matches and the module was not modified from
- // when it was last loaded.
+ // The module matches and the module was not modified from when it
+ // was last loaded.
return error;
}
}
@@ -763,12 +826,12 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec,
return error;
module_sp.reset(new Module(module_spec));
- // Make sure there are a module and an object file since we can specify
- // a valid file path with an architecture that might not be in that file.
- // By getting the object file we can guarantee that the architecture matches
+ // Make sure there are a module and an object file since we can specify a
+ // valid file path with an architecture that might not be in that file. By
+ // getting the object file we can guarantee that the architecture matches
if (module_sp->GetObjectFile()) {
- // If we get in here we got the correct arch, now we just need
- // to verify the UUID if one was given
+ // If we get in here we got the correct arch, now we just need to verify
+ // the UUID if one was given
if (uuid_ptr && *uuid_ptr != module_sp->GetUUID()) {
module_sp.reset();
} else {
@@ -807,8 +870,8 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec,
resolved_module_spec.GetFileSpec() = search_path_spec;
module_sp.reset(new Module(resolved_module_spec));
if (module_sp->GetObjectFile()) {
- // If we get in here we got the correct arch, now we just need
- // to verify the UUID if one was given
+ // If we get in here we got the correct arch, now we just need to
+ // verify the UUID if one was given
if (uuid_ptr && *uuid_ptr != module_sp->GetUUID()) {
module_sp.reset();
} else {
@@ -833,8 +896,8 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec,
// we now have to use more extreme measures to try and find the appropriate
// module.
- // Fixup the incoming path in case the path points to a valid file, yet
- // the arch or UUID (if one was passed in) don't match.
+ // Fixup the incoming path in case the path points to a valid file, yet the
+ // arch or UUID (if one was passed in) don't match.
ModuleSpec located_binary_modulespec =
Symbols::LocateExecutableObjectFile(module_spec);
@@ -871,8 +934,8 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec,
}
// Make sure no one else can try and get or create a module while this
- // function is actively working on it by doing an extra lock on the
- // global mutex list.
+ // function is actively working on it by doing an extra lock on the global
+ // mutex list.
ModuleSpec platform_module_spec(module_spec);
platform_module_spec.GetFileSpec() =
located_binary_modulespec.GetFileSpec();
@@ -903,8 +966,8 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec,
if (!module_sp) {
module_sp.reset(new Module(platform_module_spec));
- // Make sure there are a module and an object file since we can specify
- // a valid file path with an architecture that might not be in that file.
+ // Make sure there are a module and an object file since we can specify a
+ // valid file path with an architecture that might not be in that file.
// By getting the object file we can guarantee that the architecture
// matches
if (module_sp && module_sp->GetObjectFile()) {
diff --git a/source/Core/Opcode.cpp b/source/Core/Opcode.cpp
index b4e691c1ddcd..d15fdb3b17be 100644
--- a/source/Core/Opcode.cpp
+++ b/source/Core/Opcode.cpp
@@ -52,8 +52,8 @@ int Opcode::Dump(Stream *s, uint32_t min_byte_width) {
break;
}
- // Add spaces to make sure bytes dispay comes out even in case opcodes
- // aren't all the same size
+ // Add spaces to make sure bytes dispay comes out even in case opcodes aren't
+ // all the same size
if (static_cast<uint32_t>(bytes_written) < min_byte_width)
bytes_written = s->Printf("%*s", min_byte_width - bytes_written, "");
return bytes_written;
diff --git a/source/Core/PluginManager.cpp b/source/Core/PluginManager.cpp
index a49fbc3f90fe..55affb6a1030 100644
--- a/source/Core/PluginManager.cpp
+++ b/source/Core/PluginManager.cpp
@@ -17,7 +17,7 @@
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StringList.h" // for StringList
-#if defined(LLVM_ON_WIN32)
+#if defined(_WIN32)
#include "lldb/Host/windows/PosixApi.h" // for PATH_MAX
#endif
@@ -96,8 +96,8 @@ LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
Status error;
namespace fs = llvm::sys::fs;
- // If we have a regular file, a symbolic link or unknown file type, try
- // and process the file. We must handle unknown as sometimes the directory
+ // If we have a regular file, a symbolic link or unknown file type, try and
+ // process the file. We must handle unknown as sometimes the directory
// enumeration might be enumerating a file system that doesn't have correct
// file type information.
if (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file ||
@@ -128,17 +128,14 @@ LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
plugin_info.library.getAddressOfSymbol("LLDBPluginTerminate"));
} else {
// The initialize function returned FALSE which means the plug-in
- // might not be
- // compatible, or might be too new or too old, or might not want to
- // run on this
- // machine. Set it to a default-constructed instance to invalidate
- // it.
+ // might not be compatible, or might be too new or too old, or might
+ // not want to run on this machine. Set it to a default-constructed
+ // instance to invalidate it.
plugin_info = PluginInfo();
}
- // Regardless of success or failure, cache the plug-in load
- // in our plug-in info so we don't try to load it again and
- // again.
+ // Regardless of success or failure, cache the plug-in load in our
+ // plug-in info so we don't try to load it again and again.
SetPluginInfo(plugin_file_spec, plugin_info);
return FileSpec::eEnumerateDirectoryResultNext;
@@ -148,9 +145,9 @@ LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
if (ft == fs::file_type::directory_file ||
ft == fs::file_type::symlink_file || ft == fs::file_type::type_unknown) {
- // 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 enumerating a file system that doesn't have correct file type
+ // 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
+ // enumerating a file system that doesn't have correct file type
// information.
return FileSpec::eEnumerateDirectoryResultEnter;
}
@@ -160,19 +157,18 @@ LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
void PluginManager::Initialize() {
#if 1
- FileSpec dir_spec;
const bool find_directories = true;
const bool find_files = true;
const bool find_other = true;
char dir_path[PATH_MAX];
- if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec)) {
+ if (FileSpec dir_spec = HostInfo::GetSystemPluginDir()) {
if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) {
FileSpec::EnumerateDirectory(dir_path, find_directories, find_files,
find_other, LoadPluginCallback, nullptr);
}
}
- if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec)) {
+ if (FileSpec dir_spec = HostInfo::GetUserPluginDir()) {
if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) {
FileSpec::EnumerateDirectory(dir_path, find_directories, find_files,
find_other, LoadPluginCallback, nullptr);
@@ -187,8 +183,8 @@ void PluginManager::Terminate() {
PluginTerminateMap::const_iterator pos, end = plugin_map.end();
for (pos = plugin_map.begin(); pos != end; ++pos) {
- // Call the plug-in "void LLDBPluginTerminate (void)" function if there
- // is one (if the symbol was not nullptr).
+ // Call the plug-in "void LLDBPluginTerminate (void)" function if there is
+ // one (if the symbol was not nullptr).
if (pos->second.library.isValid()) {
if (pos->second.plugin_term_callback)
pos->second.plugin_term_callback();
@@ -2397,8 +2393,8 @@ static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPlugins(
}
// This is deprecated way to register plugin specific settings. e.g.
-// "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME"
-// and Platform generic settings would be under "platform.SETTINGNAME".
+// "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" and Platform
+// generic settings would be under "platform.SETTINGNAME".
static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle(
Debugger &debugger, const ConstString &plugin_type_name,
const ConstString &plugin_type_desc, bool can_create) {
diff --git a/source/Core/RegisterValue.cpp b/source/Core/RegisterValue.cpp
index f64c14019cc6..4f908609dde9 100644
--- a/source/Core/RegisterValue.cpp
+++ b/source/Core/RegisterValue.cpp
@@ -9,9 +9,8 @@
#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/DumpDataExtractor.h"
#include "lldb/Core/Scalar.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/Stream.h"
@@ -34,67 +33,6 @@
using namespace lldb;
using namespace lldb_private;
-bool RegisterValue::Dump(Stream *s, const RegisterInfo *reg_info,
- bool prefix_with_name, bool prefix_with_alt_name,
- Format format,
- uint32_t reg_name_right_align_at) const {
- DataExtractor data;
- if (GetData(data)) {
- bool name_printed = false;
- // For simplicity, alignment of the register name printing applies only
- // in the most common case where:
- //
- // prefix_with_name^prefix_with_alt_name is true
- //
- StreamString format_string;
- if (reg_name_right_align_at && (prefix_with_name ^ prefix_with_alt_name))
- format_string.Printf("%%%us", reg_name_right_align_at);
- else
- format_string.Printf("%%s");
- std::string fmt = format_string.GetString();
- if (prefix_with_name) {
- if (reg_info->name) {
- s->Printf(fmt.c_str(), reg_info->name);
- name_printed = true;
- } else if (reg_info->alt_name) {
- s->Printf(fmt.c_str(), reg_info->alt_name);
- prefix_with_alt_name = false;
- name_printed = true;
- }
- }
- if (prefix_with_alt_name) {
- if (name_printed)
- s->PutChar('/');
- if (reg_info->alt_name) {
- s->Printf(fmt.c_str(), reg_info->alt_name);
- name_printed = true;
- } else if (!name_printed) {
- // No alternate name but we were asked to display a name, so show the
- // main name
- s->Printf(fmt.c_str(), reg_info->name);
- name_printed = true;
- }
- }
- if (name_printed)
- s->PutCString(" = ");
-
- if (format == eFormatDefault)
- format = reg_info->format;
-
- DumpDataExtractor(data, s,
- 0, // Offset in "data"
- format, // Format to use when dumping
- reg_info->byte_size, // item_byte_size
- 1, // item_count
- UINT32_MAX, // num_per_line
- LLDB_INVALID_ADDRESS, // base_addr
- 0, // item_bit_size
- 0); // item_bit_offset
- return true;
- }
- return false;
-}
-
bool RegisterValue::GetData(DataExtractor &data) const {
return data.SetData(GetBytes(), GetByteSize(), GetByteOrder()) > 0;
}
@@ -375,9 +313,9 @@ static bool ParseVectorEncoding(const RegisterInfo *reg_info,
std::vector<uint8_t> bytes;
unsigned byte = 0;
- // Using radix auto-sensing by passing 0 as the radix.
- // Keep on processing the vector elements as long as the parsing succeeds and
- // the vector size is < byte_size.
+ // Using radix auto-sensing by passing 0 as the radix. Keep on processing the
+ // vector elements as long as the parsing succeeds and the vector size is <
+ // byte_size.
while (!car.getAsInteger(0, byte) && bytes.size() < byte_size) {
bytes.push_back(byte);
std::tie(car, cdr) = cdr.split(Sep);
@@ -812,10 +750,9 @@ bool RegisterValue::SetUInt(uint64_t uint, uint32_t byte_size) {
void RegisterValue::SetBytes(const void *bytes, size_t length,
lldb::ByteOrder byte_order) {
- // If this assertion fires off we need to increase the size of
- // buffer.bytes, or make it something that is allocated on
- // the heap. Since the data buffer is in a union, we can't make it
- // a collection class like SmallVector...
+ // If this assertion fires off we need to increase the size of buffer.bytes,
+ // or make it something that is allocated on the heap. Since the data buffer
+ // is in a union, we can't make it a collection class like SmallVector...
if (bytes && length > 0) {
assert(length <= sizeof(buffer.bytes) &&
"Storing too many bytes in a RegisterValue.");
diff --git a/source/Core/Scalar.cpp b/source/Core/Scalar.cpp
index 630083bae930..6a7186969ef2 100644
--- a/source/Core/Scalar.cpp
+++ b/source/Core/Scalar.cpp
@@ -9,7 +9,6 @@
#include "lldb/Core/Scalar.h"
-#include "lldb/Host/StringConvert.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/Status.h"
@@ -25,8 +24,8 @@ using namespace lldb;
using namespace lldb_private;
//----------------------------------------------------------------------
-// Promote to max type currently follows the ANSI C rule for type
-// promotion in expressions.
+// Promote to max type currently follows the ANSI C rule for type promotion in
+// expressions.
//----------------------------------------------------------------------
static Scalar::Type PromoteToMaxType(
const Scalar &lhs, // The const left hand side object
@@ -41,10 +40,9 @@ static Scalar::Type PromoteToMaxType(
// lhs/rhs will get promoted)
) {
Scalar result;
- // Initialize the promoted values for both the right and left hand side values
- // to be the objects themselves. If no promotion is needed (both right and
- // left
- // have the same type), then the temp_value will not get used.
+ // Initialize the promoted values for both the right and left hand side
+ // values to be the objects themselves. If no promotion is needed (both right
+ // and left have the same type), then the temp_value will not get used.
promoted_lhs_ptr = &lhs;
promoted_rhs_ptr = &rhs;
// Extract the types of both the right and left hand side values
@@ -128,14 +126,13 @@ bool Scalar::GetData(DataExtractor &data, size_t limit_byte_size) const {
if (limit_byte_size < byte_size) {
if (endian::InlHostByteOrder() == eByteOrderLittle) {
- // On little endian systems if we want fewer bytes from the
- // current type we just specify fewer bytes since the LSByte
- // is first...
+ // On little endian systems if we want fewer bytes from the current
+ // type we just specify fewer bytes since the LSByte is first...
byte_size = limit_byte_size;
} else if (endian::InlHostByteOrder() == eByteOrderBig) {
- // On big endian systems if we want fewer bytes from the
- // current type have to advance our initial byte pointer and
- // trim down the number of bytes since the MSByte is first
+ // On big endian systems if we want fewer bytes from the current type
+ // have to advance our initial byte pointer and trim down the number of
+ // bytes since the MSByte is first
bytes += byte_size - limit_byte_size;
byte_size = limit_byte_size;
}
@@ -164,9 +161,8 @@ const void *Scalar::GetBytes() const {
case e_slonglong:
case e_ulonglong:
bytes = reinterpret_cast<const uint8_t *>(m_integer.getRawData());
- // getRawData always returns a pointer to an uint64_t. If we have a smaller
- // type,
- // we need to update the pointer on big-endian systems.
+ // getRawData always returns a pointer to an uint64_t. If we have a
+ // smaller type, we need to update the pointer on big-endian systems.
if (endian::InlHostByteOrder() == eByteOrderBig) {
size_t byte_size = m_integer.getBitWidth() / 8;
if (byte_size < 8)
@@ -491,20 +487,24 @@ bool Scalar::Promote(Scalar::Type type) {
break;
case e_float:
- m_float = llvm::APFloat(m_integer.bitsToFloat());
+ m_float = llvm::APFloat(llvm::APFloat::IEEEsingle());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
case e_double:
- m_float = llvm::APFloat(m_integer.bitsToDouble());
+ m_float = llvm::APFloat(llvm::APFloat::IEEEdouble());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
case e_long_double:
- if (m_ieee_quad)
- m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), m_integer);
- else
- m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), m_integer);
+ m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad()
+ : llvm::APFloat::x87DoubleExtended());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
}
@@ -551,20 +551,24 @@ bool Scalar::Promote(Scalar::Type type) {
break;
case e_float:
- m_float = llvm::APFloat(m_integer.bitsToFloat());
+ m_float = llvm::APFloat(llvm::APFloat::IEEEsingle());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
case e_double:
- m_float = llvm::APFloat(m_integer.bitsToDouble());
+ m_float = llvm::APFloat(llvm::APFloat::IEEEdouble());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
case e_long_double:
- if (m_ieee_quad)
- m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), m_integer);
- else
- m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), m_integer);
+ m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad()
+ : llvm::APFloat::x87DoubleExtended());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
}
@@ -607,20 +611,24 @@ bool Scalar::Promote(Scalar::Type type) {
break;
case e_float:
- m_float = llvm::APFloat(m_integer.bitsToFloat());
+ m_float = llvm::APFloat(llvm::APFloat::IEEEsingle());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
case e_double:
- m_float = llvm::APFloat(m_integer.bitsToDouble());
+ m_float = llvm::APFloat(llvm::APFloat::IEEEdouble());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
case e_long_double:
- if (m_ieee_quad)
- m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), m_integer);
- else
- m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), m_integer);
+ m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad()
+ : llvm::APFloat::x87DoubleExtended());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
}
@@ -659,20 +667,24 @@ bool Scalar::Promote(Scalar::Type type) {
break;
case e_float:
- m_float = llvm::APFloat(m_integer.bitsToFloat());
+ m_float = llvm::APFloat(llvm::APFloat::IEEEsingle());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
case e_double:
- m_float = llvm::APFloat(m_integer.bitsToDouble());
+ m_float = llvm::APFloat(llvm::APFloat::IEEEdouble());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
case e_long_double:
- if (m_ieee_quad)
- m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), m_integer);
- else
- m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), m_integer);
+ m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad()
+ : llvm::APFloat::x87DoubleExtended());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
}
@@ -707,20 +719,24 @@ bool Scalar::Promote(Scalar::Type type) {
break;
case e_float:
- m_float = llvm::APFloat(m_integer.bitsToFloat());
+ m_float = llvm::APFloat(llvm::APFloat::IEEEsingle());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
case e_double:
- m_float = llvm::APFloat(m_integer.bitsToDouble());
+ m_float = llvm::APFloat(llvm::APFloat::IEEEdouble());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
case e_long_double:
- if (m_ieee_quad)
- m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), m_integer);
- else
- m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), m_integer);
+ m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad()
+ : llvm::APFloat::x87DoubleExtended());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
}
@@ -751,20 +767,24 @@ bool Scalar::Promote(Scalar::Type type) {
break;
case e_float:
- m_float = llvm::APFloat(m_integer.bitsToFloat());
+ m_float = llvm::APFloat(llvm::APFloat::IEEEsingle());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
case e_double:
- m_float = llvm::APFloat(m_integer.bitsToDouble());
+ m_float = llvm::APFloat(llvm::APFloat::IEEEdouble());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
case e_long_double:
- if (m_ieee_quad)
- m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), m_integer);
- else
- m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), m_integer);
+ m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad()
+ : llvm::APFloat::x87DoubleExtended());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
}
@@ -795,20 +815,24 @@ bool Scalar::Promote(Scalar::Type type) {
break;
case e_float:
- m_float = llvm::APFloat(m_integer.bitsToFloat());
+ m_float = llvm::APFloat(llvm::APFloat::IEEEsingle());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
case e_double:
- m_float = llvm::APFloat(m_integer.bitsToDouble());
+ m_float = llvm::APFloat(llvm::APFloat::IEEEdouble());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
case e_long_double:
- if (m_ieee_quad)
- m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), m_integer);
- else
- m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), m_integer);
+ m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad()
+ : llvm::APFloat::x87DoubleExtended());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
}
@@ -835,20 +859,24 @@ bool Scalar::Promote(Scalar::Type type) {
break;
case e_float:
- m_float = llvm::APFloat(m_integer.bitsToFloat());
+ m_float = llvm::APFloat(llvm::APFloat::IEEEsingle());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
case e_double:
- m_float = llvm::APFloat(m_integer.bitsToDouble());
+ m_float = llvm::APFloat(llvm::APFloat::IEEEdouble());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
case e_long_double:
- if (m_ieee_quad)
- m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), m_integer);
- else
- m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), m_integer);
+ m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad()
+ : llvm::APFloat::x87DoubleExtended());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
}
@@ -875,20 +903,24 @@ bool Scalar::Promote(Scalar::Type type) {
break;
case e_float:
- m_float = llvm::APFloat(m_integer.bitsToFloat());
+ m_float = llvm::APFloat(llvm::APFloat::IEEEsingle());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
case e_double:
- m_float = llvm::APFloat(m_integer.bitsToDouble());
+ m_float = llvm::APFloat(llvm::APFloat::IEEEdouble());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
case e_long_double:
- if (m_ieee_quad)
- m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), m_integer);
- else
- m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), m_integer);
+ m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad()
+ : llvm::APFloat::x87DoubleExtended());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
}
@@ -911,20 +943,24 @@ bool Scalar::Promote(Scalar::Type type) {
success = true;
break;
case e_float:
- m_float = llvm::APFloat(m_integer.bitsToFloat());
+ m_float = llvm::APFloat(llvm::APFloat::IEEEsingle());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
case e_double:
- m_float = llvm::APFloat(m_integer.bitsToDouble());
+ m_float = llvm::APFloat(llvm::APFloat::IEEEdouble());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
case e_long_double:
- if (m_ieee_quad)
- m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), m_integer);
- else
- m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), m_integer);
+ m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad()
+ : llvm::APFloat::x87DoubleExtended());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
success = true;
break;
}
@@ -948,20 +984,19 @@ bool Scalar::Promote(Scalar::Type type) {
success = true;
break;
case e_double:
- m_float = llvm::APFloat((float_t)m_float.convertToFloat());
+ m_float = llvm::APFloat((double_t)m_float.convertToFloat());
success = true;
break;
- case e_long_double:
- if (m_ieee_quad)
- m_float =
- llvm::APFloat(llvm::APFloat::IEEEquad(), m_float.bitcastToAPInt());
- else
- m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(),
- m_float.bitcastToAPInt());
+ case e_long_double: {
+ bool ignore;
+ m_float.convert(m_ieee_quad ? llvm::APFloat::IEEEquad()
+ : llvm::APFloat::x87DoubleExtended(),
+ llvm::APFloat::rmNearestTiesToEven, &ignore);
success = true;
break;
}
+ }
break;
case e_double:
@@ -982,16 +1017,15 @@ bool Scalar::Promote(Scalar::Type type) {
case e_double:
success = true;
break;
- case e_long_double:
- if (m_ieee_quad)
- m_float =
- llvm::APFloat(llvm::APFloat::IEEEquad(), m_float.bitcastToAPInt());
- else
- m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(),
- m_float.bitcastToAPInt());
+ case e_long_double: {
+ bool ignore;
+ m_float.convert(m_ieee_quad ? llvm::APFloat::IEEEquad()
+ : llvm::APFloat::x87DoubleExtended(),
+ llvm::APFloat::rmNearestTiesToEven, &ignore);
success = true;
break;
}
+ }
break;
case e_long_double:
@@ -1088,253 +1122,6 @@ Scalar::Type Scalar::GetValueTypeForFloatWithByteSize(size_t byte_size) {
return e_void;
}
-bool Scalar::Cast(Scalar::Type type) {
- bool success = false;
- switch (m_type) {
- case e_void:
- break;
-
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256:
- switch (type) {
- case e_void:
- break;
- case e_sint:
- m_integer = m_integer.sextOrTrunc(sizeof(sint_t) * 8);
- success = true;
- break;
-
- case e_uint:
- m_integer = m_integer.zextOrTrunc(sizeof(sint_t) * 8);
- success = true;
- break;
-
- case e_slong:
- m_integer = m_integer.sextOrTrunc(sizeof(slong_t) * 8);
- success = true;
- break;
-
- case e_ulong:
- m_integer = m_integer.zextOrTrunc(sizeof(slong_t) * 8);
- success = true;
- break;
-
- case e_slonglong:
- m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8);
- success = true;
- break;
-
- case e_ulonglong:
- m_integer = m_integer.zextOrTrunc(sizeof(slonglong_t) * 8);
- success = true;
- break;
-
- case e_sint128:
- m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
- success = true;
- break;
-
- case e_uint128:
- m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
- success = true;
- break;
-
- case e_sint256:
- m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
- success = true;
- break;
-
- case e_uint256:
- m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
- success = true;
- break;
-
- case e_float:
- m_float = llvm::APFloat(m_integer.bitsToFloat());
- success = true;
- break;
-
- case e_double:
- m_float = llvm::APFloat(m_integer.bitsToDouble());
- success = true;
- break;
-
- case e_long_double:
- if (m_ieee_quad)
- m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), m_integer);
- else
- m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), m_integer);
- success = true;
- break;
- }
- break;
-
- case e_float:
- switch (type) {
- case e_void:
- break;
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256:
- m_integer = m_float.bitcastToAPInt();
- success = true;
- break;
- case e_float:
- m_float = llvm::APFloat(m_float.convertToFloat());
- success = true;
- break;
- case e_double:
- m_float = llvm::APFloat(m_float.convertToFloat());
- success = true;
- break;
- case e_long_double:
- if (m_ieee_quad)
- m_float =
- llvm::APFloat(llvm::APFloat::IEEEquad(), m_float.bitcastToAPInt());
- else
- m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(),
- m_float.bitcastToAPInt());
- success = true;
- break;
- }
- break;
-
- case e_double:
- switch (type) {
- case e_void:
- break;
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256:
- m_integer = m_float.bitcastToAPInt();
- success = true;
- break;
- case e_float:
- m_float = llvm::APFloat(m_float.convertToDouble());
- success = true;
- break;
- case e_double:
- m_float = llvm::APFloat(m_float.convertToDouble());
- success = true;
- break;
- case e_long_double:
- if (m_ieee_quad)
- m_float =
- llvm::APFloat(llvm::APFloat::IEEEquad(), m_float.bitcastToAPInt());
- else
- m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(),
- m_float.bitcastToAPInt());
- success = true;
- break;
- }
- break;
-
- case e_long_double:
- switch (type) {
- case e_void:
- break;
- case e_sint:
- m_integer = m_float.bitcastToAPInt();
- m_integer = m_integer.sextOrTrunc(sizeof(sint_t) * 8);
- success = true;
- break;
-
- case e_uint:
- m_integer = m_float.bitcastToAPInt();
- m_integer = m_integer.zextOrTrunc(sizeof(sint_t) * 8);
- success = true;
- break;
-
- case e_slong:
- m_integer = m_float.bitcastToAPInt();
- m_integer = m_integer.sextOrTrunc(sizeof(slong_t) * 8);
- success = true;
- break;
-
- case e_ulong:
- m_integer = m_float.bitcastToAPInt();
- m_integer = m_integer.zextOrTrunc(sizeof(slong_t) * 8);
- success = true;
- break;
-
- case e_slonglong:
- m_integer = m_float.bitcastToAPInt();
- m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8);
- success = true;
- break;
-
- case e_ulonglong:
- m_integer = m_float.bitcastToAPInt();
- m_integer = m_integer.zextOrTrunc(sizeof(slonglong_t) * 8);
- success = true;
- break;
-
- case e_sint128:
- m_integer = m_float.bitcastToAPInt();
- m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
- success = true;
- break;
-
- case e_uint128:
- m_integer = m_float.bitcastToAPInt();
- m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
- success = true;
- break;
-
- case e_sint256:
- m_integer = m_float.bitcastToAPInt();
- m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
- success = true;
- break;
-
- case e_uint256:
- m_integer = m_float.bitcastToAPInt();
- m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
- success = true;
- break;
-
- case e_float:
- m_float = llvm::APFloat(m_float.convertToFloat());
- success = true;
- break;
- case e_double:
- m_float = llvm::APFloat(m_float.convertToFloat());
- success = true;
- break;
- case e_long_double:
- success = true;
- break;
- }
- break;
- }
-
- if (success)
- m_type = type;
- return success;
-}
-
bool Scalar::MakeSigned() {
bool success = false;
@@ -1397,38 +1184,38 @@ bool Scalar::MakeUnsigned() {
case e_void:
break;
case e_sint:
+ m_type = e_uint;
success = true;
break;
case e_uint:
- m_type = e_uint;
success = true;
break;
case e_slong:
+ m_type = e_ulong;
success = true;
break;
case e_ulong:
- m_type = e_ulong;
success = true;
break;
case e_slonglong:
+ m_type = e_ulonglong;
success = true;
break;
case e_ulonglong:
- m_type = e_ulonglong;
success = true;
break;
case e_sint128:
+ m_type = e_uint128;
success = true;
break;
case e_uint128:
- m_type = e_uint128;
success = true;
break;
case e_sint256:
+ m_type = e_uint256;
success = true;
break;
case e_uint256:
- m_type = e_uint256;
success = true;
break;
case e_float:
@@ -1819,7 +1606,7 @@ float Scalar::Float(float fail_value) const {
case e_uint128:
case e_sint256:
case e_uint256:
- return m_integer.bitsToFloat();
+ return llvm::APIntOps::RoundAPIntToFloat(m_integer);
case e_float:
return m_float.convertToFloat();
case e_double:
@@ -1845,7 +1632,7 @@ double Scalar::Double(double fail_value) const {
case e_uint128:
case e_sint256:
case e_uint256:
- return m_integer.bitsToDouble();
+ return llvm::APIntOps::RoundAPIntToDouble(m_integer);
case e_float:
return (double_t)m_float.convertToFloat();
case e_double:
@@ -1871,7 +1658,7 @@ long double Scalar::LongDouble(long double fail_value) const {
case e_uint128:
case e_sint256:
case e_uint256:
- return (long_double_t)m_integer.bitsToDouble();
+ return (long_double_t)llvm::APIntOps::RoundAPIntToDouble(m_integer);
case e_float:
return (long_double_t)m_float.convertToFloat();
case e_double:
@@ -2266,7 +2053,7 @@ const Scalar lldb_private::operator/(const Scalar &lhs, const Scalar &rhs) {
case Scalar::e_float:
case Scalar::e_double:
case Scalar::e_long_double:
- if (b->m_float.isZero()) {
+ if (!b->m_float.isZero()) {
result.m_float = a->m_float / b->m_float;
return result;
}
@@ -2274,8 +2061,7 @@ const Scalar lldb_private::operator/(const Scalar &lhs, const Scalar &rhs) {
}
}
// For division only, the only way it should make it here is if a promotion
- // failed,
- // or if we are trying to do a divide by zero.
+ // failed, or if we are trying to do a divide by zero.
result.m_type = Scalar::e_void;
return result;
}
@@ -2467,17 +2253,15 @@ Status Scalar::SetValueFromCString(const char *value_str, Encoding encoding,
error.SetErrorString("Invalid c-string value string.");
return error;
}
- bool success = false;
switch (encoding) {
case eEncodingInvalid:
error.SetErrorString("Invalid encoding.");
break;
case eEncodingUint:
- if (byte_size <= sizeof(unsigned long long)) {
- uint64_t uval64 =
- StringConvert::ToUInt64(value_str, UINT64_MAX, 0, &success);
- if (!success)
+ if (byte_size <= sizeof(uint64_t)) {
+ uint64_t uval64;
+ if (!llvm::to_integer(value_str, uval64))
error.SetErrorStringWithFormat(
"'%s' is not a valid unsigned integer string value", value_str);
else if (!UIntValueIsValidForSize(uval64, byte_size))
@@ -2513,10 +2297,9 @@ Status Scalar::SetValueFromCString(const char *value_str, Encoding encoding,
break;
case eEncodingSint:
- if (byte_size <= sizeof(long long)) {
- uint64_t sval64 =
- StringConvert::ToSInt64(value_str, INT64_MAX, 0, &success);
- if (!success)
+ if (byte_size <= sizeof(int64_t)) {
+ int64_t sval64;
+ if (!llvm::to_integer(value_str, sval64))
error.SetErrorStringWithFormat(
"'%s' is not a valid signed integer string value", value_str);
else if (!SIntValueIsValidForSize(sval64, byte_size))
diff --git a/source/Core/Section.cpp b/source/Core/Section.cpp
index c9faf9f89157..d9c5d32ee13c 100644
--- a/source/Core/Section.cpp
+++ b/source/Core/Section.cpp
@@ -27,8 +27,8 @@ class DataExtractor;
using namespace lldb;
using namespace lldb_private;
-static const char *GetSectionTypeAsCString(lldb::SectionType sect_type) {
- switch (sect_type) {
+const char *Section::GetTypeAsCString() const {
+ switch (m_type) {
case eSectionTypeInvalid:
return "invalid";
case eSectionTypeCode:
@@ -89,6 +89,10 @@ static const char *GetSectionTypeAsCString(lldb::SectionType sect_type) {
return "dwarf-str";
case eSectionTypeDWARFDebugStrOffsets:
return "dwarf-str-offsets";
+ case eSectionTypeDWARFDebugTypes:
+ return "dwarf-types";
+ case eSectionTypeDWARFDebugNames:
+ return "dwarf-names";
case eSectionTypeELFSymbolTable:
return "elf-symbol-table";
case eSectionTypeELFDynamicSymbols:
@@ -117,6 +121,8 @@ static const char *GetSectionTypeAsCString(lldb::SectionType sect_type) {
return "go-symtab";
case eSectionTypeAbsoluteAddress:
return "absolute";
+ case eSectionTypeDWARFGNUDebugAltLink:
+ return "dwarf-gnu-debugaltlink";
case eSectionTypeOther:
return "regular";
}
@@ -175,9 +181,9 @@ Section::~Section() {
addr_t Section::GetFileAddress() const {
SectionSP parent_sp(GetParent());
if (parent_sp) {
- // This section has a parent which means m_file_addr is an offset into
- // the parent section, so the file address for this section is the file
- // address of the parent plus the offset
+ // This section has a parent which means m_file_addr is an offset into the
+ // parent section, so the file address for this section is the file address
+ // of the parent plus the offset
return parent_sp->GetFileAddress() + m_file_addr;
}
// This section has no parent, so m_file_addr is the file base address
@@ -283,8 +289,7 @@ int Section::Compare(const Section &a, const Section &b) {
void Section::Dump(Stream *s, Target *target, uint32_t depth) const {
// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
s->Indent();
- s->Printf("0x%8.8" PRIx64 " %-16s ", GetID(),
- GetSectionTypeAsCString(m_type));
+ s->Printf("0x%8.8" PRIx64 " %-16s ", GetID(), GetTypeAsCString());
bool resolved = true;
addr_t addr = LLDB_INVALID_ADDRESS;
@@ -326,10 +331,11 @@ void Section::DumpName(Stream *s) const {
// The top most section prints the module basename
const char *name = NULL;
ModuleSP module_sp(GetModule());
- const FileSpec &file_spec = m_obj_file->GetFileSpec();
- if (m_obj_file)
+ if (m_obj_file) {
+ const FileSpec &file_spec = m_obj_file->GetFileSpec();
name = file_spec.GetFilename().AsCString();
+ }
if ((!name || !name[0]) && module_sp)
name = module_sp->GetFileSpec().GetFilename().AsCString();
if (name && name[0])
@@ -556,10 +562,8 @@ SectionSP SectionList::FindSectionContainingFileAddress(addr_t vm_addr,
Section *sect = sect_iter->get();
if (sect->ContainsFileAddress(vm_addr)) {
// The file address is in this section. We need to make sure one of our
- // child
- // sections doesn't contain this address as well as obeying the depth
- // limit
- // that was passed in.
+ // child sections doesn't contain this address as well as obeying the
+ // depth limit that was passed in.
if (depth > 0)
sect_sp = sect->GetChildren().FindSectionContainingFileAddress(
vm_addr, depth - 1);
diff --git a/source/Core/SourceManager.cpp b/source/Core/SourceManager.cpp
index b284ff1dbaaa..a6afd64f3054 100644
--- a/source/Core/SourceManager.cpp
+++ b/source/Core/SourceManager.cpp
@@ -109,8 +109,8 @@ static bool should_show_stop_column_with_ansi(DebuggerSP debugger_sp) {
if (!debugger_sp)
return false;
- // We don't use ANSI stop column formatting if the debugger doesn't think
- // it should be using color.
+ // We don't use ANSI stop column formatting if the debugger doesn't think it
+ // should be using color.
if (!debugger_sp->GetUseColor())
return false;
@@ -128,8 +128,8 @@ static bool should_show_stop_column_with_caret(DebuggerSP debugger_sp) {
if (!debugger_sp)
return false;
- // If we're asked to show the first available of ANSI or caret, then
- // we do show the caret when ANSI is not available.
+ // If we're asked to show the first available of ANSI or caret, then we do
+ // show the caret when ANSI is not available.
const auto value = debugger_sp->GetStopShowColumn();
if ((value == eStopShowColumnAnsiOrCaret) && !debugger_sp->GetUseColor())
return true;
@@ -255,9 +255,9 @@ size_t SourceManager::DisplayMoreWithLineNumbers(
if (m_last_line > 0) {
if (reverse) {
- // If this is the first time we've done a reverse, then back up one more
- // time so we end
- // up showing the chunk before the last one we've shown:
+ // If this is the first time we've done a reverse, then back up one
+ // more time so we end up showing the chunk before the last one we've
+ // shown:
if (m_last_line > m_last_count)
m_last_line -= m_last_count;
else
@@ -299,10 +299,9 @@ bool SourceManager::GetDefaultFileAndLine(FileSpec &file_spec, uint32_t &line) {
if (target_sp) {
// If nobody has set the default file and line then try here. If there's
- // no executable, then we
- // will try again later when there is one. Otherwise, if we can't find it
- // we won't look again,
- // somebody will have to set it (for instance when we stop somewhere...)
+ // no executable, then we will try again later when there is one.
+ // Otherwise, if we can't find it we won't look again, somebody will have
+ // to set it (for instance when we stop somewhere...)
Module *executable_ptr = target_sp->GetExecutableModulePointer();
if (executable_ptr) {
SymbolContextList sc_list;
@@ -410,9 +409,7 @@ void SourceManager::File::CommonInitializer(const FileSpec &file_spec,
FileSpec new_file_spec;
// Check target specific source remappings first, then fall back to
// modules objects can have individual path remappings that were
- // detected
- // when the debug info for a module was found.
- // then
+ // detected when the debug info for a module was found. then
if (target->GetSourcePathMap().FindFile(m_file_spec, new_file_spec) ||
target->GetImages().FindSourceFile(m_file_spec, new_file_spec)) {
m_file_spec = new_file_spec;
@@ -538,8 +535,8 @@ size_t SourceManager::File::DisplaySourceLines(uint32_t line, uint32_t column,
if (column && (column < count)) {
auto debugger_sp = m_debugger_wp.lock();
if (should_show_stop_column_with_ansi(debugger_sp) && debugger_sp) {
- // Check if we have any ANSI codes with which to mark this column.
- // If not, no need to do this work.
+ // Check if we have any ANSI codes with which to mark this column. If
+ // not, no need to do this work.
auto ansi_prefix_entry = debugger_sp->GetStopShowColumnAnsiPrefix();
auto ansi_suffix_entry = debugger_sp->GetStopShowColumnAnsiSuffix();
diff --git a/source/Core/Value.cpp b/source/Core/Value.cpp
index d415f1b09eb7..254c9008babb 100644
--- a/source/Core/Value.cpp
+++ b/source/Core/Value.cpp
@@ -365,11 +365,10 @@ Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
if (process == NULL || !process->IsAlive()) {
Target *target = exe_ctx->GetTargetPtr();
if (target) {
- // Allow expressions to run and evaluate things when the target
- // has memory sections loaded. This allows you to use "target modules
- // load"
- // to load your executable and any shared libraries, then execute
- // commands where you can look at types in data sections.
+ // Allow expressions to run and evaluate things when the target has
+ // memory sections loaded. This allows you to use "target modules
+ // load" to load your executable and any shared libraries, then
+ // execute commands where you can look at types in data sections.
const SectionLoadList &target_sections = target->GetSectionLoadList();
if (!target_sections.IsEmpty()) {
address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
@@ -406,8 +405,8 @@ Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
error.SetErrorString("invalid file address");
} else {
if (module == NULL) {
- // The only thing we can currently lock down to a module so that
- // we can resolve a file address, is a variable.
+ // The only thing we can currently lock down to a module so that we
+ // can resolve a file address, is a variable.
Variable *variable = GetVariable();
if (variable) {
SymbolContext var_sc;
@@ -541,12 +540,11 @@ Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
} else if ((address_type == eAddressTypeLoad) ||
(address_type == eAddressTypeFile)) {
if (file_so_addr.IsValid()) {
- // We have a file address that we were able to translate into a
- // section offset address so we might be able to read this from
- // the object files if we don't have a live process. Lets always
- // try and read from the process if we have one though since we
- // want to read the actual value by setting "prefer_file_cache"
- // to false.
+ // We have a file address that we were able to translate into a section
+ // offset address so we might be able to read this from the object
+ // files if we don't have a live process. Lets always try and read from
+ // the process if we have one though since we want to read the actual
+ // value by setting "prefer_file_cache" to false.
const bool prefer_file_cache = false;
if (exe_ctx->GetTargetRef().ReadMemory(file_so_addr, prefer_file_cache,
dst, byte_size,
@@ -555,10 +553,10 @@ Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
"read memory from 0x%" PRIx64 " failed", (uint64_t)address);
}
} else {
- // The execution context might have a NULL process, but it
- // might have a valid process in the exe_ctx->target, so use
- // the ExecutionContext::GetProcess accessor to ensure we
- // get the process if there is one.
+ // The execution context might have a NULL process, but it might have a
+ // valid process in the exe_ctx->target, so use the
+ // ExecutionContext::GetProcess accessor to ensure we get the process
+ // if there is one.
Process *process = exe_ctx->GetProcessPtr();
if (process) {
@@ -671,6 +669,25 @@ const char *Value::GetContextTypeAsCString(ContextType context_type) {
return "???";
}
+void Value::ConvertToLoadAddress(Module *module, Target *target) {
+ if (!module || !target || (GetValueType() != eValueTypeFileAddress))
+ return;
+
+ lldb::addr_t file_addr = GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+ if (file_addr == LLDB_INVALID_ADDRESS)
+ return;
+
+ Address so_addr;
+ if (!module->ResolveFileAddress(file_addr, so_addr))
+ return;
+ lldb::addr_t load_addr = so_addr.GetLoadAddress(target);
+ if (load_addr == LLDB_INVALID_ADDRESS)
+ return;
+
+ SetValueType(Value::eValueTypeLoadAddress);
+ GetScalar() = load_addr;
+}
+
ValueList::ValueList(const ValueList &rhs) { m_values = rhs.m_values; }
const ValueList &ValueList::operator=(const ValueList &rhs) {
diff --git a/source/Core/ValueObject.cpp b/source/Core/ValueObject.cpp
index c09139fe2b09..244ea2936fb4 100644
--- a/source/Core/ValueObject.cpp
+++ b/source/Core/ValueObject.cpp
@@ -19,6 +19,7 @@
#include "lldb/Core/ValueObjectMemory.h"
#include "lldb/Core/ValueObjectSyntheticFilter.h"
#include "lldb/DataFormatters/DataVisualization.h"
+#include "lldb/DataFormatters/DumpValueObjectOptions.h" // for DumpValueObj...
#include "lldb/DataFormatters/FormatManager.h" // for FormatManager
#include "lldb/DataFormatters/StringPrinter.h"
#include "lldb/DataFormatters/TypeFormat.h" // for TypeFormatImpl_F...
@@ -146,16 +147,15 @@ bool ValueObject::UpdateValueIfNeeded(bool update_format) {
if (update_format)
did_change_formats = UpdateFormatsIfNeeded();
- // If this is a constant value, then our success is predicated on whether
- // we have an error or not
+ // If this is a constant value, then our success is predicated on whether we
+ // have an error or not
if (GetIsConstant()) {
// if you are constant, things might still have changed behind your back
// (e.g. you are a frozen object and things have changed deeper than you
- // cared to freeze-dry yourself)
- // in this case, your value has not changed, but "computed" entries might
- // have, so you might now have
- // a different summary, or a different object description. clear these so we
- // will recompute them
+ // cared to freeze-dry yourself) in this case, your value has not changed,
+ // but "computed" entries might have, so you might now have a different
+ // summary, or a different object description. clear these so we will
+ // recompute them
if (update_format && !did_change_formats)
ClearUserVisibleData(eClearUserVisibleDataItemsSummary |
eClearUserVisibleDataItemsDescription);
@@ -167,8 +167,8 @@ bool ValueObject::UpdateValueIfNeeded(bool update_format) {
if (NeedsUpdating()) {
m_update_point.SetUpdated();
- // Save the old value using swap to avoid a string copy which
- // also will clear our m_value_str
+ // Save the old value using swap to avoid a string copy which also will
+ // clear our m_value_str
if (m_value_str.empty()) {
m_old_value_valid = false;
} else {
@@ -215,8 +215,8 @@ bool ValueObject::UpdateValueIfNeeded(bool update_format) {
if (first_update)
SetValueDidChange(false);
else if (!m_value_did_change && success == false) {
- // The value wasn't gotten successfully, so we mark this
- // as changed if the value used to be valid and now isn't
+ // The value wasn't gotten successfully, so we mark this as changed if
+ // the value used to be valid and now isn't
SetValueDidChange(value_was_valid);
} else if (need_compare_checksums) {
SetValueDidChange(memcmp(&old_checksum[0], &m_value_checksum[0],
@@ -261,8 +261,7 @@ bool ValueObject::UpdateFormatsIfNeeded() {
void ValueObject::SetNeedsUpdate() {
m_update_point.SetNeedsUpdate();
// We have to clear the value string here so ConstResult children will notice
- // if their values are
- // changed by hand (i.e. with SetValueAsCString).
+ // if their values are changed by hand (i.e. with SetValueAsCString).
ClearUserVisibleData(eClearUserVisibleDataItemsValue);
}
@@ -556,9 +555,9 @@ size_t ValueObject::GetIndexOfChildWithName(const ConstString &name) {
ValueObjectSP ValueObject::GetChildMemberWithName(const ConstString &name,
bool can_create) {
- // when getting a child by name, it could be buried inside some base
- // classes (which really aren't part of the expression path), so we
- // need a vector of indexes that can get us down to the correct child
+ // when getting a child by name, it could be buried inside some base classes
+ // (which really aren't part of the expression path), so we need a vector of
+ // indexes that can get us down to the correct child
ValueObjectSP child_sp;
// We may need to update our value if we are dynamic
@@ -682,8 +681,8 @@ bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr,
const TypeSummaryOptions &options) {
destination.clear();
- // ideally we would like to bail out if passing NULL, but if we do so
- // we end up not providing the summary for function pointers anymore
+ // ideally we would like to bail out if passing NULL, but if we do so we end
+ // up not providing the summary for function pointers anymore
if (/*summary_ptr == NULL ||*/ m_is_getting_summary)
return false;
@@ -695,9 +694,8 @@ bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr,
actual_options.SetLanguage(GetPreferredDisplayLanguage());
// this is a hot path in code and we prefer to avoid setting this string all
- // too often also clearing out other
- // information that we might care to see in a crash log. might be useful in
- // very specific situations though.
+ // too often also clearing out other information that we might care to see in
+ // a crash log. might be useful in very specific situations though.
/*Host::SetCrashDescriptionWithFormat("Trying to fetch a summary for %s %s.
Summary provider's description is %s",
GetTypeName().GetCString(),
@@ -925,7 +923,8 @@ bool ValueObject::SetData(DataExtractor &data, Status &error) {
break;
}
- // If we have reached this point, then we have successfully changed the value.
+ // If we have reached this point, then we have successfully changed the
+ // value.
SetNeedsUpdate();
return true;
}
@@ -1010,9 +1009,9 @@ ValueObject::ReadPointedString(lldb::DataBufferSP &buffer_sp, Status &error,
DataExtractor data;
if (cstr_len > 0 && honor_array) {
// I am using GetPointeeData() here to abstract the fact that some
- // ValueObjects are actually frozen pointers in the host
- // but the pointed-to data lives in the debuggee, and GetPointeeData()
- // automatically takes care of this
+ // ValueObjects are actually frozen pointers in the host but the pointed-
+ // to data lives in the debuggee, and GetPointeeData() automatically
+ // takes care of this
GetPointeeData(data, 0, cstr_len);
if ((bytes_read = data.GetByteSize()) > 0) {
@@ -1031,9 +1030,9 @@ ValueObject::ReadPointedString(lldb::DataBufferSP &buffer_sp, Status &error,
int cstr_len_displayed = -1;
bool capped_cstr = false;
// I am using GetPointeeData() here to abstract the fact that some
- // ValueObjects are actually frozen pointers in the host
- // but the pointed-to data lives in the debuggee, and GetPointeeData()
- // automatically takes care of this
+ // ValueObjects are actually frozen pointers in the host but the pointed-
+ // to data lives in the debuggee, and GetPointeeData() automatically
+ // takes care of this
while ((bytes_read = GetPointeeData(data, offset, k_max_buf_size)) > 0) {
total_bytes_read += bytes_read;
const char *cstr = data.PeekCStr(0);
@@ -1175,8 +1174,8 @@ const char *ValueObject::GetValueAsCString() {
format_sp.reset(new TypeFormatImpl_Format(my_format));
if (GetValueAsCString(*format_sp.get(), m_value_str)) {
if (!m_value_did_change && m_old_value_valid) {
- // The value was gotten successfully, so we consider the
- // value as changed if the value string differs
+ // The value was gotten successfully, so we consider the value as
+ // changed if the value string differs
SetValueDidChange(m_old_value_str != m_value_str);
}
}
@@ -1187,8 +1186,8 @@ const char *ValueObject::GetValueAsCString() {
return m_value_str.c_str();
}
-// if > 8bytes, 0 is returned. this method should mostly be used
-// to read address values out of pointers
+// if > 8bytes, 0 is returned. this method should mostly be used to read
+// address values out of pointers
uint64_t ValueObject::GetValueAsUnsigned(uint64_t fail_value, bool *success) {
// If our byte size is zero this is an aggregate type that has children
if (CanProvideValue()) {
@@ -1224,10 +1223,9 @@ int64_t ValueObject::GetValueAsSigned(int64_t fail_value, bool *success) {
}
// if any more "special cases" are added to
-// ValueObject::DumpPrintableRepresentation() please keep
-// this call up to date by returning true for your new special cases. We will
-// eventually move
-// to checking this call result before trying to display special cases
+// ValueObject::DumpPrintableRepresentation() please keep this call up to date
+// by returning true for your new special cases. We will eventually move to
+// checking this call result before trying to display special cases
bool ValueObject::HasSpecialPrintableRepresentation(
ValueObjectRepresentationStyle val_obj_display, Format custom_format) {
Flags flags(GetTypeInfo());
@@ -1276,8 +1274,7 @@ bool ValueObject::DumpPrintableRepresentation(
if (flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) {
// when being asked to get a printable display an array or pointer type
- // directly,
- // try to "do the right thing"
+ // directly, try to "do the right thing"
if (IsCStringContainer(true) &&
(custom_format == eFormatCString ||
@@ -1309,8 +1306,8 @@ bool ValueObject::DumpPrintableRepresentation(
if (custom_format == eFormatEnum)
return false;
- // this only works for arrays, because I have no way to know when
- // the pointed memory ends, and no special \0 end of data marker
+ // this only works for arrays, because I have no way to know when the
+ // pointed memory ends, and no special \0 end of data marker
if (flags.Test(eTypeIsArray)) {
if ((custom_format == eFormatBytes) ||
(custom_format == eFormatBytesWithASCII)) {
@@ -1406,8 +1403,8 @@ bool ValueObject::DumpPrintableRepresentation(
llvm::StringRef str;
// this is a local stream that we are using to ensure that the data pointed
- // to by cstr survives long enough for us to copy it to its destination - it
- // is necessary to have this temporary storage area for cases where our
+ // to by cstr survives long enough for us to copy it to its destination -
+ // it is necessary to have this temporary storage area for cases where our
// desired output is not backed by some other longer-term storage
StreamString strm;
@@ -1485,9 +1482,9 @@ bool ValueObject::DumpPrintableRepresentation(
s.PutCString("<no printable representation>");
}
- // we should only return false here if we could not do *anything*
- // even if we have an error message as output, that's a success
- // from our callers' perspective, so return true
+ // we should only return false here if we could not do *anything* even if
+ // we have an error message as output, that's a success from our callers'
+ // perspective, so return true
var_success = true;
if (custom_format != eFormatInvalid)
@@ -1590,9 +1587,8 @@ bool ValueObject::SetValueFromCString(const char *value_str, Status &error) {
switch (value_type) {
case Value::eValueTypeLoadAddress: {
// If it is a load address, then the scalar value is the storage
- // location
- // of the data, and we have to shove this value down to that load
- // location.
+ // location of the data, and we have to shove this value down to that
+ // load location.
ExecutionContext exe_ctx(GetExecutionContextRef());
Process *process = exe_ctx.GetProcessPtr();
if (process) {
@@ -1639,7 +1635,8 @@ bool ValueObject::SetValueFromCString(const char *value_str, Status &error) {
return false;
}
- // If we have reached this point, then we have successfully changed the value.
+ // If we have reached this point, then we have successfully changed the
+ // value.
SetNeedsUpdate();
return true;
}
@@ -1734,16 +1731,14 @@ bool ValueObject::IsUninitializedReference() {
return false;
}
-// This allows you to create an array member using and index
-// that doesn't not fall in the normal bounds of the array.
-// Many times structure can be defined as:
-// struct Collection
-// {
+// This allows you to create an array member using and index that doesn't not
+// fall in the normal bounds of the array. Many times structure can be defined
+// as: struct Collection {
// uint32_t item_count;
// Item item_array[0];
// };
-// The size of the "item_array" is 1, but many times in practice
-// there are more items in "item_array".
+// The size of the "item_array" is 1, but many times in practice there are more
+// items in "item_array".
ValueObjectSP ValueObject::GetSyntheticArrayMember(size_t index,
bool can_create) {
@@ -1752,13 +1747,13 @@ ValueObjectSP ValueObject::GetSyntheticArrayMember(size_t index,
char index_str[64];
snprintf(index_str, sizeof(index_str), "[%" PRIu64 "]", (uint64_t)index);
ConstString index_const_str(index_str);
- // Check if we have already created a synthetic array member in this
- // valid object. If we have we will re-use it.
+ // Check if we have already created a synthetic array member in this valid
+ // object. If we have we will re-use it.
synthetic_child_sp = GetSyntheticChild(index_const_str);
if (!synthetic_child_sp) {
ValueObject *synthetic_child;
- // We haven't made a synthetic array member for INDEX yet, so
- // lets make one and cache it for any future reference.
+ // We haven't made a synthetic array member for INDEX yet, so lets make
+ // one and cache it for any future reference.
synthetic_child = CreateChildAtIndex(0, true, index);
// Cache the value if we got one back...
@@ -1780,8 +1775,8 @@ ValueObjectSP ValueObject::GetSyntheticBitFieldChild(uint32_t from, uint32_t to,
char index_str[64];
snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to);
ConstString index_const_str(index_str);
- // Check if we have already created a synthetic array member in this
- // valid object. If we have we will re-use it.
+ // Check if we have already created a synthetic array member in this valid
+ // object. If we have we will re-use it.
synthetic_child_sp = GetSyntheticChild(index_const_str);
if (!synthetic_child_sp) {
uint32_t bit_field_size = to - from + 1;
@@ -1789,8 +1784,8 @@ ValueObjectSP ValueObject::GetSyntheticBitFieldChild(uint32_t from, uint32_t to,
if (GetDataExtractor().GetByteOrder() == eByteOrderBig)
bit_field_offset =
GetByteSize() * 8 - bit_field_size - bit_field_offset;
- // We haven't made a synthetic array member for INDEX yet, so
- // lets make one and cache it for any future reference.
+ // We haven't made a synthetic array member for INDEX yet, so lets make
+ // one and cache it for any future reference.
ValueObjectChild *synthetic_child = new ValueObjectChild(
*this, GetCompilerType(), index_const_str, GetByteSize(), 0,
bit_field_size, bit_field_offset, false, false, eAddressTypeInvalid,
@@ -1820,8 +1815,8 @@ ValueObjectSP ValueObject::GetSyntheticChildAtOffset(
name_const_str.SetCString(name_str);
}
- // Check if we have already created a synthetic array member in this
- // valid object. If we have we will re-use it.
+ // Check if we have already created a synthetic array member in this valid
+ // object. If we have we will re-use it.
synthetic_child_sp = GetSyntheticChild(name_const_str);
if (synthetic_child_sp.get())
@@ -1858,8 +1853,8 @@ ValueObjectSP ValueObject::GetSyntheticBase(uint32_t offset,
name_const_str.SetCString(name_str);
}
- // Check if we have already created a synthetic array member in this
- // valid object. If we have we will re-use it.
+ // Check if we have already created a synthetic array member in this valid
+ // object. If we have we will re-use it.
synthetic_child_sp = GetSyntheticChild(name_const_str);
if (synthetic_child_sp.get())
@@ -1884,11 +1879,10 @@ ValueObjectSP ValueObject::GetSyntheticBase(uint32_t offset,
return synthetic_child_sp;
}
-// your expression path needs to have a leading . or ->
-// (unless it somehow "looks like" an array, in which case it has
-// a leading [ symbol). while the [ is meaningful and should be shown
-// to the user, . and -> are just parser design, but by no means
-// added information for the user.. strip them off
+// your expression path needs to have a leading . or -> (unless it somehow
+// "looks like" an array, in which case it has a leading [ symbol). while the [
+// is meaningful and should be shown to the user, . and -> are just parser
+// design, but by no means added information for the user.. strip them off
static const char *SkipLeadingExpressionPathSeparators(const char *expression) {
if (!expression || !expression[0])
return expression;
@@ -1904,12 +1898,12 @@ ValueObject::GetSyntheticExpressionPathChild(const char *expression,
bool can_create) {
ValueObjectSP synthetic_child_sp;
ConstString name_const_string(expression);
- // Check if we have already created a synthetic array member in this
- // valid object. If we have we will re-use it.
+ // Check if we have already created a synthetic array member in this valid
+ // object. If we have we will re-use it.
synthetic_child_sp = GetSyntheticChild(name_const_string);
if (!synthetic_child_sp) {
- // We haven't made a synthetic array member for expression yet, so
- // lets make one and cache it for any future reference.
+ // We haven't made a synthetic array member for expression yet, so lets
+ // make one and cache it for any future reference.
synthetic_child_sp = GetValueForExpressionPath(
expression, NULL, NULL,
GetValueForExpressionPathOptions().SetSyntheticChildrenTraversal(
@@ -2055,10 +2049,9 @@ bool ValueObject::IsBaseClass(uint32_t &depth) {
void ValueObject::GetExpressionPath(Stream &s, bool qualify_cxx_base_classes,
GetExpressionPathFormat epformat) {
// synthetic children do not actually "exist" as part of the hierarchy, and
- // sometimes they are consed up in ways
- // that don't make sense from an underlying language/API standpoint. So, use a
- // special code path here to return
- // something that can hopefully be used in expression
+ // sometimes they are consed up in ways that don't make sense from an
+ // underlying language/API standpoint. So, use a special code path here to
+ // return something that can hopefully be used in expression
if (m_is_synthetic_children_generated) {
UpdateValueIfNeeded();
@@ -2092,11 +2085,10 @@ void ValueObject::GetExpressionPath(Stream &s, bool qualify_cxx_base_classes,
if (is_deref_of_parent &&
epformat == eGetExpressionPathFormatDereferencePointers) {
// this is the original format of GetExpressionPath() producing code like
- // *(a_ptr).memberName, which is entirely
- // fine, until you put this into
+ // *(a_ptr).memberName, which is entirely fine, until you put this into
// StackFrame::GetValueForVariableExpressionPath() which prefers to see
- // a_ptr->memberName.
- // the eHonorPointers mode is meant to produce strings in this latter format
+ // a_ptr->memberName. the eHonorPointers mode is meant to produce strings
+ // in this latter format
s.PutCString("*(");
}
@@ -2105,9 +2097,9 @@ void ValueObject::GetExpressionPath(Stream &s, bool qualify_cxx_base_classes,
if (parent)
parent->GetExpressionPath(s, qualify_cxx_base_classes, epformat);
- // if we are a deref_of_parent just because we are synthetic array
- // members made up to allow ptr[%d] syntax to work in variable
- // printing, then add our name ([%d]) to the expression path
+ // if we are a deref_of_parent just because we are synthetic array members
+ // made up to allow ptr[%d] syntax to work in variable printing, then add our
+ // name ([%d]) to the expression path
if (m_is_array_item_for_pointer &&
epformat == eGetExpressionPathFormatHonorPointers)
s.PutCString(m_name.AsCString());
@@ -2355,8 +2347,8 @@ ValueObjectSP ValueObject::GetValueForExpressionPath_Impl(
}
// if we are here and options.m_no_synthetic_children is true,
- // child_valobj_sp is going to be a NULL SP,
- // so we hit the "else" branch, and return an error
+ // child_valobj_sp is going to be a NULL SP, so we hit the "else"
+ // branch, and return an error
if (child_valobj_sp.get()) // if it worked, just return
{
*reason_to_stop =
@@ -2424,8 +2416,8 @@ ValueObjectSP ValueObject::GetValueForExpressionPath_Impl(
}
// if we are here and options.m_no_synthetic_children is true,
- // child_valobj_sp is going to be a NULL SP,
- // so we hit the "else" branch, and return an error
+ // child_valobj_sp is going to be a NULL SP, so we hit the "else"
+ // branch, and return an error
if (child_valobj_sp.get()) // if it worked, move on
{
root = child_valobj_sp;
@@ -2506,8 +2498,8 @@ ValueObjectSP ValueObject::GetValueForExpressionPath_Impl(
assert(!bracket_expr.empty());
if (!bracket_expr.contains('-')) {
- // if no separator, this is of the form [N]. Note that this cannot
- // be an unbounded range of the form [], because that case was handled
+ // if no separator, this is of the form [N]. Note that this cannot be
+ // an unbounded range of the form [], because that case was handled
// above with an unconditional return.
unsigned long index = 0;
if (bracket_expr.getAsInteger(0, index)) {
@@ -2631,8 +2623,8 @@ ValueObjectSP ValueObject::GetValueForExpressionPath_Impl(
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
return nullptr;
}
- // if we are here, then root itself is a synthetic VO.. should be good
- // to go
+ // if we are here, then root itself is a synthetic VO.. should be
+ // good to go
if (!root) {
*reason_to_stop =
@@ -3031,20 +3023,17 @@ ValueObject::EvaluationPoint::EvaluationPoint(
ValueObject::EvaluationPoint::~EvaluationPoint() {}
// This function checks the EvaluationPoint against the current process state.
-// If the current
-// state matches the evaluation point, or the evaluation point is already
-// invalid, then we return
-// false, meaning "no change". If the current state is different, we update our
-// state, and return
-// true meaning "yes, change". If we did see a change, we also set
-// m_needs_update to true, so
-// future calls to NeedsUpdate will return true.
-// exe_scope will be set to the current execution context scope.
+// If the current state matches the evaluation point, or the evaluation point
+// is already invalid, then we return false, meaning "no change". If the
+// current state is different, we update our state, and return true meaning
+// "yes, change". If we did see a change, we also set m_needs_update to true,
+// so future calls to NeedsUpdate will return true. exe_scope will be set to
+// the current execution context scope.
bool ValueObject::EvaluationPoint::SyncWithProcessState(
bool accept_invalid_exe_ctx) {
- // Start with the target, if it is NULL, then we're obviously not going to get
- // any further:
+ // Start with the target, if it is NULL, then we're obviously not going to
+ // get any further:
const bool thread_and_frame_only_if_stopped = true;
ExecutionContext exe_ctx(
m_exe_ctx_ref.Lock(thread_and_frame_only_if_stopped));
@@ -3061,8 +3050,8 @@ bool ValueObject::EvaluationPoint::SyncWithProcessState(
ProcessModID current_mod_id = process->GetModID();
// If the current stop id is 0, either we haven't run yet, or the process
- // state has been cleared.
- // In either case, we aren't going to be able to sync with the process state.
+ // state has been cleared. In either case, we aren't going to be able to sync
+ // with the process state.
if (current_mod_id.GetStopID() == 0)
return false;
@@ -3070,8 +3059,8 @@ bool ValueObject::EvaluationPoint::SyncWithProcessState(
const bool was_valid = m_mod_id.IsValid();
if (was_valid) {
if (m_mod_id == current_mod_id) {
- // Everything is already up to date in this object, no need to
- // update the execution context scope.
+ // Everything is already up to date in this object, no need to update the
+ // execution context scope.
changed = false;
} else {
m_mod_id = current_mod_id;
@@ -3081,10 +3070,9 @@ bool ValueObject::EvaluationPoint::SyncWithProcessState(
}
// Now re-look up the thread and frame in case the underlying objects have
- // gone away & been recreated.
- // That way we'll be sure to return a valid exe_scope.
- // If we used to have a thread or a frame but can't find it anymore, then mark
- // ourselves as invalid.
+ // gone away & been recreated. That way we'll be sure to return a valid
+ // exe_scope. If we used to have a thread or a frame but can't find it
+ // anymore, then mark ourselves as invalid.
if (!accept_invalid_exe_ctx) {
if (m_exe_ctx_ref.HasThreadRef()) {
@@ -3299,11 +3287,9 @@ void ValueObject::SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType lt) {
}
bool ValueObject::CanProvideValue() {
- // we need to support invalid types as providers of values because some
- // bare-board
- // debugging scenarios have no notion of types, but still manage to have raw
- // numeric
- // values for things like registers. sigh.
+ // we need to support invalid types as providers of values because some bare-
+ // board debugging scenarios have no notion of types, but still manage to
+ // have raw numeric values for things like registers. sigh.
const CompilerType &type(GetCompilerType());
return (false == type.IsValid()) ||
(0 != (type.GetTypeInfo() & eTypeHasValue));
@@ -3326,7 +3312,9 @@ ValueObjectSP ValueObject::Persist() {
if (!persistent_state)
return nullptr;
- ConstString name(persistent_state->GetNextPersistentVariableName());
+ auto prefix = persistent_state->GetPersistentVariablePrefix();
+ ConstString name =
+ persistent_state->GetNextPersistentVariableName(*target_sp, prefix);
ValueObjectSP const_result_sp =
ValueObjectConstResult::Create(target_sp.get(), GetValue(), name);
diff --git a/source/Core/ValueObjectCast.cpp b/source/Core/ValueObjectCast.cpp
index a489bdc74f5f..e0978f692bc5 100644
--- a/source/Core/ValueObjectCast.cpp
+++ b/source/Core/ValueObjectCast.cpp
@@ -71,9 +71,9 @@ bool ValueObjectCast::UpdateValue() {
m_value.SetCompilerType(compiler_type);
SetAddressTypeOfChildren(m_parent->GetAddressTypeOfChildren());
if (!CanProvideValue()) {
- // this value object represents an aggregate type whose
- // children have values, but this object does not. So we
- // say we are changed if our location has changed.
+ // this value object represents an aggregate type whose children have
+ // values, but this object does not. So we say we are changed if our
+ // location has changed.
SetValueDidChange(m_value.GetValueType() != old_value.GetValueType() ||
m_value.GetScalar() != old_value.GetScalar());
}
diff --git a/source/Core/ValueObjectChild.cpp b/source/Core/ValueObjectChild.cpp
index 591bc21711ae..019daa2fd3d2 100644
--- a/source/Core/ValueObjectChild.cpp
+++ b/source/Core/ValueObjectChild.cpp
@@ -172,8 +172,8 @@ bool ValueObjectChild::UpdateValue() {
} else if (addr == 0) {
m_error.SetErrorString("parent is NULL");
} else {
- // Set this object's scalar value to the address of its
- // value by adding its byte offset to the parent address
+ // Set this object's scalar value to the address of its value by
+ // adding its byte offset to the parent address
m_value.GetScalar() += GetByteOffset();
}
} break;
diff --git a/source/Core/ValueObjectDynamicValue.cpp b/source/Core/ValueObjectDynamicValue.cpp
index 0013d0dbf740..e9b48310b0c6 100644
--- a/source/Core/ValueObjectDynamicValue.cpp
+++ b/source/Core/ValueObjectDynamicValue.cpp
@@ -122,8 +122,8 @@ bool ValueObjectDynamicValue::UpdateValue() {
return false;
}
- // Setting our type_sp to NULL will route everything back through our
- // parent which is equivalent to not using dynamic values.
+ // Setting our type_sp to NULL will route everything back through our parent
+ // which is equivalent to not using dynamic values.
if (m_use_dynamic == lldb::eNoDynamicValues) {
m_dynamic_type_info.Clear();
return true;
@@ -173,8 +173,7 @@ bool ValueObjectDynamicValue::UpdateValue() {
}
// Getting the dynamic value may have run the program a bit, and so marked us
- // as needing updating, but we really
- // don't...
+ // as needing updating, but we really don't...
m_update_point.SetUpdated();
@@ -192,8 +191,8 @@ bool ValueObjectDynamicValue::UpdateValue() {
}
// If we don't have a dynamic type, then make ourselves just a echo of our
- // parent.
- // Or we could return false, and make ourselves an echo of our parent?
+ // parent. Or we could return false, and make ourselves an echo of our
+ // parent?
if (!found_dynamic_type) {
if (m_dynamic_type_info)
SetValueDidChange(true);
@@ -248,14 +247,14 @@ bool ValueObjectDynamicValue::UpdateValue() {
static_cast<void *>(this), GetTypeName().GetCString());
if (m_address.IsValid() && m_dynamic_type_info) {
- // The variable value is in the Scalar value inside the m_value.
- // We can point our m_data right to it.
+ // The variable value is in the Scalar value inside the m_value. We can
+ // point our m_data right to it.
m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
if (m_error.Success()) {
if (!CanProvideValue()) {
- // this value object represents an aggregate type whose
- // children have values, but this object does not. So we
- // say we are changed if our location has changed.
+ // this value object represents an aggregate type whose children have
+ // values, but this object does not. So we say we are changed if our
+ // location has changed.
SetValueDidChange(m_value.GetValueType() != old_value.GetValueType() ||
m_value.GetScalar() != old_value.GetScalar());
}
@@ -287,13 +286,11 @@ bool ValueObjectDynamicValue::SetValueFromCString(const char *value_str,
return false;
}
- // if we are at an offset from our parent, in order to set ourselves correctly
- // we would need
- // to change the new value so that it refers to the correct dynamic type. we
- // choose not to deal
- // with that - if anything more than a value overwrite is required, you should
- // be using the
- // expression parser instead of the value editing facility
+ // if we are at an offset from our parent, in order to set ourselves
+ // correctly we would need to change the new value so that it refers to the
+ // correct dynamic type. we choose not to deal with that - if anything more
+ // than a value overwrite is required, you should be using the expression
+ // parser instead of the value editing facility
if (my_value != parent_value) {
// but NULL'ing out a value should always be allowed
if (strcmp(value_str, "0")) {
@@ -322,13 +319,11 @@ bool ValueObjectDynamicValue::SetData(DataExtractor &data, Status &error) {
return false;
}
- // if we are at an offset from our parent, in order to set ourselves correctly
- // we would need
- // to change the new value so that it refers to the correct dynamic type. we
- // choose not to deal
- // with that - if anything more than a value overwrite is required, you should
- // be using the
- // expression parser instead of the value editing facility
+ // if we are at an offset from our parent, in order to set ourselves
+ // correctly we would need to change the new value so that it refers to the
+ // correct dynamic type. we choose not to deal with that - if anything more
+ // than a value overwrite is required, you should be using the expression
+ // parser instead of the value editing facility
if (my_value != parent_value) {
// but NULL'ing out a value should always be allowed
lldb::offset_t offset = 0;
diff --git a/source/Core/ValueObjectList.cpp b/source/Core/ValueObjectList.cpp
index 00aee798c0e3..0dd07252888f 100644
--- a/source/Core/ValueObjectList.cpp
+++ b/source/Core/ValueObjectList.cpp
@@ -87,8 +87,8 @@ ValueObjectSP ValueObjectList::FindValueObjectByUID(lldb::user_id_t uid) {
collection::iterator pos, end = m_value_objects.end();
for (pos = m_value_objects.begin(); pos != end; ++pos) {
- // Watch out for NULL objects in our list as the list
- // might get resized to a specific size and lazily filled in
+ // Watch out for NULL objects in our list as the list might get resized to
+ // a specific size and lazily filled in
ValueObject *valobj = (*pos).get();
if (valobj && valobj->GetID() == uid) {
valobj_sp = *pos;
diff --git a/source/Core/ValueObjectMemory.cpp b/source/Core/ValueObjectMemory.cpp
index e26900014c9d..3e71fea6bb35 100644
--- a/source/Core/ValueObjectMemory.cpp
+++ b/source/Core/ValueObjectMemory.cpp
@@ -165,21 +165,20 @@ bool ValueObjectMemory::UpdateValue() {
llvm_unreachable("Unhandled expression result value kind...");
case Value::eValueTypeScalar:
- // The variable value is in the Scalar value inside the m_value.
- // We can point our m_data right to it.
+ // The variable value is in the Scalar value inside the m_value. We can
+ // point our m_data right to it.
m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
break;
case Value::eValueTypeFileAddress:
case Value::eValueTypeLoadAddress:
case Value::eValueTypeHostAddress:
- // The DWARF expression result was an address in the inferior
- // process. If this variable is an aggregate type, we just need
- // the address as the main value as all child variable objects
- // will rely upon this location and add an offset and then read
- // their own values as needed. If this variable is a simple
- // type, we read all data for it into m_data.
- // Make sure this type has a value before we try and read it
+ // The DWARF expression result was an address in the inferior process. If
+ // this variable is an aggregate type, we just need the address as the
+ // main value as all child variable objects will rely upon this location
+ // and add an offset and then read their own values as needed. If this
+ // variable is a simple type, we read all data for it into m_data. Make
+ // sure this type has a value before we try and read it
// If we have a file address, convert it to a load address if we can.
if (value_type == Value::eValueTypeFileAddress &&
@@ -192,14 +191,14 @@ bool ValueObjectMemory::UpdateValue() {
}
if (!CanProvideValue()) {
- // this value object represents an aggregate type whose
- // children have values, but this object does not. So we
- // say we are changed if our location has changed.
+ // this value object represents an aggregate type whose children have
+ // values, but this object does not. So we say we are changed if our
+ // location has changed.
SetValueDidChange(value_type != old_value.GetValueType() ||
m_value.GetScalar() != old_value.GetScalar());
} else {
- // Copy the Value and set the context to use our Variable
- // so it can extract read its value into m_data appropriately
+ // Copy the Value and set the context to use our Variable so it can
+ // extract read its value into m_data appropriately
Value value(m_value);
if (m_type_sp)
value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get());
diff --git a/source/Core/ValueObjectSyntheticFilter.cpp b/source/Core/ValueObjectSyntheticFilter.cpp
index 87310c423cb8..044387a4ae12 100644
--- a/source/Core/ValueObjectSyntheticFilter.cpp
+++ b/source/Core/ValueObjectSyntheticFilter.cpp
@@ -129,7 +129,19 @@ lldb::ValueType ValueObjectSynthetic::GetValueType() const {
}
void ValueObjectSynthetic::CreateSynthFilter() {
- m_synth_filter_ap = (m_synth_sp->GetFrontEnd(*m_parent));
+ ValueObject *valobj_for_frontend = m_parent;
+ if (m_synth_sp->WantsDereference())
+ {
+ CompilerType type = m_parent->GetCompilerType();
+ if (type.IsValid() && type.IsPointerOrReferenceType())
+ {
+ Status error;
+ lldb::ValueObjectSP deref_sp = m_parent->Dereference(error);
+ if (error.Success())
+ valobj_for_frontend = deref_sp.get();
+ }
+ }
+ m_synth_filter_ap = (m_synth_sp->GetFrontEnd(*valobj_for_frontend));
if (!m_synth_filter_ap.get())
m_synth_filter_ap = llvm::make_unique<DummySyntheticFrontEnd>(*m_parent);
}
@@ -171,10 +183,9 @@ bool ValueObjectSynthetic::UpdateValue() {
m_children_byindex.Clear();
m_name_toindex.Clear();
// usually, an object's value can change but this does not alter its
- // children count
- // for a synthetic VO that might indeed happen, so we need to tell the upper
- // echelons
- // that they need to come back to us asking for children
+ // children count for a synthetic VO that might indeed happen, so we need
+ // to tell the upper echelons that they need to come back to us asking for
+ // children
m_children_count_valid = false;
m_synthetic_children_cache.Clear();
m_synthetic_children_count = UINT32_MAX;
diff --git a/source/Core/ValueObjectVariable.cpp b/source/Core/ValueObjectVariable.cpp
index 8436ba529a54..bfe5c3de7fbf 100644
--- a/source/Core/ValueObjectVariable.cpp
+++ b/source/Core/ValueObjectVariable.cpp
@@ -175,9 +175,8 @@ bool ValueObjectVariable::UpdateValue() {
switch (value_type) {
case Value::eValueTypeFileAddress:
// If this type is a pointer, then its children will be considered load
- // addresses
- // if the pointer or reference is dereferenced, but only if the process
- // is alive.
+ // addresses if the pointer or reference is dereferenced, but only if
+ // the process is alive.
//
// There could be global variables like in the following code:
// struct LinkedListNode { Foo* foo; LinkedListNode* next; };
@@ -187,14 +186,11 @@ bool ValueObjectVariable::UpdateValue() {
// LinkedListNode g_first_node = { &g_foo1, &g_second_node };
//
// When we aren't running, we should be able to look at these variables
- // using
- // the "target variable" command. Children of the "g_first_node" always
- // will
- // be of the same address type as the parent. But children of the "next"
- // member of
- // LinkedListNode will become load addresses if we have a live process,
- // or remain
- // what a file address if it what a file address.
+ // using the "target variable" command. Children of the "g_first_node"
+ // always will be of the same address type as the parent. But children
+ // of the "next" member of LinkedListNode will become load addresses if
+ // we have a live process, or remain what a file address if it what a
+ // file address.
if (process_is_alive && is_pointer_or_ref)
SetAddressTypeOfChildren(eAddressTypeLoad);
else
@@ -202,12 +198,10 @@ bool ValueObjectVariable::UpdateValue() {
break;
case Value::eValueTypeHostAddress:
// Same as above for load addresses, except children of pointer or refs
- // are always
- // load addresses. Host addresses are used to store freeze dried
- // variables. If this
- // type is a struct, the entire struct contents will be copied into the
- // heap of the
- // LLDB process, but we do not currrently follow any pointers.
+ // are always load addresses. Host addresses are used to store freeze
+ // dried variables. If this type is a struct, the entire struct
+ // contents will be copied into the heap of the
+ // LLDB process, but we do not currently follow any pointers.
if (is_pointer_or_ref)
SetAddressTypeOfChildren(eAddressTypeLoad);
else
@@ -224,8 +218,8 @@ bool ValueObjectVariable::UpdateValue() {
case Value::eValueTypeVector:
// fall through
case Value::eValueTypeScalar:
- // The variable value is in the Scalar value inside the m_value.
- // We can point our m_data right to it.
+ // The variable value is in the Scalar value inside the m_value. We can
+ // point our m_data right to it.
m_error =
m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
break;
@@ -233,44 +227,26 @@ bool ValueObjectVariable::UpdateValue() {
case Value::eValueTypeFileAddress:
case Value::eValueTypeLoadAddress:
case Value::eValueTypeHostAddress:
- // The DWARF expression result was an address in the inferior
- // process. If this variable is an aggregate type, we just need
- // the address as the main value as all child variable objects
- // will rely upon this location and add an offset and then read
- // their own values as needed. If this variable is a simple
- // type, we read all data for it into m_data.
- // Make sure this type has a value before we try and read it
+ // The DWARF expression result was an address in the inferior process.
+ // If this variable is an aggregate type, we just need the address as
+ // the main value as all child variable objects will rely upon this
+ // location and add an offset and then read their own values as needed.
+ // If this variable is a simple type, we read all data for it into
+ // m_data. Make sure this type has a value before we try and read it
// If we have a file address, convert it to a load address if we can.
- if (value_type == Value::eValueTypeFileAddress && process_is_alive) {
- lldb::addr_t file_addr =
- m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
- if (file_addr != LLDB_INVALID_ADDRESS) {
- SymbolContext var_sc;
- variable->CalculateSymbolContext(&var_sc);
- if (var_sc.module_sp) {
- ObjectFile *objfile = var_sc.module_sp->GetObjectFile();
- if (objfile) {
- Address so_addr(file_addr, objfile->GetSectionList());
- lldb::addr_t load_addr = so_addr.GetLoadAddress(target);
- if (load_addr != LLDB_INVALID_ADDRESS) {
- m_value.SetValueType(Value::eValueTypeLoadAddress);
- m_value.GetScalar() = load_addr;
- }
- }
- }
- }
- }
+ if (value_type == Value::eValueTypeFileAddress && process_is_alive)
+ m_value.ConvertToLoadAddress(GetModule().get(), target);
if (!CanProvideValue()) {
- // this value object represents an aggregate type whose
- // children have values, but this object does not. So we
- // say we are changed if our location has changed.
+ // this value object represents an aggregate type whose children have
+ // values, but this object does not. So we say we are changed if our
+ // location has changed.
SetValueDidChange(value_type != old_value.GetValueType() ||
m_value.GetScalar() != old_value.GetScalar());
} else {
- // Copy the Value and set the context to use our Variable
- // so it can extract read its value into m_data appropriately
+ // Copy the Value and set the context to use our Variable so it can
+ // extract read its value into m_data appropriately
Value value(m_value);
value.SetContext(Value::eContextTypeVariable, variable);
m_error =
@@ -299,14 +275,13 @@ bool ValueObjectVariable::IsInScope() {
if (frame) {
return m_variable_sp->IsInScope(frame);
} else {
- // This ValueObject had a frame at one time, but now we
- // can't locate it, so return false since we probably aren't
- // in scope.
+ // This ValueObject had a frame at one time, but now we can't locate it,
+ // so return false since we probably aren't in scope.
return false;
}
}
- // We have a variable that wasn't tied to a frame, which
- // means it is a global and is always in scope.
+ // We have a variable that wasn't tied to a frame, which means it is a global
+ // and is always in scope.
return true;
}
diff --git a/source/DataFormatters/FormatManager.cpp b/source/DataFormatters/FormatManager.cpp
index 7619b6f6f82b..bafee1799b80 100644
--- a/source/DataFormatters/FormatManager.cpp
+++ b/source/DataFormatters/FormatManager.cpp
@@ -494,8 +494,8 @@ bool FormatManager::ShouldPrintAsOneLiner(ValueObject &valobj) {
if (valobj.GetNumChildren() == 0)
return false;
- // ask the type if it has any opinion about this
- // eLazyBoolCalculate == no opinion; other values should be self explanatory
+ // ask the type if it has any opinion about this eLazyBoolCalculate == no
+ // opinion; other values should be self explanatory
CompilerType compiler_type(valobj.GetCompilerType());
if (compiler_type.IsValid()) {
switch (compiler_type.ShouldPrintAsOneLiner(&valobj)) {
@@ -532,8 +532,7 @@ bool FormatManager::ShouldPrintAsOneLiner(ValueObject &valobj) {
}
// if we decided to define synthetic children for a type, we probably care
- // enough
- // to show them, but avoid nesting children in children
+ // enough to show them, but avoid nesting children in children
if (child_sp->GetSyntheticChildren().get() != nullptr) {
ValueObjectSP synth_sp(child_sp->GetSyntheticValue());
// wait.. wat? just get out of here..
diff --git a/source/DataFormatters/StringPrinter.cpp b/source/DataFormatters/StringPrinter.cpp
index 84143a541087..89d7a95069ca 100644
--- a/source/DataFormatters/StringPrinter.cpp
+++ b/source/DataFormatters/StringPrinter.cpp
@@ -26,9 +26,8 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-// we define this for all values of type but only implement it for those we care
-// about
-// that's good because we get linker errors for any unsupported type
+// we define this for all values of type but only implement it for those we
+// care about that's good because we get linker errors for any unsupported type
template <lldb_private::formatters::StringPrinter::StringElementType type>
static StringPrinter::StringPrinterBufferPointer<>
GetPrintableImpl(uint8_t *buffer, uint8_t *buffer_end, uint8_t *&next);
@@ -163,8 +162,8 @@ GetPrintableImpl<StringPrinter::StringElementType::UTF8>(uint8_t *buffer,
(unsigned char)*(buffer + 2), (unsigned char)*(buffer + 3));
break;
default:
- // this is probably some bogus non-character thing
- // just print it as-is and hope to sync up again soon
+ // this is probably some bogus non-character thing just print it as-is and
+ // hope to sync up again soon
retval = {buffer, 1};
next = buffer + 1;
return retval;
@@ -223,9 +222,9 @@ GetPrintableImpl<StringPrinter::StringElementType::UTF8>(uint8_t *buffer,
return retval;
}
-// Given a sequence of bytes, this function returns:
-// a sequence of bytes to actually print out + a length
-// the following unscanned position of the buffer is in next
+// Given a sequence of bytes, this function returns: a sequence of bytes to
+// actually print out + a length the following unscanned position of the buffer
+// is in next
static StringPrinter::StringPrinterBufferPointer<>
GetPrintable(StringPrinter::StringElementType type, uint8_t *buffer,
uint8_t *buffer_end, uint8_t *&next) {
@@ -321,8 +320,7 @@ static bool DumpUTFBufferToStream(
(llvm::UTF8 *)utf8_data_buffer_sp->GetBytes();
} else {
// just copy the pointers - the cast is necessary to make the compiler
- // happy
- // but this should only happen if we are reading UTF8 data
+ // happy but this should only happen if we are reading UTF8 data
utf8_data_ptr = const_cast<llvm::UTF8 *>(
reinterpret_cast<const llvm::UTF8 *>(data_ptr));
utf8_data_end_ptr = const_cast<llvm::UTF8 *>(
@@ -344,8 +342,8 @@ static bool DumpUTFBufferToStream(
}
// since we tend to accept partial data (and even partially malformed data)
- // we might end up with no NULL terminator before the end_ptr
- // hence we need to take a slower route and ensure we stay within boundaries
+ // we might end up with no NULL terminator before the end_ptr hence we need
+ // to take a slower route and ensure we stay within boundaries
for (; utf8_data_ptr < utf8_data_end_ptr;) {
if (zero_is_terminator && !*utf8_data_ptr)
break;
@@ -472,8 +470,8 @@ bool StringPrinter::ReadStringAndDumpToStream<
}
// since we tend to accept partial data (and even partially malformed data)
- // we might end up with no NULL terminator before the end_ptr
- // hence we need to take a slower route and ensure we stay within boundaries
+ // we might end up with no NULL terminator before the end_ptr hence we need
+ // to take a slower route and ensure we stay within boundaries
for (uint8_t *data = buffer_sp->GetBytes(); *data && (data < data_end);) {
if (escape_non_printables) {
uint8_t *next_data = nullptr;
diff --git a/source/DataFormatters/TypeFormat.cpp b/source/DataFormatters/TypeFormat.cpp
index 333fe91b76db..7902ccb47771 100644
--- a/source/DataFormatters/TypeFormat.cpp
+++ b/source/DataFormatters/TypeFormat.cpp
@@ -111,12 +111,12 @@ bool TypeFormatImpl_Format::FormatObject(ValueObject *valobj,
valobj->GetBitfieldBitSize(), // Bitfield bit size
valobj->GetBitfieldBitOffset(), // Bitfield bit offset
exe_scope);
- // Given that we do not want to set the ValueObject's m_error
- // for a formatting error (or else we wouldn't be able to reformat
- // until a next update), an empty string is treated as a "false"
- // return from here, but that's about as severe as we get
- // CompilerType::DumpTypeValue() should always return
- // something, even if that something is an error message
+ // Given that we do not want to set the ValueObject's m_error for a
+ // formatting error (or else we wouldn't be able to reformat until a
+ // next update), an empty string is treated as a "false" return from
+ // here, but that's about as severe as we get
+ // CompilerType::DumpTypeValue() should always return something, even
+ // if that something is an error message
dest = sstr.GetString();
}
}
diff --git a/source/DataFormatters/ValueObjectPrinter.cpp b/source/DataFormatters/ValueObjectPrinter.cpp
index 863ff3af12e8..43e91a2b6c92 100644
--- a/source/DataFormatters/ValueObjectPrinter.cpp
+++ b/source/DataFormatters/ValueObjectPrinter.cpp
@@ -244,8 +244,8 @@ void ValueObjectPrinter::PrintDecl() {
// always show the type at the root level if it is invalid
if (show_type) {
- // Some ValueObjects don't have types (like registers sets). Only print
- // the type if there is one to print
+ // Some ValueObjects don't have types (like registers sets). Only print the
+ // type if there is one to print
ConstString type_name;
if (m_compiler_type.IsValid()) {
if (m_options.m_use_type_display_name)
@@ -402,12 +402,10 @@ bool ValueObjectPrinter::PrintValueAndSummaryIfNeeded(bool &value_printed,
}
if (m_error.size()) {
// we need to support scenarios in which it is actually fine for a value
- // to have no type
- // but - on the other hand - if we get an error *AND* have no type, we try
- // to get out
- // gracefully, since most often that combination means "could not resolve
- // a type"
- // and the default failure mode is quite ugly
+ // to have no type but - on the other hand - if we get an error *AND*
+ // have no type, we try to get out gracefully, since most often that
+ // combination means "could not resolve a type" and the default failure
+ // mode is quite ugly
if (!m_compiler_type.IsValid()) {
m_stream->Printf(" <could not resolve type>");
return false;
@@ -416,10 +414,10 @@ bool ValueObjectPrinter::PrintValueAndSummaryIfNeeded(bool &value_printed,
error_printed = true;
m_stream->Printf(" <%s>\n", m_error.c_str());
} else {
- // Make sure we have a value and make sure the summary didn't
- // specify that the value should not be printed - and do not print
- // the value if this thing is nil
- // (but show the value if the user passes a format explicitly)
+ // Make sure we have a value and make sure the summary didn't specify
+ // that the value should not be printed - and do not print the value if
+ // this thing is nil (but show the value if the user passes a format
+ // explicitly)
TypeSummaryImpl *entry = GetSummaryFormatter();
if (!IsNil() && !IsUninitialized() && !m_value.empty() &&
(entry == NULL || (entry->DoesPrintValue(m_valobj) ||
@@ -494,8 +492,8 @@ bool ValueObjectPrinter::ShouldPrintChildren(
if (is_uninit)
return false;
- // if the user has specified an element count, always print children
- // as it is explicit user demand being honored
+ // if the user has specified an element count, always print children as it is
+ // explicit user demand being honored
if (m_options.m_pointer_as_array)
return true;
@@ -505,17 +503,16 @@ bool ValueObjectPrinter::ShouldPrintChildren(
return false;
if (is_failed_description || m_curr_depth < m_options.m_max_depth) {
- // We will show children for all concrete types. We won't show
- // pointer contents unless a pointer depth has been specified.
- // We won't reference contents unless the reference is the
- // root object (depth of zero).
+ // We will show children for all concrete types. We won't show pointer
+ // contents unless a pointer depth has been specified. We won't reference
+ // contents unless the reference is the root object (depth of zero).
- // Use a new temporary pointer depth in case we override the
- // current pointer depth below...
+ // Use a new temporary pointer depth in case we override the current
+ // pointer depth below...
if (is_ptr || is_ref) {
- // We have a pointer or reference whose value is an address.
- // Make sure that address is not NULL
+ // We have a pointer or reference whose value is an address. Make sure
+ // that address is not NULL
AddressType ptr_address_type;
if (m_valobj->GetPointerValue(&ptr_address_type) == 0)
return false;
@@ -523,10 +520,10 @@ bool ValueObjectPrinter::ShouldPrintChildren(
const bool is_root_level = m_curr_depth == 0;
if (is_ref && is_root_level) {
- // If this is the root object (depth is zero) that we are showing
- // and it is a reference, and no pointer depth has been supplied
- // print out what it references. Don't do this at deeper depths
- // otherwise we can end up with infinite recursion...
+ // If this is the root object (depth is zero) that we are showing and
+ // it is a reference, and no pointer depth has been supplied print out
+ // what it references. Don't do this at deeper depths otherwise we can
+ // end up with infinite recursion...
return true;
}
@@ -759,8 +756,7 @@ bool ValueObjectPrinter::PrintChildrenOneLiner(bool hide_names) {
void ValueObjectPrinter::PrintChildrenIfNeeded(bool value_printed,
bool summary_printed) {
// this flag controls whether we tried to display a description for this
- // object and failed
- // if that happens, we want to display the children, if any
+ // object and failed if that happens, we want to display the children, if any
bool is_failed_description =
!PrintObjectDescriptionIfNeeded(value_printed, summary_printed);
diff --git a/source/DataFormatters/VectorType.cpp b/source/DataFormatters/VectorType.cpp
index 4fb92cad3988..d85a7e674177 100644
--- a/source/DataFormatters/VectorType.cpp
+++ b/source/DataFormatters/VectorType.cpp
@@ -157,9 +157,8 @@ static lldb::Format GetItemFormatForFormat(lldb::Format format,
case lldb::eFormatDefault: {
// special case the (default, char) combination to actually display as an
- // integer value
- // most often, you won't want to see the ASCII characters... (and if you do,
- // eFormatChar is a keystroke away)
+ // integer value most often, you won't want to see the ASCII characters...
+ // (and if you do, eFormatChar is a keystroke away)
bool is_char = element_type.IsCharType();
bool is_signed = false;
element_type.IsIntegerType(is_signed);
diff --git a/source/Expression/CMakeLists.txt b/source/Expression/CMakeLists.txt
index 7d9643a45dd5..020d470ed126 100644
--- a/source/Expression/CMakeLists.txt
+++ b/source/Expression/CMakeLists.txt
@@ -30,6 +30,7 @@ add_lldb_library(lldbExpression
lldbTarget
lldbUtility
lldbPluginExpressionParserClang
+ lldbPluginObjectFileJIT
LINK_COMPONENTS
Core
diff --git a/source/Expression/DWARFExpression.cpp b/source/Expression/DWARFExpression.cpp
index 14011aece7c9..55eb65f32b5a 100644
--- a/source/Expression/DWARFExpression.cpp
+++ b/source/Expression/DWARFExpression.cpp
@@ -15,6 +15,7 @@
// C++ Includes
#include <vector>
+#include "lldb/Core/Module.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Core/Value.h"
@@ -37,13 +38,13 @@
#include "lldb/Target/StackID.h"
#include "lldb/Target/Thread.h"
-#include "Plugins/SymbolFile/DWARF/DWARFCompileUnit.h"
+#include "Plugins/SymbolFile/DWARF/DWARFUnit.h"
using namespace lldb;
using namespace lldb_private;
static lldb::addr_t
-ReadAddressFromDebugAddrSection(const DWARFCompileUnit *dwarf_cu,
+ReadAddressFromDebugAddrSection(const DWARFUnit *dwarf_cu,
uint32_t index) {
uint32_t index_size = dwarf_cu->GetAddressByteSize();
dw_offset_t addr_base = dwarf_cu->GetAddrBase();
@@ -55,7 +56,7 @@ ReadAddressFromDebugAddrSection(const DWARFCompileUnit *dwarf_cu,
//----------------------------------------------------------------------
// DWARFExpression constructor
//----------------------------------------------------------------------
-DWARFExpression::DWARFExpression(DWARFCompileUnit *dwarf_cu)
+DWARFExpression::DWARFExpression(DWARFUnit *dwarf_cu)
: m_module_wp(), m_data(), m_dwarf_cu(dwarf_cu),
m_reg_kind(eRegisterKindDWARF), m_loclist_slide(LLDB_INVALID_ADDRESS) {}
@@ -66,7 +67,7 @@ DWARFExpression::DWARFExpression(const DWARFExpression &rhs)
DWARFExpression::DWARFExpression(lldb::ModuleSP module_sp,
const DataExtractor &data,
- DWARFCompileUnit *dwarf_cu,
+ DWARFUnit *dwarf_cu,
lldb::offset_t data_offset,
lldb::offset_t data_length)
: m_module_wp(), m_data(data, data_offset, data_length),
@@ -147,13 +148,13 @@ void DWARFExpression::DumpLocation(Stream *s, lldb::offset_t offset,
break;
case lldb::eDescriptionLevelBrief:
- if (offset > start_offset)
+ if (op_offset > start_offset)
s->PutChar(' ');
break;
case lldb::eDescriptionLevelFull:
case lldb::eDescriptionLevelVerbose:
- if (offset > start_offset)
+ if (op_offset > start_offset)
s->EOL();
s->Indent();
if (level == lldb::eDescriptionLevelFull)
@@ -172,34 +173,34 @@ void DWARFExpression::DumpLocation(Stream *s, lldb::offset_t offset,
*s << "DW_OP_deref";
break; // 0x06
case DW_OP_const1u:
- s->Printf("DW_OP_const1u(0x%2.2x) ", m_data.GetU8(&offset));
+ s->Printf("DW_OP_const1u(0x%2.2x)", m_data.GetU8(&offset));
break; // 0x08 1 1-byte constant
case DW_OP_const1s:
- s->Printf("DW_OP_const1s(0x%2.2x) ", m_data.GetU8(&offset));
+ s->Printf("DW_OP_const1s(0x%2.2x)", m_data.GetU8(&offset));
break; // 0x09 1 1-byte constant
case DW_OP_const2u:
- s->Printf("DW_OP_const2u(0x%4.4x) ", m_data.GetU16(&offset));
+ s->Printf("DW_OP_const2u(0x%4.4x)", m_data.GetU16(&offset));
break; // 0x0a 1 2-byte constant
case DW_OP_const2s:
- s->Printf("DW_OP_const2s(0x%4.4x) ", m_data.GetU16(&offset));
+ s->Printf("DW_OP_const2s(0x%4.4x)", m_data.GetU16(&offset));
break; // 0x0b 1 2-byte constant
case DW_OP_const4u:
- s->Printf("DW_OP_const4u(0x%8.8x) ", m_data.GetU32(&offset));
+ s->Printf("DW_OP_const4u(0x%8.8x)", m_data.GetU32(&offset));
break; // 0x0c 1 4-byte constant
case DW_OP_const4s:
- s->Printf("DW_OP_const4s(0x%8.8x) ", m_data.GetU32(&offset));
+ s->Printf("DW_OP_const4s(0x%8.8x)", m_data.GetU32(&offset));
break; // 0x0d 1 4-byte constant
case DW_OP_const8u:
- s->Printf("DW_OP_const8u(0x%16.16" PRIx64 ") ", m_data.GetU64(&offset));
+ s->Printf("DW_OP_const8u(0x%16.16" PRIx64 ")", m_data.GetU64(&offset));
break; // 0x0e 1 8-byte constant
case DW_OP_const8s:
- s->Printf("DW_OP_const8s(0x%16.16" PRIx64 ") ", m_data.GetU64(&offset));
+ s->Printf("DW_OP_const8s(0x%16.16" PRIx64 ")", m_data.GetU64(&offset));
break; // 0x0f 1 8-byte constant
case DW_OP_constu:
- s->Printf("DW_OP_constu(0x%" PRIx64 ") ", m_data.GetULEB128(&offset));
+ s->Printf("DW_OP_constu(0x%" PRIx64 ")", m_data.GetULEB128(&offset));
break; // 0x10 1 ULEB128 constant
case DW_OP_consts:
- s->Printf("DW_OP_consts(0x%" PRId64 ") ", m_data.GetSLEB128(&offset));
+ s->Printf("DW_OP_consts(0x%" PRId64 ")", m_data.GetSLEB128(&offset));
break; // 0x11 1 SLEB128 constant
case DW_OP_dup:
s->PutCString("DW_OP_dup");
@@ -211,7 +212,7 @@ void DWARFExpression::DumpLocation(Stream *s, lldb::offset_t offset,
s->PutCString("DW_OP_over");
break; // 0x14
case DW_OP_pick:
- s->Printf("DW_OP_pick(0x%2.2x) ", m_data.GetU8(&offset));
+ s->Printf("DW_OP_pick(0x%2.2x)", m_data.GetU8(&offset));
break; // 0x15 1 1-byte stack index
case DW_OP_swap:
s->PutCString("DW_OP_swap");
@@ -253,7 +254,7 @@ void DWARFExpression::DumpLocation(Stream *s, lldb::offset_t offset,
s->PutCString("DW_OP_plus");
break; // 0x22
case DW_OP_plus_uconst: // 0x23 1 ULEB128 addend
- s->Printf("DW_OP_plus_uconst(0x%" PRIx64 ") ",
+ s->Printf("DW_OP_plus_uconst(0x%" PRIx64 ")",
m_data.GetULEB128(&offset));
break;
@@ -679,8 +680,8 @@ static bool ReadRegisterValueAsScalar(RegisterContext *reg_ctx,
error_ptr->Clear();
return true;
} else {
- // If we get this error, then we need to implement a value
- // buffer in the dwarf expression evaluation function...
+ // If we get this error, then we need to implement a value buffer in
+ // the dwarf expression evaluation function...
if (error_ptr)
error_ptr->SetErrorStringWithFormat(
"register %s can't be converted to a scalar value",
@@ -991,17 +992,17 @@ bool DWARFExpression::Update_DW_OP_addr(lldb::addr_t file_addr) {
if (op == DW_OP_addr) {
const uint32_t addr_byte_size = m_data.GetAddressByteSize();
- // We have to make a copy of the data as we don't know if this
- // data is from a read only memory mapped buffer, so we duplicate
- // all of the data first, then modify it, and if all goes well,
- // we then replace the data for this expression
+ // We have to make a copy of the data as we don't know if this data is
+ // from a read only memory mapped buffer, so we duplicate all of the data
+ // first, then modify it, and if all goes well, we then replace the data
+ // for this expression
// So first we copy the data into a heap buffer
std::unique_ptr<DataBufferHeap> head_data_ap(
new DataBufferHeap(m_data.GetDataStart(), m_data.GetByteSize()));
- // Make en encoder so we can write the address into the buffer using
- // the correct byte order (endianness)
+ // Make en encoder so we can write the address into the buffer using the
+ // correct byte order (endianness)
DataEncoder encoder(head_data_ap->GetBytes(), head_data_ap->GetByteSize(),
m_data.GetByteOrder(), addr_byte_size);
@@ -1009,9 +1010,8 @@ bool DWARFExpression::Update_DW_OP_addr(lldb::addr_t file_addr) {
if (encoder.PutMaxU64(offset, addr_byte_size, file_addr) == UINT32_MAX)
return false;
- // All went well, so now we can reset the data using a shared
- // pointer to the heap data so "m_data" will now correctly
- // manage the heap data.
+ // All went well, so now we can reset the data using a shared pointer to
+ // the heap data so "m_data" will now correctly manage the heap data.
m_data.SetData(DataBufferSP(head_data_ap.release()));
return true;
} else {
@@ -1025,9 +1025,9 @@ bool DWARFExpression::Update_DW_OP_addr(lldb::addr_t file_addr) {
}
bool DWARFExpression::ContainsThreadLocalStorage() const {
- // We are assuming for now that any thread local variable will not
- // have a location list. This has been true for all thread local
- // variables we have seen so far produced by any compiler.
+ // We are assuming for now that any thread local variable will not have a
+ // location list. This has been true for all thread local variables we have
+ // seen so far produced by any compiler.
if (IsLocationList())
return false;
lldb::offset_t offset = 0;
@@ -1048,24 +1048,24 @@ bool DWARFExpression::LinkThreadLocalStorage(
lldb::ModuleSP new_module_sp,
std::function<lldb::addr_t(lldb::addr_t file_addr)> const
&link_address_callback) {
- // We are assuming for now that any thread local variable will not
- // have a location list. This has been true for all thread local
- // variables we have seen so far produced by any compiler.
+ // We are assuming for now that any thread local variable will not have a
+ // location list. This has been true for all thread local variables we have
+ // seen so far produced by any compiler.
if (IsLocationList())
return false;
const uint32_t addr_byte_size = m_data.GetAddressByteSize();
- // We have to make a copy of the data as we don't know if this
- // data is from a read only memory mapped buffer, so we duplicate
- // all of the data first, then modify it, and if all goes well,
- // we then replace the data for this expression
+ // We have to make a copy of the data as we don't know if this data is from a
+ // read only memory mapped buffer, so we duplicate all of the data first,
+ // then modify it, and if all goes well, we then replace the data for this
+ // expression
// So first we copy the data into a heap buffer
std::shared_ptr<DataBufferHeap> heap_data_sp(
new DataBufferHeap(m_data.GetDataStart(), m_data.GetByteSize()));
- // Make en encoder so we can write the address into the buffer using
- // the correct byte order (endianness)
+ // Make en encoder so we can write the address into the buffer using the
+ // correct byte order (endianness)
DataEncoder encoder(heap_data_sp->GetBytes(), heap_data_sp->GetByteSize(),
m_data.GetByteOrder(), addr_byte_size);
@@ -1080,8 +1080,7 @@ bool DWARFExpression::LinkThreadLocalStorage(
switch (op) {
case DW_OP_const4u:
// Remember the const offset in case we later have a
- // DW_OP_form_tls_address
- // or DW_OP_GNU_push_tls_address
+ // DW_OP_form_tls_address or DW_OP_GNU_push_tls_address
const_offset = offset;
const_value = m_data.GetU32(&offset);
decoded_data = true;
@@ -1090,8 +1089,7 @@ bool DWARFExpression::LinkThreadLocalStorage(
case DW_OP_const8u:
// Remember the const offset in case we later have a
- // DW_OP_form_tls_address
- // or DW_OP_GNU_push_tls_address
+ // DW_OP_form_tls_address or DW_OP_GNU_push_tls_address
const_offset = offset;
const_value = m_data.GetU64(&offset);
decoded_data = true;
@@ -1101,21 +1099,15 @@ bool DWARFExpression::LinkThreadLocalStorage(
case DW_OP_form_tls_address:
case DW_OP_GNU_push_tls_address:
// DW_OP_form_tls_address and DW_OP_GNU_push_tls_address must be preceded
- // by
- // a file address on the stack. We assume that DW_OP_const4u or
- // DW_OP_const8u
- // is used for these values, and we check that the last opcode we got
- // before
- // either of these was DW_OP_const4u or DW_OP_const8u. If so, then we can
- // link
- // the value accodingly. For Darwin, the value in the DW_OP_const4u or
- // DW_OP_const8u is the file address of a structure that contains a
- // function
- // pointer, the pthread key and the offset into the data pointed to by the
- // pthread key. So we must link this address and also set the module of
- // this
- // expression to the new_module_sp so we can resolve the file address
- // correctly
+ // by a file address on the stack. We assume that DW_OP_const4u or
+ // DW_OP_const8u is used for these values, and we check that the last
+ // opcode we got before either of these was DW_OP_const4u or
+ // DW_OP_const8u. If so, then we can link the value accodingly. For
+ // Darwin, the value in the DW_OP_const4u or DW_OP_const8u is the file
+ // address of a structure that contains a function pointer, the pthread
+ // key and the offset into the data pointed to by the pthread key. So we
+ // must link this address and also set the module of this expression to
+ // the new_module_sp so we can resolve the file address correctly
if (const_byte_size > 0) {
lldb::addr_t linked_file_addr = link_address_callback(const_value);
if (linked_file_addr == LLDB_INVALID_ADDRESS)
@@ -1144,8 +1136,8 @@ bool DWARFExpression::LinkThreadLocalStorage(
}
// If we linked the TLS address correctly, update the module so that when the
- // expression
- // is evaluated it can resolve the file address to a load address and read the
+ // expression is evaluated it can resolve the file address to a load address
+ // and read the
// TLS data
m_module_wp = new_module_sp;
m_data.SetData(heap_data_sp);
@@ -1323,7 +1315,7 @@ bool DWARFExpression::Evaluate(ExecutionContext *exe_ctx,
bool DWARFExpression::Evaluate(
ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
lldb::ModuleSP module_sp, const DataExtractor &opcodes,
- DWARFCompileUnit *dwarf_cu, const lldb::offset_t opcodes_offset,
+ DWARFUnit *dwarf_cu, const lldb::offset_t opcodes_offset,
const lldb::offset_t opcodes_length, const lldb::RegisterKind reg_kind,
const Value *initial_value_ptr, const Value *object_address_ptr,
Value &result, Status *error_ptr) {
@@ -1383,6 +1375,7 @@ bool DWARFExpression::Evaluate(
}
log->Printf("0x%8.8" PRIx64 ": %s", op_offset, DW_OP_value_to_name(op));
}
+
switch (op) {
//----------------------------------------------------------------------
// The DW_OP_addr operation has a single operand that encodes a machine
@@ -1391,17 +1384,22 @@ bool DWARFExpression::Evaluate(
case DW_OP_addr:
stack.push_back(Scalar(opcodes.GetAddress(&offset)));
stack.back().SetValueType(Value::eValueTypeFileAddress);
+ // Convert the file address to a load address, so subsequent
+ // DWARF operators can operate on it.
+ if (frame)
+ stack.back().ConvertToLoadAddress(module_sp.get(),
+ frame->CalculateTarget().get());
break;
//----------------------------------------------------------------------
// The DW_OP_addr_sect_offset4 is used for any location expressions in
// shared libraries that have a location like:
// DW_OP_addr(0x1000)
- // If this address resides in a shared library, then this virtual
- // address won't make sense when it is evaluated in the context of a
- // running process where shared libraries have been slid. To account for
- // this, this new address type where we can store the section pointer
- // and a 4 byte offset.
+ // If this address resides in a shared library, then this virtual address
+ // won't make sense when it is evaluated in the context of a running
+ // process where shared libraries have been slid. To account for this, this
+ // new address type where we can store the section pointer and a 4 byte
+ // offset.
//----------------------------------------------------------------------
// case DW_OP_addr_sect_offset4:
// {
@@ -1436,9 +1434,9 @@ bool DWARFExpression::Evaluate(
// OPCODE: DW_OP_deref
// OPERANDS: none
// DESCRIPTION: Pops the top stack entry and treats it as an address.
- // The value retrieved from that address is pushed. The size of the
- // data retrieved from the dereferenced address is the size of an
- // address on the target machine.
+ // The value retrieved from that address is pushed. The size of the data
+ // retrieved from the dereferenced address is the size of an address on the
+ // target machine.
//----------------------------------------------------------------------
case DW_OP_deref: {
if (stack.empty()) {
@@ -1455,6 +1453,33 @@ bool DWARFExpression::Evaluate(
stack.back().GetScalar() = ptr;
stack.back().ClearContext();
} break;
+ case Value::eValueTypeFileAddress: {
+ auto file_addr = stack.back().GetScalar().ULongLong(
+ LLDB_INVALID_ADDRESS);
+ if (!module_sp) {
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormat(
+ "need module to resolve file address for DW_OP_deref");
+ return false;
+ }
+ Address so_addr;
+ if (!module_sp->ResolveFileAddress(file_addr, so_addr)) {
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormat(
+ "failed to resolve file address in module");
+ return false;
+ }
+ addr_t load_Addr = so_addr.GetLoadAddress(exe_ctx->GetTargetPtr());
+ if (load_Addr == LLDB_INVALID_ADDRESS) {
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormat(
+ "failed to resolve load address");
+ return false;
+ }
+ stack.back().GetScalar() = load_Addr;
+ stack.back().SetValueType(Value::eValueTypeLoadAddress);
+ // Fall through to load address code below...
+ } LLVM_FALLTHROUGH;
case Value::eValueTypeLoadAddress:
if (exe_ctx) {
if (process) {
@@ -1500,13 +1525,13 @@ bool DWARFExpression::Evaluate(
// 1 - uint8_t that specifies the size of the data to dereference.
// DESCRIPTION: Behaves like the DW_OP_deref operation: it pops the top
// stack entry and treats it as an address. The value retrieved from that
- // address is pushed. In the DW_OP_deref_size operation, however, the
- // size in bytes of the data retrieved from the dereferenced address is
+ // address is pushed. In the DW_OP_deref_size operation, however, the size
+ // in bytes of the data retrieved from the dereferenced address is
// specified by the single operand. This operand is a 1-byte unsigned
// integral constant whose value may not be larger than the size of an
- // address on the target machine. The data retrieved is zero extended
- // to the size of an address on the target machine before being pushed
- // on the expression stack.
+ // address on the target machine. The data retrieved is zero extended to
+ // the size of an address on the target machine before being pushed on the
+ // expression stack.
//----------------------------------------------------------------------
case DW_OP_deref_size: {
if (stack.empty()) {
@@ -1525,8 +1550,7 @@ bool DWARFExpression::Evaluate(
// I can't decide whether the size operand should apply to the bytes in
// their
// lldb-host endianness or the target endianness.. I doubt this'll ever
- // come up
- // but I'll opt for assuming big endian regardless.
+ // come up but I'll opt for assuming big endian regardless.
switch (size) {
case 1:
ptr = ptr & 0xff;
@@ -1622,18 +1646,17 @@ bool DWARFExpression::Evaluate(
// OPERANDS: 1
// 1 - uint8_t that specifies the size of the data to dereference.
// DESCRIPTION: Behaves like the DW_OP_xderef operation: the entry at
- // the top of the stack is treated as an address. The second stack
- // entry is treated as an "address space identifier" for those
- // architectures that support multiple address spaces. The top two
- // stack elements are popped, a data item is retrieved through an
- // implementation-defined address calculation and pushed as the new
- // stack top. In the DW_OP_xderef_size operation, however, the size in
- // bytes of the data retrieved from the dereferenced address is
- // specified by the single operand. This operand is a 1-byte unsigned
- // integral constant whose value may not be larger than the size of an
- // address on the target machine. The data retrieved is zero extended
- // to the size of an address on the target machine before being pushed
- // on the expression stack.
+ // the top of the stack is treated as an address. The second stack entry is
+ // treated as an "address space identifier" for those architectures that
+ // support multiple address spaces. The top two stack elements are popped,
+ // a data item is retrieved through an implementation-defined address
+ // calculation and pushed as the new stack top. In the DW_OP_xderef_size
+ // operation, however, the size in bytes of the data retrieved from the
+ // dereferenced address is specified by the single operand. This operand is
+ // a 1-byte unsigned integral constant whose value may not be larger than
+ // the size of an address on the target machine. The data retrieved is zero
+ // extended to the size of an address on the target machine before being
+ // pushed on the expression stack.
//----------------------------------------------------------------------
case DW_OP_xderef_size:
if (error_ptr)
@@ -1643,13 +1666,13 @@ bool DWARFExpression::Evaluate(
// OPCODE: DW_OP_xderef
// OPERANDS: none
// DESCRIPTION: Provides an extended dereference mechanism. The entry at
- // the top of the stack is treated as an address. The second stack entry
- // is treated as an "address space identifier" for those architectures
- // that support multiple address spaces. The top two stack elements are
- // popped, a data item is retrieved through an implementation-defined
- // address calculation and pushed as the new stack top. The size of the
- // data retrieved from the dereferenced address is the size of an address
- // on the target machine.
+ // the top of the stack is treated as an address. The second stack entry is
+ // treated as an "address space identifier" for those architectures that
+ // support multiple address spaces. The top two stack elements are popped,
+ // a data item is retrieved through an implementation-defined address
+ // calculation and pushed as the new stack top. The size of the data
+ // retrieved from the dereferenced address is the size of an address on the
+ // target machine.
//----------------------------------------------------------------------
case DW_OP_xderef:
if (error_ptr)
@@ -1661,16 +1684,13 @@ bool DWARFExpression::Evaluate(
//
// Opcode Operand 1
// --------------- ----------------------------------------------------
- // DW_OP_const1u 1-byte unsigned integer constant
- // DW_OP_const1s 1-byte signed integer constant
- // DW_OP_const2u 2-byte unsigned integer constant
- // DW_OP_const2s 2-byte signed integer constant
- // DW_OP_const4u 4-byte unsigned integer constant
- // DW_OP_const4s 4-byte signed integer constant
- // DW_OP_const8u 8-byte unsigned integer constant
- // DW_OP_const8s 8-byte signed integer constant
- // DW_OP_constu unsigned LEB128 integer constant
- // DW_OP_consts signed LEB128 integer constant
+ // DW_OP_const1u 1-byte unsigned integer constant DW_OP_const1s
+ // 1-byte signed integer constant DW_OP_const2u 2-byte unsigned integer
+ // constant DW_OP_const2s 2-byte signed integer constant DW_OP_const4u
+ // 4-byte unsigned integer constant DW_OP_const4s 4-byte signed integer
+ // constant DW_OP_const8u 8-byte unsigned integer constant DW_OP_const8s
+ // 8-byte signed integer constant DW_OP_constu unsigned LEB128 integer
+ // constant DW_OP_consts signed LEB128 integer constant
//----------------------------------------------------------------------
case DW_OP_const1u:
stack.push_back(Scalar((uint8_t)opcodes.GetU8(&offset)));
@@ -1789,9 +1809,9 @@ bool DWARFExpression::Evaluate(
// OPCODE: DW_OP_rot
// OPERANDS: none
// DESCRIPTION: Rotates the first three stack entries. The entry at
- // the top of the stack becomes the third stack entry, the second
- // entry becomes the top of the stack, and the third entry becomes
- // the second entry.
+ // the top of the stack becomes the third stack entry, the second entry
+ // becomes the top of the stack, and the third entry becomes the second
+ // entry.
//----------------------------------------------------------------------
case DW_OP_rot:
if (stack.size() < 3) {
@@ -1853,8 +1873,8 @@ bool DWARFExpression::Evaluate(
// OPCODE: DW_OP_div
// OPERANDS: none
// DESCRIPTION: pops the top two stack values, divides the former second
- // entry by the former top of the stack using signed division, and
- // pushes the result.
+ // entry by the former top of the stack using signed division, and pushes
+ // the result.
//----------------------------------------------------------------------
case DW_OP_div:
if (stack.size() < 2) {
@@ -1905,8 +1925,8 @@ bool DWARFExpression::Evaluate(
// OPCODE: DW_OP_mod
// OPERANDS: none
// DESCRIPTION: pops the top two stack values and pushes the result of
- // the calculation: former second stack entry modulo the former top of
- // the stack.
+ // the calculation: former second stack entry modulo the former top of the
+ // stack.
//----------------------------------------------------------------------
case DW_OP_mod:
if (stack.size() < 2) {
@@ -2050,8 +2070,8 @@ bool DWARFExpression::Evaluate(
// OPCODE: DW_OP_shl
// OPERANDS: none
// DESCRIPTION: pops the top two stack entries, shifts the former
- // second entry left by the number of bits specified by the former top
- // of the stack, and pushes the result.
+ // second entry left by the number of bits specified by the former top of
+ // the stack, and pushes the result.
//----------------------------------------------------------------------
case DW_OP_shl:
if (stack.size() < 2) {
@@ -2096,8 +2116,8 @@ bool DWARFExpression::Evaluate(
// OPERANDS: none
// DESCRIPTION: pops the top two stack entries, shifts the former second
// entry right arithmetically (divide the magnitude by 2, keep the same
- // sign for the result) by the number of bits specified by the former
- // top of the stack, and pushes the result.
+ // sign for the result) by the number of bits specified by the former top
+ // of the stack, and pushes the result.
//----------------------------------------------------------------------
case DW_OP_shra:
if (stack.size() < 2) {
@@ -2136,8 +2156,8 @@ bool DWARFExpression::Evaluate(
// OPCODE: DW_OP_skip
// OPERANDS: int16_t
// DESCRIPTION: An unconditional branch. Its single operand is a 2-byte
- // signed integer constant. The 2-byte constant is the number of bytes
- // of the DWARF expression to skip forward or backward from the current
+ // signed integer constant. The 2-byte constant is the number of bytes of
+ // the DWARF expression to skip forward or backward from the current
// operation, beginning after the 2-byte constant.
//----------------------------------------------------------------------
case DW_OP_skip: {
@@ -2156,11 +2176,10 @@ bool DWARFExpression::Evaluate(
// OPCODE: DW_OP_bra
// OPERANDS: int16_t
// DESCRIPTION: A conditional branch. Its single operand is a 2-byte
- // signed integer constant. This operation pops the top of stack. If
- // the value popped is not the constant 0, the 2-byte constant operand
- // is the number of bytes of the DWARF expression to skip forward or
- // backward from the current operation, beginning after the 2-byte
- // constant.
+ // signed integer constant. This operation pops the top of stack. If the
+ // value popped is not the constant 0, the 2-byte constant operand is the
+ // number of bytes of the DWARF expression to skip forward or backward from
+ // the current operation, beginning after the 2-byte constant.
//----------------------------------------------------------------------
case DW_OP_bra:
if (stack.empty()) {
@@ -2537,15 +2556,15 @@ bool DWARFExpression::Evaluate(
// OPERANDS: 1
// ULEB128: byte size of the piece
// DESCRIPTION: The operand describes the size in bytes of the piece of
- // the object referenced by the DWARF expression whose result is at the
- // top of the stack. If the piece is located in a register, but does not
- // occupy the entire register, the placement of the piece within that
- // register is defined by the ABI.
+ // the object referenced by the DWARF expression whose result is at the top
+ // of the stack. If the piece is located in a register, but does not occupy
+ // the entire register, the placement of the piece within that register is
+ // defined by the ABI.
//
- // Many compilers store a single variable in sets of registers, or store
- // a variable partially in memory and partially in registers.
- // DW_OP_piece provides a way of describing how large a part of a
- // variable a particular DWARF expression refers to.
+ // Many compilers store a single variable in sets of registers, or store a
+ // variable partially in memory and partially in registers. DW_OP_piece
+ // provides a way of describing how large a part of a variable a particular
+ // DWARF expression refers to.
//----------------------------------------------------------------------
case DW_OP_piece: {
const uint64_t piece_byte_size = opcodes.GetULEB128(&offset);
@@ -2555,8 +2574,8 @@ bool DWARFExpression::Evaluate(
if (stack.empty()) {
// In a multi-piece expression, this means that the current piece is
- // not available.
- // Fill with zeros for now by resizing the data and appending it
+ // not available. Fill with zeros for now by resizing the data and
+ // appending it
curr_piece.ResizeData(piece_byte_size);
::memset(curr_piece.GetBuffer().GetBytes(), 0, piece_byte_size);
pieces.AppendDataToHostBuffer(curr_piece);
@@ -2646,9 +2665,9 @@ bool DWARFExpression::Evaluate(
// Check if this is the first piece?
if (op_piece_offset == 0) {
- // This is the first piece, we should push it back onto the stack so
- // subsequent
- // pieces will be able to access this piece and add to it
+ // This is the first piece, we should push it back onto the stack
+ // so subsequent pieces will be able to access this piece and add
+ // to it
if (pieces.AppendDataToHostBuffer(curr_piece) == 0) {
if (error_ptr)
error_ptr->SetErrorString("failed to append piece data");
@@ -2706,7 +2725,7 @@ bool DWARFExpression::Evaluate(
if (error_ptr) {
error_ptr->SetErrorStringWithFormat(
"unable to extract DW_OP_bit_piece(bit_size = %" PRIu64
- ", bit_offset = %" PRIu64 ") from an addresss value.",
+ ", bit_offset = %" PRIu64 ") from an address value.",
piece_bit_size, piece_bit_offset);
}
return false;
@@ -2727,11 +2746,11 @@ bool DWARFExpression::Evaluate(
// OPCODE: DW_OP_push_object_address
// OPERANDS: none
// DESCRIPTION: Pushes the address of the object currently being
- // evaluated as part of evaluation of a user presented expression.
- // This object may correspond to an independent variable described by
- // its own DIE or it may be a component of an array, structure, or class
- // whose address has been dynamically determined by an earlier step
- // during user expression evaluation.
+ // evaluated as part of evaluation of a user presented expression. This
+ // object may correspond to an independent variable described by its own
+ // DIE or it may be a component of an array, structure, or class whose
+ // address has been dynamically determined by an earlier step during user
+ // expression evaluation.
//----------------------------------------------------------------------
case DW_OP_push_object_address:
if (object_address_ptr)
@@ -2749,21 +2768,20 @@ bool DWARFExpression::Evaluate(
// OPERANDS:
// uint16_t compile unit relative offset of a DIE
// DESCRIPTION: Performs subroutine calls during evaluation
- // of a DWARF expression. The operand is the 2-byte unsigned offset
- // of a debugging information entry in the current compilation unit.
+ // of a DWARF expression. The operand is the 2-byte unsigned offset of a
+ // debugging information entry in the current compilation unit.
//
// Operand interpretation is exactly like that for DW_FORM_ref2.
//
- // This operation transfers control of DWARF expression evaluation
- // to the DW_AT_location attribute of the referenced DIE. If there is
- // no such attribute, then there is no effect. Execution of the DWARF
- // expression of a DW_AT_location attribute may add to and/or remove from
- // values on the stack. Execution returns to the point following the call
- // when the end of the attribute is reached. Values on the stack at the
- // time of the call may be used as parameters by the called expression
- // and values left on the stack by the called expression may be used as
- // return values by prior agreement between the calling and called
- // expressions.
+ // This operation transfers control of DWARF expression evaluation to the
+ // DW_AT_location attribute of the referenced DIE. If there is no such
+ // attribute, then there is no effect. Execution of the DWARF expression of
+ // a DW_AT_location attribute may add to and/or remove from values on the
+ // stack. Execution returns to the point following the call when the end of
+ // the attribute is reached. Values on the stack at the time of the call
+ // may be used as parameters by the called expression and values left on
+ // the stack by the called expression may be used as return values by prior
+ // agreement between the calling and called expressions.
//----------------------------------------------------------------------
case DW_OP_call2:
if (error_ptr)
@@ -2774,22 +2792,21 @@ bool DWARFExpression::Evaluate(
// OPERANDS: 1
// uint32_t compile unit relative offset of a DIE
// DESCRIPTION: Performs a subroutine call during evaluation of a DWARF
- // expression. For DW_OP_call4, the operand is a 4-byte unsigned offset
- // of a debugging information entry in the current compilation unit.
+ // expression. For DW_OP_call4, the operand is a 4-byte unsigned offset of
+ // a debugging information entry in the current compilation unit.
//
// Operand interpretation DW_OP_call4 is exactly like that for
// DW_FORM_ref4.
//
- // This operation transfers control of DWARF expression evaluation
- // to the DW_AT_location attribute of the referenced DIE. If there is
- // no such attribute, then there is no effect. Execution of the DWARF
- // expression of a DW_AT_location attribute may add to and/or remove from
- // values on the stack. Execution returns to the point following the call
- // when the end of the attribute is reached. Values on the stack at the
- // time of the call may be used as parameters by the called expression
- // and values left on the stack by the called expression may be used as
- // return values by prior agreement between the calling and called
- // expressions.
+ // This operation transfers control of DWARF expression evaluation to the
+ // DW_AT_location attribute of the referenced DIE. If there is no such
+ // attribute, then there is no effect. Execution of the DWARF expression of
+ // a DW_AT_location attribute may add to and/or remove from values on the
+ // stack. Execution returns to the point following the call when the end of
+ // the attribute is reached. Values on the stack at the time of the call
+ // may be used as parameters by the called expression and values left on
+ // the stack by the called expression may be used as return values by prior
+ // agreement between the calling and called expressions.
//----------------------------------------------------------------------
case DW_OP_call4:
if (error_ptr)
@@ -2800,9 +2817,8 @@ bool DWARFExpression::Evaluate(
// OPCODE: DW_OP_stack_value
// OPERANDS: None
// DESCRIPTION: Specifies that the object does not exist in memory but
- // rather is a constant value. The value from the top of the stack is
- // the value to be used. This is the actual object value and not the
- // location.
+ // rather is a constant value. The value from the top of the stack is the
+ // value to be used. This is the actual object value and not the location.
//----------------------------------------------------------------------
case DW_OP_stack_value:
stack.back().SetValueType(Value::eValueTypeScalar);
@@ -2841,8 +2857,8 @@ bool DWARFExpression::Evaluate(
// opcode, DW_OP_GNU_push_tls_address)
// OPERANDS: none
// DESCRIPTION: Pops a TLS offset from the stack, converts it to
- // an address in the current thread's thread-local storage block,
- // and pushes it on the stack.
+ // an address in the current thread's thread-local storage block, and
+ // pushes it on the stack.
//----------------------------------------------------------------------
case DW_OP_form_tls_address:
case DW_OP_GNU_push_tls_address: {
@@ -2893,8 +2909,8 @@ bool DWARFExpression::Evaluate(
// OPERANDS: 1
// ULEB128: index to the .debug_addr section
// DESCRIPTION: Pushes an address to the stack from the .debug_addr
- // section with the base address specified by the DW_AT_addr_base
- // attribute and the 0 based index is the ULEB128 encoded index.
+ // section with the base address specified by the DW_AT_addr_base attribute
+ // and the 0 based index is the ULEB128 encoded index.
//----------------------------------------------------------------------
case DW_OP_GNU_addr_index: {
if (!dwarf_cu) {
@@ -2984,7 +3000,7 @@ bool DWARFExpression::Evaluate(
return true; // Return true on success
}
-size_t DWARFExpression::LocationListSize(const DWARFCompileUnit *dwarf_cu,
+size_t DWARFExpression::LocationListSize(const DWARFUnit *dwarf_cu,
const DataExtractor &debug_loc_data,
lldb::offset_t offset) {
const lldb::offset_t debug_loc_offset = offset;
@@ -3008,7 +3024,7 @@ size_t DWARFExpression::LocationListSize(const DWARFCompileUnit *dwarf_cu,
}
bool DWARFExpression::AddressRangeForLocationListEntry(
- const DWARFCompileUnit *dwarf_cu, const DataExtractor &debug_loc_data,
+ const DWARFUnit *dwarf_cu, const DataExtractor &debug_loc_data,
lldb::offset_t *offset_ptr, lldb::addr_t &low_pc, lldb::addr_t &high_pc) {
if (!debug_loc_data.ValidOffset(*offset_ptr))
return false;
@@ -3242,11 +3258,11 @@ bool DWARFExpression::PrintDWARFExpression(Stream &s, const DataExtractor &data,
}
void DWARFExpression::PrintDWARFLocationList(
- Stream &s, const DWARFCompileUnit *cu, const DataExtractor &debug_loc_data,
+ Stream &s, const DWARFUnit *cu, const DataExtractor &debug_loc_data,
lldb::offset_t offset) {
uint64_t start_addr, end_addr;
- uint32_t addr_size = DWARFCompileUnit::GetAddressByteSize(cu);
- s.SetAddressByteSize(DWARFCompileUnit::GetAddressByteSize(cu));
+ uint32_t addr_size = DWARFUnit::GetAddressByteSize(cu);
+ s.SetAddressByteSize(DWARFUnit::GetAddressByteSize(cu));
dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0;
while (debug_loc_data.ValidOffset(offset)) {
start_addr = debug_loc_data.GetMaxU64(&offset, addr_size);
diff --git a/source/Expression/DiagnosticManager.cpp b/source/Expression/DiagnosticManager.cpp
index ae20feb910dd..a98d30339b4a 100644
--- a/source/Expression/DiagnosticManager.cpp
+++ b/source/Expression/DiagnosticManager.cpp
@@ -22,9 +22,8 @@ void DiagnosticManager::Dump(Log *log) {
std::string str = GetString();
- // GetString() puts a separator after each diagnostic.
- // We want to remove the last '\n' because log->PutCString will add one for
- // us.
+ // GetString() puts a separator after each diagnostic. We want to remove the
+ // last '\n' because log->PutCString will add one for us.
if (str.size() && str.back() == '\n') {
str.pop_back();
diff --git a/source/Expression/ExpressionSourceCode.cpp b/source/Expression/ExpressionSourceCode.cpp
index d60a12888065..abbb332fac48 100644
--- a/source/Expression/ExpressionSourceCode.cpp
+++ b/source/Expression/ExpressionSourceCode.cpp
@@ -93,15 +93,15 @@ public:
m_state = CURRENT_FILE_POPPED;
}
- // An entry is valid if it occurs before the current line in
- // the current file.
+ // An entry is valid if it occurs before the current line in the current
+ // file.
bool IsValidEntry(uint32_t line) {
switch (m_state) {
case CURRENT_FILE_NOT_YET_PUSHED:
return true;
case CURRENT_FILE_PUSHED:
- // If we are in file included in the current file,
- // the entry should be added.
+ // If we are in file included in the current file, the entry should be
+ // added.
if (m_file_stack.back() != m_current_file)
return true;
diff --git a/source/Expression/ExpressionVariable.cpp b/source/Expression/ExpressionVariable.cpp
index a97180029a84..bce9a87bfb47 100644
--- a/source/Expression/ExpressionVariable.cpp
+++ b/source/Expression/ExpressionVariable.cpp
@@ -9,6 +9,7 @@
#include "lldb/Expression/ExpressionVariable.h"
#include "lldb/Expression/IRExecutionUnit.h"
+#include "lldb/Target/Target.h"
#include "lldb/Utility/Log.h"
using namespace lldb_private;
@@ -69,8 +70,8 @@ void PersistentExpressionState::RegisterExecutionUnit(
execution_unit_sp->GetJittedGlobalVariables()) {
if (global_var.m_remote_addr != LLDB_INVALID_ADDRESS) {
// Demangle the name before inserting it, so that lookups by the ConstStr
- // of the demangled name
- // will find the mangled one (needed for looking up metadata pointers.)
+ // of the demangled name will find the mangled one (needed for looking up
+ // metadata pointers.)
Mangled mangler(global_var.m_name);
mangler.GetDemangledName(lldb::eLanguageTypeUnknown);
m_symbol_map[global_var.m_name.GetCString()] = global_var.m_remote_addr;
@@ -80,3 +81,13 @@ void PersistentExpressionState::RegisterExecutionUnit(
}
}
}
+
+ConstString PersistentExpressionState::GetNextPersistentVariableName(
+ Target &target, llvm::StringRef Prefix) {
+ llvm::SmallString<64> name;
+ {
+ llvm::raw_svector_ostream os(name);
+ os << Prefix << target.GetNextPersistentVariableIndex();
+ }
+ return ConstString(name);
+}
diff --git a/source/Expression/FunctionCaller.cpp b/source/Expression/FunctionCaller.cpp
index 6f60f8bf9c13..9742ed0b270e 100644
--- a/source/Expression/FunctionCaller.cpp
+++ b/source/Expression/FunctionCaller.cpp
@@ -48,7 +48,8 @@ FunctionCaller::FunctionCaller(ExecutionContextScope &exe_scope,
m_function_return_type(return_type),
m_wrapper_function_name("__lldb_caller_function"),
m_wrapper_struct_name("__lldb_caller_struct"), m_wrapper_args_addrs(),
- m_arg_values(arg_value_list), m_compiled(false), m_JITted(false) {
+ m_struct_valid(false), m_arg_values(arg_value_list), m_compiled(false),
+ m_JITted(false) {
m_jit_process_wp = lldb::ProcessWP(exe_scope.CalculateProcess());
// Can't make a FunctionCaller without a process.
assert(m_jit_process_wp.lock());
@@ -90,8 +91,12 @@ bool FunctionCaller::WriteFunctionWrapper(
m_jit_start_addr, m_jit_end_addr, m_execution_unit_sp, exe_ctx,
can_interpret, eExecutionPolicyAlways));
- if (!jit_error.Success())
+ if (!jit_error.Success()) {
+ diagnostic_manager.Printf(eDiagnosticSeverityError,
+ "Error in PrepareForExecution: %s.",
+ jit_error.AsCString());
return false;
+ }
if (m_parser->GetGenerateDebugInfo()) {
lldb::ModuleSP jit_module_sp(m_execution_unit_sp->GetJITModule());
@@ -318,9 +323,9 @@ lldb::ExpressionResults FunctionCaller::ExecuteFunction(
DiagnosticManager &diagnostic_manager, Value &results) {
lldb::ExpressionResults return_value = lldb::eExpressionSetupError;
- // FunctionCaller::ExecuteFunction execution is always just to get the result.
- // Do make sure we ignore
- // breakpoints, unwind on error, and don't try to debug it.
+ // FunctionCaller::ExecuteFunction execution is always just to get the
+ // result. Do make sure we ignore breakpoints, unwind on error, and don't try
+ // to debug it.
EvaluateExpressionOptions real_options = options;
real_options.SetDebug(false);
real_options.SetUnwindOnError(true);
@@ -355,9 +360,8 @@ lldb::ExpressionResults FunctionCaller::ExecuteFunction(
return lldb::eExpressionSetupError;
// We need to make sure we record the fact that we are running an expression
- // here
- // otherwise this fact will fail to be recorded when fetching an Objective-C
- // object description
+ // here otherwise this fact will fail to be recorded when fetching an
+ // Objective-C object description
if (exe_ctx.GetProcessPtr())
exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
diff --git a/source/Expression/IRDynamicChecks.cpp b/source/Expression/IRDynamicChecks.cpp
index 0c8cba2050c0..e0a7dca4113d 100644
--- a/source/Expression/IRDynamicChecks.cpp
+++ b/source/Expression/IRDynamicChecks.cpp
@@ -109,17 +109,17 @@ static std::string PrintValue(llvm::Value *V, bool truncate = false) {
//----------------------------------------------------------------------
/// @class Instrumenter IRDynamicChecks.cpp
-/// @brief Finds and instruments individual LLVM IR instructions
+/// Finds and instruments individual LLVM IR instructions
///
-/// When instrumenting LLVM IR, it is frequently desirable to first search
-/// for instructions, and then later modify them. This way iterators
-/// remain intact, and multiple passes can look at the same code base without
+/// When instrumenting LLVM IR, it is frequently desirable to first search for
+/// instructions, and then later modify them. This way iterators remain
+/// intact, and multiple passes can look at the same code base without
/// treading on each other's toes.
///
/// The Instrumenter class implements this functionality. A client first
-/// calls Inspect on a function, which populates a list of instructions to
-/// be instrumented. Then, later, when all passes' Inspect functions have
-/// been called, the client calls Instrument, which adds the desired
+/// calls Inspect on a function, which populates a list of instructions to be
+/// instrumented. Then, later, when all passes' Inspect functions have been
+/// called, the client calls Instrument, which adds the desired
/// instrumentation.
///
/// A subclass of Instrumenter must override InstrumentInstruction, which
@@ -200,8 +200,8 @@ protected:
}
//------------------------------------------------------------------
- /// Determine whether a single instruction is interesting to
- /// instrument, and, if so, call RegisterInstruction
+ /// Determine whether a single instruction is interesting to instrument,
+ /// and, if so, call RegisterInstruction
///
/// @param[in] i
/// The instruction to be inspected.
@@ -250,8 +250,8 @@ protected:
}
//------------------------------------------------------------------
- /// Build a function pointer for a function with signature
- /// void (*)(uint8_t*) with a given address
+ /// Build a function pointer for a function with signature void
+ /// (*)(uint8_t*) with a given address
///
/// @param[in] start_address
/// The address of the function.
@@ -275,8 +275,8 @@ protected:
}
//------------------------------------------------------------------
- /// Build a function pointer for a function with signature
- /// void (*)(uint8_t*, uint8_t*) with a given address
+ /// Build a function pointer for a function with signature void
+ /// (*)(uint8_t*, uint8_t*) with a given address
///
/// @param[in] start_address
/// The address of the function.
diff --git a/source/Expression/IRExecutionUnit.cpp b/source/Expression/IRExecutionUnit.cpp
index be53f37e0bcc..e34a4c7fac52 100644
--- a/source/Expression/IRExecutionUnit.cpp
+++ b/source/Expression/IRExecutionUnit.cpp
@@ -33,6 +33,7 @@
#include "lldb/Utility/Log.h"
#include "lldb/../../source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
+#include "lldb/../../source/Plugins/ObjectFile/JIT/ObjectFileJIT.h"
using namespace lldb_private;
@@ -362,13 +363,10 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr,
ReportAllocations(*m_execution_engine_ap);
// We have to do this after calling ReportAllocations because for the MCJIT,
- // getGlobalValueAddress
- // will cause the JIT to perform all relocations. That can only be done once,
- // and has to happen
- // after we do the remapping from local -> remote.
- // That means we don't know the local address of the Variables, but we don't
- // need that for anything,
- // so that's okay.
+ // getGlobalValueAddress will cause the JIT to perform all relocations. That
+ // can only be done once, and has to happen after we do the remapping from
+ // local -> remote. That means we don't know the local address of the
+ // Variables, but we don't need that for anything, so that's okay.
std::function<void(llvm::GlobalValue &)> RegisterOneValue = [this](
llvm::GlobalValue &val) {
@@ -379,8 +377,8 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr,
lldb::addr_t remote_addr = GetRemoteAddressForLocal(var_ptr_addr);
// This is a really unfortunae API that sometimes returns local addresses
- // and sometimes returns remote addresses, based on whether
- // the variable was relocated during ReportAllocations or not.
+ // and sometimes returns remote addresses, based on whether the variable
+ // was relocated during ReportAllocations or not.
if (remote_addr == LLDB_INVALID_ADDRESS) {
remote_addr = var_ptr_addr;
@@ -584,33 +582,9 @@ lldb::SectionType IRExecutionUnit::GetSectionTypeFromSectionName(
default:
break;
}
- } else if (name.startswith("__apple_") || name.startswith(".apple_")) {
-#if 0
- const uint32_t name_idx = name[0] == '_' ? 8 : 7;
- llvm::StringRef apple_name(name.substr(name_idx));
- switch (apple_name[0])
- {
- case 'n':
- if (apple_name.equals("names"))
- sect_type = lldb::eSectionTypeDWARFAppleNames;
- else if (apple_name.equals("namespac") || apple_name.equals("namespaces"))
- sect_type = lldb::eSectionTypeDWARFAppleNamespaces;
- break;
- case 't':
- if (apple_name.equals("types"))
- sect_type = lldb::eSectionTypeDWARFAppleTypes;
- break;
- case 'o':
- if (apple_name.equals("objc"))
- sect_type = lldb::eSectionTypeDWARFAppleObjC;
- break;
- default:
- break;
- }
-#else
+ } else if (name.startswith("__apple_") || name.startswith(".apple_"))
sect_type = lldb::eSectionTypeInvalid;
-#endif
- } else if (name.equals("__objc_imageinfo"))
+ else if (name.equals("__objc_imageinfo"))
sect_type = lldb::eSectionTypeOther;
}
return sect_type;
@@ -906,8 +880,8 @@ lldb::addr_t IRExecutionUnit::FindInSymbols(
if (get_external_load_address(load_address, sc_list, sc)) {
return load_address;
}
- // if there are any searches we try after this, add an sc_list.Clear() in an
- // "else" clause here
+ // if there are any searches we try after this, add an sc_list.Clear() in
+ // an "else" clause here
if (best_internal_load_address != LLDB_INVALID_ADDRESS) {
return best_internal_load_address;
@@ -1124,6 +1098,7 @@ bool IRExecutionUnit::CommitOneAllocation(lldb::ProcessSP &process_sp,
case lldb::eSectionTypeDWARFAppleTypes:
case lldb::eSectionTypeDWARFAppleNamespaces:
case lldb::eSectionTypeDWARFAppleObjC:
+ case lldb::eSectionTypeDWARFGNUDebugAltLink:
error.Clear();
break;
default:
@@ -1251,15 +1226,18 @@ bool IRExecutionUnit::GetArchitecture(lldb_private::ArchSpec &arch) {
lldb::ModuleSP IRExecutionUnit::GetJITModule() {
ExecutionContext exe_ctx(GetBestExecutionContextScope());
Target *target = exe_ctx.GetTargetPtr();
- if (target) {
- lldb::ModuleSP jit_module_sp = lldb_private::Module::CreateJITModule(
- std::static_pointer_cast<lldb_private::ObjectFileJITDelegate>(
- shared_from_this()));
- if (jit_module_sp) {
- bool changed = false;
- jit_module_sp->SetLoadAddress(*target, 0, true, changed);
- }
- return jit_module_sp;
- }
- return lldb::ModuleSP();
+ if (!target)
+ return nullptr;
+
+ auto Delegate = std::static_pointer_cast<lldb_private::ObjectFileJITDelegate>(
+ shared_from_this());
+
+ lldb::ModuleSP jit_module_sp =
+ lldb_private::Module::CreateModuleFromObjectFile<ObjectFileJIT>(Delegate);
+ if (!jit_module_sp)
+ return nullptr;
+
+ bool changed = false;
+ jit_module_sp->SetLoadAddress(*target, 0, true, changed);
+ return jit_module_sp;
}
diff --git a/source/Expression/IRInterpreter.cpp b/source/Expression/IRInterpreter.cpp
index a809bff20039..abf86b739f07 100644
--- a/source/Expression/IRInterpreter.cpp
+++ b/source/Expression/IRInterpreter.cpp
@@ -154,16 +154,10 @@ public:
switch (type_size) {
case 1:
- scalar = (uint8_t)u64value;
- break;
case 2:
- scalar = (uint16_t)u64value;
- break;
case 4:
- scalar = (uint32_t)u64value;
- break;
case 8:
- scalar = (uint64_t)u64value;
+ scalar = llvm::APInt(type_size*8, u64value);
break;
default:
return false;
@@ -1567,8 +1561,8 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
return false;
}
- // Push all function arguments to the argument list that will
- // be passed to the call function thread plan
+ // Push all function arguments to the argument list that will be passed
+ // to the call function thread plan
for (int i = 0; i < numArgs; i++) {
// Get details of this argument
llvm::Value *arg_op = call_inst->getArgOperand(i);
diff --git a/source/Expression/IRMemoryMap.cpp b/source/Expression/IRMemoryMap.cpp
index 817c75e66a3b..1953e80852ff 100644
--- a/source/Expression/IRMemoryMap.cpp
+++ b/source/Expression/IRMemoryMap.cpp
@@ -49,8 +49,8 @@ lldb::addr_t IRMemoryMap::FindSpace(size_t size) {
//
// The memory returned by this function will never be written to. The only
// point is that it should not shadow process memory if possible, so that
- // expressions processing real values from the process do not use the
- // wrong data.
+ // expressions processing real values from the process do not use the wrong
+ // data.
//
// If the process can in fact allocate memory (CanJIT() lets us know this)
// then this can be accomplished just be allocating memory in the inferior.
@@ -93,8 +93,8 @@ lldb::addr_t IRMemoryMap::FindSpace(size_t size) {
}
// Now, if it's possible to use the GetMemoryRegionInfo API to detect mapped
- // regions, walk forward through memory until a region is found that
- // has adequate space for our allocation.
+ // regions, walk forward through memory until a region is found that has
+ // adequate space for our allocation.
if (process_is_alive) {
const uint64_t end_of_memory = process_sp->GetAddressByteSize() == 8
? 0xffffffffffffffffull
@@ -188,16 +188,12 @@ bool IRMemoryMap::IntersectsAllocation(lldb::addr_t addr, size_t size) const {
AllocationMap::const_iterator iter = m_allocations.lower_bound(addr);
// Since we only know that the returned interval begins at a location greater
- // than or
- // equal to where the given interval begins, it's possible that the given
- // interval
- // intersects either the returned interval or the previous interval. Thus, we
- // need to
- // check both. Note that we only need to check these two intervals. Since all
- // intervals
- // are disjoint it is not possible that an adjacent interval does not
- // intersect, but a
- // non-adjacent interval does intersect.
+ // than or equal to where the given interval begins, it's possible that the
+ // given interval intersects either the returned interval or the previous
+ // interval. Thus, we need to check both. Note that we only need to check
+ // these two intervals. Since all intervals are disjoint it is not possible
+ // that an adjacent interval does not intersect, but a non-adjacent interval
+ // does intersect.
if (iter != m_allocations.end()) {
if (AllocationsIntersect(addr, size, iter->second.m_process_start,
iter->second.m_size))
@@ -217,16 +213,15 @@ bool IRMemoryMap::IntersectsAllocation(lldb::addr_t addr, size_t size) const {
bool IRMemoryMap::AllocationsIntersect(lldb::addr_t addr1, size_t size1,
lldb::addr_t addr2, size_t size2) {
// Given two half open intervals [A, B) and [X, Y), the only 6 permutations
- // that satisfy
- // A<B and X<Y are the following:
+ // that satisfy A<B and X<Y are the following:
// A B X Y
// A X B Y (intersects)
// A X Y B (intersects)
// X A B Y (intersects)
// X A Y B (intersects)
// X Y A B
- // The first is B <= X, and the last is Y <= A.
- // So the condition is !(B <= X || Y <= A)), or (X < B && A < Y)
+ // The first is B <= X, and the last is Y <= A. So the condition is !(B <= X
+ // || Y <= A)), or (X < B && A < Y)
return (addr2 < (addr1 + size1)) && (addr1 < (addr2 + size2));
}
@@ -306,15 +301,21 @@ lldb::addr_t IRMemoryMap::Malloc(size_t size, uint8_t alignment,
lldb::addr_t allocation_address = LLDB_INVALID_ADDRESS;
lldb::addr_t aligned_address = LLDB_INVALID_ADDRESS;
- size_t alignment_mask = alignment - 1;
size_t allocation_size;
- if (size == 0)
+ if (size == 0) {
+ // FIXME: Malloc(0) should either return an invalid address or assert, in
+ // order to cut down on unnecessary allocations.
allocation_size = alignment;
- else
- allocation_size = (size & alignment_mask)
- ? ((size + alignment) & (~alignment_mask))
- : size;
+ } else {
+ // Round up the requested size to an aligned value.
+ allocation_size = llvm::alignTo(size, alignment);
+
+ // The process page cache does not see the requested alignment. We can't
+ // assume its result will be any more than 1-byte aligned. To work around
+ // this, request `alignment - 1` additional bytes.
+ allocation_size += alignment - 1;
+ }
switch (policy) {
default:
diff --git a/source/Expression/LLVMUserExpression.cpp b/source/Expression/LLVMUserExpression.cpp
index 83acb8249ba6..fc32bfbd37a2 100644
--- a/source/Expression/LLVMUserExpression.cpp
+++ b/source/Expression/LLVMUserExpression.cpp
@@ -74,9 +74,8 @@ LLVMUserExpression::DoExecute(DiagnosticManager &diagnostic_manager,
lldb::UserExpressionSP &shared_ptr_to_me,
lldb::ExpressionVariableSP &result) {
// The expression log is quite verbose, and if you're just tracking the
- // execution of the
- // expression, it's quite convenient to have these logs come out with the STEP
- // log as well.
+ // execution of the expression, it's quite convenient to have these logs come
+ // out with the STEP log as well.
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS |
LIBLLDB_LOG_STEP));
diff --git a/source/Expression/Materializer.cpp b/source/Expression/Materializer.cpp
index 39fc5c8c2539..74a965e015ce 100644
--- a/source/Expression/Materializer.cpp
+++ b/source/Expression/Materializer.cpp
@@ -77,7 +77,8 @@ public:
void MakeAllocation(IRMemoryMap &map, Status &err) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- // Allocate a spare memory area to store the persistent variable's contents.
+ // Allocate a spare memory area to store the persistent variable's
+ // contents.
Status allocate_error;
const bool zero_memory = false;
@@ -230,8 +231,8 @@ public:
ExpressionVariable::EVIsProgramReference &&
!m_persistent_variable_sp->m_live_sp) {
// If the reference comes from the program, then the
- // ClangExpressionVariable's
- // live variable data hasn't been set up yet. Do this now.
+ // ClangExpressionVariable's live variable data hasn't been set up yet.
+ // Do this now.
lldb::addr_t location;
Status read_error;
@@ -256,10 +257,8 @@ public:
frame_bottom != LLDB_INVALID_ADDRESS && location >= frame_bottom &&
location <= frame_top) {
// If the variable is resident in the stack frame created by the
- // expression,
- // then it cannot be relied upon to stay around. We treat it as
- // needing
- // reallocation.
+ // expression, then it cannot be relied upon to stay around. We
+ // treat it as needing reallocation.
m_persistent_variable_sp->m_flags |=
ExpressionVariable::EVIsLLDBAllocated;
m_persistent_variable_sp->m_flags |=
@@ -889,9 +888,11 @@ public:
return;
}
- ConstString name = m_delegate
- ? m_delegate->GetName()
- : persistent_state->GetNextPersistentVariableName();
+ ConstString name =
+ m_delegate
+ ? m_delegate->GetName()
+ : persistent_state->GetNextPersistentVariableName(
+ *target_sp, persistent_state->GetPersistentVariablePrefix());
lldb::ExpressionVariableSP ret = persistent_state->CreatePersistentVariable(
exe_scope, name, m_type, map.GetByteOrder(), map.GetAddressByteSize());
diff --git a/source/Expression/REPL.cpp b/source/Expression/REPL.cpp
index 84a6405f3268..a441e381985c 100644
--- a/source/Expression/REPL.cpp
+++ b/source/Expression/REPL.cpp
@@ -61,10 +61,8 @@ lldb::REPLSP REPL::Create(Status &err, lldb::LanguageType language,
std::string REPL::GetSourcePath() {
ConstString file_basename = GetSourceFileBasename();
-
- FileSpec tmpdir_file_spec;
- if (HostInfo::GetLLDBPath(lldb::ePathTypeLLDBTempSystemDir,
- tmpdir_file_spec)) {
+ FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir();
+ if (tmpdir_file_spec) {
tmpdir_file_spec.GetFilename().SetCString(file_basename.AsCString());
m_repl_source_path = tmpdir_file_spec.GetPath();
} else {
@@ -243,10 +241,8 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) {
IOHandler::Type::REPL, IOHandler::Type::CommandInterpreter)) {
// We typed "quit" or an alias to quit so we need to check if the
// command interpreter is above us and tell it that it is done as
- // well
- // so we don't drop back into the command interpreter if we have
- // already
- // quit
+ // well so we don't drop back into the command interpreter if we
+ // have already quit
lldb::IOHandlerSP io_handler_sp(ci.GetIOHandler());
if (io_handler_sp)
io_handler_sp->SetIsDone(true);
@@ -444,8 +440,8 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) {
}
}
- // Don't complain about the REPL process going away if we are in the process
- // of quitting.
+ // Don't complain about the REPL process going away if we are in the
+ // process of quitting.
if (!did_quit && (!process_sp || !process_sp->IsAlive())) {
error_sp->Printf(
"error: REPL process is no longer alive, exiting REPL\n");
@@ -542,11 +538,9 @@ Status REPL::RunLoop() {
debugger.PushIOHandler(io_handler_sp);
- // Check if we are in dedicated REPL mode where LLDB was start with the
- // "--repl" option
- // from the command line. Currently we know this by checking if the debugger
- // already
- // has a IOHandler thread.
+ // Check if we are in dedicated REPL mode where LLDB was start with the "--
+ // repl" option from the command line. Currently we know this by checking if
+ // the debugger already has a IOHandler thread.
if (!debugger.HasIOHandlerThread()) {
// The debugger doesn't have an existing IOHandler thread, so this must be
// dedicated REPL mode...
@@ -566,8 +560,8 @@ Status REPL::RunLoop() {
io_handler_sp->WaitForPop();
if (m_dedicated_repl_mode) {
- // If we were in dedicated REPL mode we would have started the
- // IOHandler thread, and we should kill our process
+ // If we were in dedicated REPL mode we would have started the IOHandler
+ // thread, and we should kill our process
lldb::ProcessSP process_sp = m_target.GetProcessSP();
if (process_sp && process_sp->IsAlive())
process_sp->Destroy(false);
diff --git a/source/Expression/UserExpression.cpp b/source/Expression/UserExpression.cpp
index 3386bc4577ae..34945fdcbfa1 100644
--- a/source/Expression/UserExpression.cpp
+++ b/source/Expression/UserExpression.cpp
@@ -179,9 +179,8 @@ lldb::ExpressionResults UserExpression::Evaluate(
execution_policy = eExecutionPolicyNever;
// We need to set the expression execution thread here, turns out parse can
- // call functions in the process of
- // looking up symbols, which will escape the context set by exe_ctx passed to
- // Execute.
+ // call functions in the process of looking up symbols, which will escape the
+ // context set by exe_ctx passed to Execute.
lldb::ThreadSP thread_sp = exe_ctx.GetThreadSP();
ThreadList::ExpressionExecutionThreadPusher execution_thread_pusher(
thread_sp);
@@ -198,9 +197,9 @@ lldb::ExpressionResults UserExpression::Evaluate(
else
full_prefix = option_prefix;
- // If the language was not specified in the expression command,
- // set it to the language in the target's properties if
- // specified, else default to the langage for the frame.
+ // If the language was not specified in the expression command, set it to the
+ // language in the target's properties if specified, else default to the
+ // langage for the frame.
if (language == lldb::eLanguageTypeUnknown) {
if (target->GetLanguage() != lldb::eLanguageTypeUnknown)
language = target->GetLanguage();
diff --git a/source/Host/CMakeLists.txt b/source/Host/CMakeLists.txt
index 2b6f0e48a3f2..5a92447edf30 100644
--- a/source/Host/CMakeLists.txt
+++ b/source/Host/CMakeLists.txt
@@ -3,6 +3,18 @@ macro(add_host_subdirectory group)
source_group(${group} FILES ${ARGN})
endmacro()
+# Removes all module flags from the current CMAKE_CXX_FLAGS. Used for
+# the Objective-C++ code in lldb which we don't want to build with modules.
+# Reasons for this are that modules with Objective-C++ would require that
+# all LLVM/Clang modules are Objective-C++ compatible (which they are likely
+# not) and we would have rebuild a second set of modules just for the few
+# Objective-C++ files in lldb (which slows down the build process).
+macro(remove_module_flags)
+ string(REGEX REPLACE "-fmodules-cache-path=[^ ]+" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+ string(REGEX REPLACE "-fmodules" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+ string(REGEX REPLACE "-fcxx-modules" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+endmacro()
+
add_host_subdirectory(common
common/File.cpp
common/FileCache.cpp
@@ -39,11 +51,6 @@ add_host_subdirectory(common
common/UDPSocket.cpp
)
-# Keep track of whether we want to provide a define for the
-# Python's architecture-specific lib path (i.e. where a
-# Python lldb module would go).
-set (get_python_libdir 0)
-
if (NOT LLDB_DISABLE_LIBEDIT)
add_host_subdirectory(common
common/Editline.cpp
@@ -54,10 +61,6 @@ add_host_subdirectory(posix
posix/ConnectionFileDescriptorPosix.cpp
)
-if(NOT LLDB_DISABLE_PYTHON)
- list(APPEND LLDB_PLUGINS lldbPluginScriptInterpreterPython)
-endif()
-
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
add_host_subdirectory(windows
windows/ConnectionGenericFileWindows.cpp
@@ -74,11 +77,6 @@ if (CMAKE_SYSTEM_NAME MATCHES "Windows")
windows/Windows.cpp
)
else()
- if (NOT LLDB_DISABLE_PYTHON)
- # We'll grab the arch-specific python libdir on POSIX systems.
- set (get_python_libdir 1)
- endif()
-
add_host_subdirectory(posix
posix/DomainSocket.cpp
posix/FileSystem.cpp
@@ -92,10 +90,9 @@ else()
if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
include_directories(SYSTEM ${LIBXML2_INCLUDE_DIR})
- add_host_subdirectory(macosx
- macosx/Host.mm
- macosx/HostInfoMacOSX.mm
- macosx/HostThreadMacOSX.mm
+ add_subdirectory(macosx/objcxx)
+ set(LLDBObjCLibs lldbHostMacOSXObjCXX)
+ add_host_subdirectory(maqcosx
macosx/Symbols.cpp
macosx/cfcpp/CFCBundle.cpp
macosx/cfcpp/CFCData.cpp
@@ -144,19 +141,6 @@ else()
endif()
endif()
-if (${get_python_libdir})
- # Call a python script to gather the arch-specific libdir for
- # modules like the lldb module.
- execute_process(
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../../scripts/get_relative_lib_dir.py
- RESULT_VARIABLE get_libdir_status
- OUTPUT_VARIABLE relative_libdir
- )
- if (get_libdir_status EQUAL 0)
- add_definitions(-DLLDB_PYTHON_RELATIVE_LIBDIR="${relative_libdir}")
- endif()
-endif()
-
set(EXTRA_LIBS)
if (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
list(APPEND EXTRA_LIBS kvm)
@@ -177,16 +161,16 @@ endif()
add_lldb_library(lldbHost
${HOST_SOURCES}
-
+
LINK_LIBS
lldbCore
- lldbInterpreter
lldbSymbol
lldbTarget
lldbUtility
- ${LLDB_PLUGINS}
${EXTRA_LIBS}
-
+ ${LLDBObjCLibs}
+
LINK_COMPONENTS
+ Object
Support
)
diff --git a/source/Host/android/HostInfoAndroid.cpp b/source/Host/android/HostInfoAndroid.cpp
index 27ce17a76d70..a96033283212 100644
--- a/source/Host/android/HostInfoAndroid.cpp
+++ b/source/Host/android/HostInfoAndroid.cpp
@@ -79,13 +79,10 @@ bool HostInfoAndroid::ComputeTempFileBaseDirectory(FileSpec &file_spec) {
bool success = HostInfoLinux::ComputeTempFileBaseDirectory(file_spec);
// On Android, there is no path which is guaranteed to be writable. If the
- // user has not
- // provided a path via an environment variable, the generic algorithm will
- // deduce /tmp, which
- // is plain wrong. In that case we have an invalid directory, we substitute
- // the path with
- // /data/local/tmp, which is correct at least in some cases (i.e., when
- // running as shell user).
+ // user has not provided a path via an environment variable, the generic
+ // algorithm will deduce /tmp, which is plain wrong. In that case we have an
+ // invalid directory, we substitute the path with /data/local/tmp, which is
+ // correct at least in some cases (i.e., when running as shell user).
if (!success || !file_spec.Exists())
file_spec = FileSpec("/data/local/tmp", false);
diff --git a/source/Host/common/Editline.cpp b/source/Host/common/Editline.cpp
index 7b580dde656a..329c0c1f3b70 100644
--- a/source/Host/common/Editline.cpp
+++ b/source/Host/common/Editline.cpp
@@ -33,8 +33,8 @@ using namespace lldb_private::line_editor;
// doesn't explicitly initialize the curses termcap library, which it gets away
// with until TERM is set to VT100 where it stumbles over an implementation
// assumption that may not exist on other platforms. The setupterm() function
-// would normally require headers that don't work gracefully in this context, so
-// the function declaraction has been hoisted here.
+// would normally require headers that don't work gracefully in this context,
+// so the function declaraction has been hoisted here.
#if defined(__APPLE__)
extern "C" {
int setupterm(char *term, int fildes, int *errret);
@@ -43,12 +43,10 @@ int setupterm(char *term, int fildes, int *errret);
#endif
// Editline uses careful cursor management to achieve the illusion of editing a
-// multi-line block of text
-// with a single line editor. Preserving this illusion requires fairly careful
-// management of cursor
-// state. Read and understand the relationship between DisplayInput(),
-// MoveCursor(), SetCurrentLine(),
-// and SaveEditedLine() before making changes.
+// multi-line block of text with a single line editor. Preserving this
+// illusion requires fairly careful management of cursor state. Read and
+// understand the relationship between DisplayInput(), MoveCursor(),
+// SetCurrentLine(), and SaveEditedLine() before making changes.
#define ESCAPE "\x1b"
#define ANSI_FAINT ESCAPE "[2m"
@@ -70,8 +68,7 @@ int setupterm(char *term, int fildes, int *errret);
#define EditLineStringFormatSpec "%s"
// use #defines so wide version functions and structs will resolve to old
-// versions
-// for case of libedit not built with wide char support
+// versions for case of libedit not built with wide char support
#define history_w history
#define history_winit history_init
#define history_wend history_end
@@ -145,10 +142,8 @@ bool IsInputPending(FILE *file) {
// FIXME: This will be broken on Windows if we ever re-enable Editline. You
// can't use select
// on something that isn't a socket. This will have to be re-written to not
- // use a FILE*, but
- // instead use some kind of yet-to-be-created abstraction that select-like
- // functionality on
- // non-socket objects.
+ // use a FILE*, but instead use some kind of yet-to-be-created abstraction
+ // that select-like functionality on non-socket objects.
const int fd = fileno(file);
SelectHelper select_helper;
select_helper.SetTimeout(std::chrono::microseconds(0));
@@ -160,13 +155,13 @@ namespace lldb_private {
namespace line_editor {
typedef std::weak_ptr<EditlineHistory> EditlineHistoryWP;
-// EditlineHistory objects are sometimes shared between multiple
-// Editline instances with the same program name.
+// EditlineHistory objects are sometimes shared between multiple Editline
+// instances with the same program name.
class EditlineHistory {
private:
- // Use static GetHistory() function to get a EditlineHistorySP to one of these
- // objects
+ // Use static GetHistory() function to get a EditlineHistorySP to one of
+ // these objects
EditlineHistory(const std::string &prefix, uint32_t size, bool unique_entries)
: m_history(NULL), m_event(), m_prefix(prefix), m_path() {
m_history = history_winit();
@@ -436,11 +431,10 @@ unsigned char Editline::RecallHistory(bool earlier) {
if (history_w(pHistory, &history_event, H_FIRST) == -1)
return CC_ERROR;
- // Save any edits to the "live" entry in case we return by moving forward in
- // history
- // (it would be more bash-like to save over any current entry, but libedit
- // doesn't
- // offer the ability to add entries anywhere except the end.)
+ // Save any edits to the "live" entry in case we return by moving forward
+ // in history (it would be more bash-like to save over any current entry,
+ // but libedit doesn't offer the ability to add entries anywhere except the
+ // end.)
SaveEditedLine();
m_live_history_lines = m_input_lines;
m_in_history = true;
@@ -466,8 +460,7 @@ unsigned char Editline::RecallHistory(bool earlier) {
DisplayInput();
// Prepare to edit the last line when moving to previous entry, or the first
- // line
- // when moving to next entry
+ // line when moving to next entry
SetCurrentLine(m_current_line_index =
earlier ? (int)m_input_lines.size() - 1 : 0);
MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingPrompt);
@@ -490,8 +483,8 @@ int Editline::GetCharacter(EditLineGetCharType *c) {
}
if (m_multiline_enabled) {
- // Detect when the number of rows used for this input line changes due to an
- // edit
+ // Detect when the number of rows used for this input line changes due to
+ // an edit
int lineLength = (int)((info->lastchar - info->buffer) + GetPromptWidth());
int new_line_rows = (lineLength / m_terminal_width) + 1;
if (m_current_line_rows != -1 && new_line_rows != m_current_line_rows) {
@@ -510,12 +503,10 @@ int Editline::GetCharacter(EditLineGetCharType *c) {
char ch = 0;
// This mutex is locked by our caller (GetLine). Unlock it while we read a
- // character
- // (blocking operation), so we do not hold the mutex indefinitely. This
- // gives a chance
- // for someone to interrupt us. After Read returns, immediately lock the
- // mutex again and
- // check if we were interrupted.
+ // character (blocking operation), so we do not hold the mutex
+ // indefinitely. This gives a chance for someone to interrupt us. After
+ // Read returns, immediately lock the mutex again and check if we were
+ // interrupted.
m_output_mutex.unlock();
int read_count = m_input_connection.Read(&ch, 1, llvm::None, status, NULL);
m_output_mutex.lock();
@@ -614,7 +605,8 @@ unsigned char Editline::EndOrAddLineCommand(int ch) {
// Save any edits to this line
SaveEditedLine();
- // If this is the end of the last line, consider whether to add a line instead
+ // If this is the end of the last line, consider whether to add a line
+ // instead
const LineInfoW *info = el_wline(m_editline);
if (m_current_line_index == m_input_lines.size() - 1 &&
info->cursor == info->lastchar) {
@@ -653,8 +645,8 @@ unsigned char Editline::DeleteNextCharCommand(int ch) {
return CC_REFRESH;
}
- // Fail when at the end of the last line, except when ^D is pressed on
- // the line is empty, in which case it is treated as EOF
+ // Fail when at the end of the last line, except when ^D is pressed on the
+ // line is empty, in which case it is treated as EOF
if (m_current_line_index == m_input_lines.size() - 1) {
if (ch == 4 && info->buffer == info->lastchar) {
fprintf(m_output_file, "^D\n");
@@ -685,7 +677,8 @@ unsigned char Editline::DeleteNextCharCommand(int ch) {
unsigned char Editline::DeletePreviousCharCommand(int ch) {
LineInfoW *info = const_cast<LineInfoW *>(el_wline(m_editline));
- // Just delete the previous character normally when not at the start of a line
+ // Just delete the previous character normally when not at the start of a
+ // line
if (info->cursor > info->buffer) {
el_deletestr(m_editline, 1);
return CC_REFRESH;
@@ -709,8 +702,7 @@ unsigned char Editline::DeletePreviousCharCommand(int ch) {
DisplayInput(m_current_line_index);
// Put the cursor back where libedit expects it to be before returning to
- // editing
- // by telling libedit about the newly inserted text
+ // editing by telling libedit about the newly inserted text
MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingPrompt);
el_winsertstr(m_editline, priorLine.c_str());
return CC_REDISPLAY;
@@ -762,7 +754,8 @@ unsigned char Editline::NextLineCommand(int ch) {
EditLineStringType(indentation, EditLineCharType(' ')));
}
- // Move down past the current line using newlines to force scrolling if needed
+ // Move down past the current line using newlines to force scrolling if
+ // needed
SetCurrentLine(m_current_line_index + 1);
const LineInfoW *info = el_wline(m_editline);
int cursor_position = (int)((info->cursor - info->buffer) + GetPromptWidth());
@@ -824,8 +817,7 @@ unsigned char Editline::FixIndentationCommand(int ch) {
DisplayInput(m_current_line_index);
// Reposition the cursor back on the original line and prepare to restart
- // editing
- // with a new cursor position
+ // editing with a new cursor position
SetCurrentLine(m_current_line_index);
MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingPrompt);
m_revert_cursor_index = cursor_position + indent_correction;
@@ -945,9 +937,9 @@ void Editline::ConfigureEditor(bool multiline) {
m_multiline_enabled = multiline;
if (m_editline) {
- // Disable edit mode to stop the terminal from flushing all input
- // during the call to el_end() since we expect to have multiple editline
- // instances in this program.
+ // Disable edit mode to stop the terminal from flushing all input during
+ // the call to el_end() since we expect to have multiple editline instances
+ // in this program.
el_set(m_editline, EL_EDITMODE, 0);
el_end(m_editline);
}
@@ -973,7 +965,8 @@ void Editline::ConfigureEditor(bool multiline) {
return Editline::InstanceFor(editline)->GetCharacter(c);
}));
- // Commands used for multiline support, registered whether or not they're used
+ // Commands used for multiline support, registered whether or not they're
+ // used
el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-break-line"),
EditLineConstString("Insert a line break"),
(EditlineCommandCallbackType)([](EditLine *editline, int ch) {
@@ -1031,13 +1024,11 @@ void Editline::ConfigureEditor(bool multiline) {
return Editline::InstanceFor(editline)->FixIndentationCommand(ch);
}));
- // Register the complete callback under two names for compatibility with older
- // clients using
- // custom .editrc files (largely because libedit has a bad bug where if you
- // have a bind command
- // that tries to bind to a function name that doesn't exist, it can corrupt
- // the heap and
- // crash your process later.)
+ // Register the complete callback under two names for compatibility with
+ // older clients using custom .editrc files (largely because libedit has a
+ // bad bug where if you have a bind command that tries to bind to a function
+ // name that doesn't exist, it can corrupt the heap and crash your process
+ // later.)
EditlineCommandCallbackType complete_callback = [](EditLine *editline,
int ch) {
return Editline::InstanceFor(editline)->TabCommand(ch);
@@ -1118,8 +1109,7 @@ void Editline::ConfigureEditor(bool multiline) {
NULL);
// Escape is absorbed exiting edit mode, so re-register important
- // sequences
- // without the prefix
+ // sequences without the prefix
el_set(m_editline, EL_BIND, "-a", "[A", "lldb-previous-line", NULL);
el_set(m_editline, EL_BIND, "-a", "[B", "lldb-next-line", NULL);
el_set(m_editline, EL_BIND, "-a", "[\\^", "lldb-revert-line", NULL);
@@ -1176,18 +1166,18 @@ Editline::Editline(const char *editline_name, FILE *input_file,
Editline::~Editline() {
if (m_editline) {
- // Disable edit mode to stop the terminal from flushing all input
- // during the call to el_end() since we expect to have multiple editline
- // instances in this program.
+ // Disable edit mode to stop the terminal from flushing all input during
+ // the call to el_end() since we expect to have multiple editline instances
+ // in this program.
el_set(m_editline, EL_EDITMODE, 0);
el_end(m_editline);
m_editline = nullptr;
}
- // EditlineHistory objects are sometimes shared between multiple
- // Editline instances with the same program name. So just release
- // our shared pointer and if we are the last owner, it will save the
- // history to the history save file automatically.
+ // EditlineHistory objects are sometimes shared between multiple Editline
+ // instances with the same program name. So just release our shared pointer
+ // and if we are the last owner, it will save the history to the history save
+ // file automatically.
m_history_sp.reset();
}
@@ -1313,8 +1303,8 @@ bool Editline::GetLines(int first_line_number, StringList &lines,
bool &interrupted) {
ConfigureEditor(true);
- // Print the initial input lines, then move the cursor back up to the start of
- // input
+ // Print the initial input lines, then move the cursor back up to the start
+ // of input
SetBaseLineNumber(first_line_number);
m_input_lines = std::vector<EditLineStringType>();
m_input_lines.insert(m_input_lines.begin(), EditLineConstString(""));
diff --git a/source/Host/common/File.cpp b/source/Host/common/File.cpp
index 6ee4e894756b..3c3d55df2207 100644
--- a/source/Host/common/File.cpp
+++ b/source/Host/common/File.cpp
@@ -100,7 +100,7 @@ int File::GetDescriptor() const {
// Don't open the file descriptor if we don't need to, just get it from the
// stream if we have one.
if (StreamIsValid()) {
-#if defined(LLVM_ON_WIN32)
+#if defined(_WIN32)
return _fileno(m_stream);
#else
return fileno(m_stream);
@@ -126,8 +126,8 @@ FILE *File::GetStream() {
const char *mode = GetStreamOpenModeFromOptions(m_options);
if (mode) {
if (!m_should_close_fd) {
-// We must duplicate the file descriptor if we don't own it because
-// when you call fdopen, the stream will own the fd
+// We must duplicate the file descriptor if we don't own it because when you
+// call fdopen, the stream will own the fd
#ifdef _WIN32
m_descriptor = ::_dup(GetDescriptor());
#else
@@ -139,8 +139,8 @@ FILE *File::GetStream() {
m_stream =
llvm::sys::RetryAfterSignal(nullptr, ::fdopen, m_descriptor, mode);
- // If we got a stream, then we own the stream and should no
- // longer own the descriptor because fclose() will close it for us
+ // If we got a stream, then we own the stream and should no longer own
+ // the descriptor because fclose() will close it for us
if (m_stream) {
m_own_stream = true;
@@ -315,7 +315,7 @@ Status File::GetFileSpec(FileSpec &file_spec) const {
if (::fcntl(GetDescriptor(), F_GETPATH, path) == -1)
error.SetErrorToErrno();
else
- file_spec.SetFile(path, false);
+ file_spec.SetFile(path, false, FileSpec::Style::native);
} else {
error.SetErrorString("invalid file handle");
}
@@ -330,7 +330,7 @@ Status File::GetFileSpec(FileSpec &file_spec) const {
error.SetErrorToErrno();
else {
path[len] = '\0';
- file_spec.SetFile(path, false);
+ file_spec.SetFile(path, false, FileSpec::Style::native);
}
}
#else
diff --git a/source/Host/common/Host.cpp b/source/Host/common/Host.cpp
index 97581185ad9e..d2848254779e 100644
--- a/source/Host/common/Host.cpp
+++ b/source/Host/common/Host.cpp
@@ -59,7 +59,6 @@
#include "lldb/Target/FileAction.h"
#include "lldb/Target/ProcessLaunchInfo.h"
#include "lldb/Target/UnixSignals.h"
-#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/DataBufferLLVM.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
@@ -120,9 +119,8 @@ HostThread Host::StartMonitoringChildProcess(
#ifndef __linux__
//------------------------------------------------------------------
-// Scoped class that will disable thread canceling when it is
-// constructed, and exception safely restore the previous value it
-// when it goes out of scope.
+// Scoped class that will disable thread canceling when it is constructed, and
+// exception safely restore the previous value it when it goes out of scope.
//------------------------------------------------------------------
class ScopedPThreadCancelDisabler {
public:
@@ -271,8 +269,7 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) {
__FUNCTION__, arg);
break;
}
- // If the callback returns true, it means this process should
- // exit
+ // If the callback returns true, it means this process should exit
if (callback_return) {
if (log)
log->Printf("%s (arg = %p) thread exiting because callback "
@@ -423,7 +420,7 @@ FileSpec Host::GetModuleFileSpecForHostAddress(const void *host_addr) {
Dl_info info;
if (::dladdr(host_addr, &info)) {
if (info.dli_fname)
- module_filespec.SetFile(info.dli_fname, true);
+ module_filespec.SetFile(info.dli_fname, true, FileSpec::Style::native);
}
#endif
return module_filespec;
@@ -466,15 +463,17 @@ MonitorShellCommand(std::shared_ptr<ShellInfo> shell_info, lldb::pid_t pid,
Status Host::RunShellCommand(const char *command, const FileSpec &working_dir,
int *status_ptr, int *signo_ptr,
std::string *command_output_ptr,
- uint32_t timeout_sec, bool run_in_default_shell) {
+ const Timeout<std::micro> &timeout,
+ bool run_in_default_shell) {
return RunShellCommand(Args(command), working_dir, status_ptr, signo_ptr,
- command_output_ptr, timeout_sec, run_in_default_shell);
+ command_output_ptr, timeout, run_in_default_shell);
}
Status Host::RunShellCommand(const Args &args, const FileSpec &working_dir,
int *status_ptr, int *signo_ptr,
std::string *command_output_ptr,
- uint32_t timeout_sec, bool run_in_default_shell) {
+ const Timeout<std::micro> &timeout,
+ bool run_in_default_shell) {
Status error;
ProcessLaunchInfo launch_info;
launch_info.SetArchitecture(HostInfo::GetArchitecture());
@@ -498,11 +497,10 @@ Status Host::RunShellCommand(const Args &args, const FileSpec &working_dir,
llvm::SmallString<PATH_MAX> output_file_path;
if (command_output_ptr) {
- // Create a temporary file to get the stdout/stderr and redirect the
- // output of the command into this file. We will later read this file
- // if all goes well and fill the data into "command_output_ptr"
- FileSpec tmpdir_file_spec;
- if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) {
+ // Create a temporary file to get the stdout/stderr and redirect the output
+ // of the command into this file. We will later read this file if all goes
+ // well and fill the data into "command_output_ptr"
+ if (FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir()) {
tmpdir_file_spec.AppendPathComponent("lldb-shell-output.%%%%%%");
llvm::sys::fs::createUniqueFile(tmpdir_file_spec.GetPath(),
output_file_path);
@@ -539,18 +537,14 @@ Status Host::RunShellCommand(const Args &args, const FileSpec &working_dir,
error.SetErrorString("failed to get process ID");
if (error.Success()) {
- bool timed_out = false;
- shell_info_sp->process_reaped.WaitForValueEqualTo(
- true, std::chrono::seconds(timeout_sec), &timed_out);
- if (timed_out) {
+ if (!shell_info_sp->process_reaped.WaitForValueEqualTo(true, timeout)) {
error.SetErrorString("timed out waiting for shell command to complete");
// Kill the process since it didn't complete within the timeout specified
Kill(pid, SIGKILL);
// Wait for the monitor callback to get the message
- timed_out = false;
shell_info_sp->process_reaped.WaitForValueEqualTo(
- true, std::chrono::seconds(1), &timed_out);
+ true, std::chrono::seconds(1));
} else {
if (status_ptr)
*status_ptr = shell_info_sp->status;
@@ -581,7 +575,8 @@ Status Host::RunShellCommand(const Args &args, const FileSpec &working_dir,
return error;
}
-// The functions below implement process launching for non-Apple-based platforms
+// The functions below implement process launching for non-Apple-based
+// platforms
#if !defined(__APPLE__)
Status Host::LaunchProcess(ProcessLaunchInfo &launch_info) {
std::unique_ptr<ProcessLauncher> delegate_launcher;
@@ -596,8 +591,7 @@ Status Host::LaunchProcess(ProcessLaunchInfo &launch_info) {
HostProcess process = launcher.LaunchProcess(launch_info, error);
// TODO(zturner): It would be better if the entire HostProcess were returned
- // instead of writing
- // it into this structure.
+ // instead of writing it into this structure.
launch_info.SetProcessID(process.GetProcessId());
return error;
diff --git a/source/Host/common/HostInfoBase.cpp b/source/Host/common/HostInfoBase.cpp
index aff887f9f1d2..4de6953a91e3 100644
--- a/source/Host/common/HostInfoBase.cpp
+++ b/source/Host/common/HostInfoBase.cpp
@@ -33,19 +33,19 @@ using namespace lldb_private;
namespace {
//----------------------------------------------------------------------
-// The HostInfoBaseFields is a work around for windows not supporting
-// static variables correctly in a thread safe way. Really each of the
-// variables in HostInfoBaseFields should live in the functions in which
-// they are used and each one should be static, but the work around is
-// in place to avoid this restriction. Ick.
+// The HostInfoBaseFields is a work around for windows not supporting static
+// variables correctly in a thread safe way. Really each of the variables in
+// HostInfoBaseFields should live in the functions in which they are used and
+// each one should be static, but the work around is in place to avoid this
+// restriction. Ick.
//----------------------------------------------------------------------
struct HostInfoBaseFields {
~HostInfoBaseFields() {
if (m_lldb_process_tmp_dir.Exists()) {
// Remove the LLDB temporary directory if we have one. Set "recurse" to
- // true to all files that were created for the LLDB process can be cleaned
- // up.
+ // true to all files that were created for the LLDB process can be
+ // cleaned up.
llvm::sys::fs::remove_directories(m_lldb_process_tmp_dir.GetPath());
}
}
@@ -58,7 +58,6 @@ struct HostInfoBaseFields {
FileSpec m_lldb_so_dir;
FileSpec m_lldb_support_exe_dir;
FileSpec m_lldb_headers_dir;
- FileSpec m_lldb_python_dir;
FileSpec m_lldb_clang_resource_dir;
FileSpec m_lldb_system_plugin_dir;
FileSpec m_lldb_user_plugin_dir;
@@ -111,152 +110,88 @@ llvm::Optional<HostInfoBase::ArchitectureKind> HostInfoBase::ParseArchitectureKi
.Default(llvm::None);
}
-bool HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec) {
- file_spec.Clear();
+FileSpec HostInfoBase::GetShlibDir() {
+ static llvm::once_flag g_once_flag;
+ static bool success = false;
+ llvm::call_once(g_once_flag, []() {
+ success = HostInfo::ComputeSharedLibraryDirectory(g_fields->m_lldb_so_dir);
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ LLDB_LOG(log, "shlib dir -> `{0}`", g_fields->m_lldb_so_dir);
+ });
+ return success ? g_fields->m_lldb_so_dir : FileSpec();
+}
-#if defined(LLDB_DISABLE_PYTHON)
- if (type == lldb::ePathTypePythonDir)
- return false;
-#endif
+FileSpec HostInfoBase::GetSupportExeDir() {
+ static llvm::once_flag g_once_flag;
+ static bool success = false;
+ llvm::call_once(g_once_flag, []() {
+ success =
+ HostInfo::ComputeSupportExeDirectory(g_fields->m_lldb_support_exe_dir);
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ LLDB_LOG(log, "support exe dir -> `{0}`", g_fields->m_lldb_support_exe_dir);
+ });
+ return success ? g_fields->m_lldb_support_exe_dir : FileSpec();
+}
- FileSpec *result = nullptr;
- switch (type) {
- case lldb::ePathTypeLLDBShlibDir: {
- static llvm::once_flag g_once_flag;
- static bool success = false;
- llvm::call_once(g_once_flag, []() {
- success =
- HostInfo::ComputeSharedLibraryDirectory(g_fields->m_lldb_so_dir);
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log)
- log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBShlibDir) => '%s'",
- g_fields->m_lldb_so_dir.GetPath().c_str());
- });
- if (success)
- result = &g_fields->m_lldb_so_dir;
- } break;
- case lldb::ePathTypeSupportExecutableDir: {
- static llvm::once_flag g_once_flag;
- static bool success = false;
- llvm::call_once(g_once_flag, []() {
- success = HostInfo::ComputeSupportExeDirectory(
- g_fields->m_lldb_support_exe_dir);
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log)
- log->Printf(
- "HostInfoBase::GetLLDBPath(ePathTypeSupportExecutableDir) => '%s'",
- g_fields->m_lldb_support_exe_dir.GetPath().c_str());
- });
- if (success)
- result = &g_fields->m_lldb_support_exe_dir;
- } break;
- case lldb::ePathTypeHeaderDir: {
- static llvm::once_flag g_once_flag;
- static bool success = false;
- llvm::call_once(g_once_flag, []() {
- success = HostInfo::ComputeHeaderDirectory(g_fields->m_lldb_headers_dir);
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log)
- log->Printf("HostInfoBase::GetLLDBPath(ePathTypeHeaderDir) => '%s'",
- g_fields->m_lldb_headers_dir.GetPath().c_str());
- });
- if (success)
- result = &g_fields->m_lldb_headers_dir;
- } break;
- case lldb::ePathTypePythonDir: {
- static llvm::once_flag g_once_flag;
- static bool success = false;
- llvm::call_once(g_once_flag, []() {
- success = HostInfo::ComputePythonDirectory(g_fields->m_lldb_python_dir);
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log)
- log->Printf("HostInfoBase::GetLLDBPath(ePathTypePythonDir) => '%s'",
- g_fields->m_lldb_python_dir.GetPath().c_str());
- });
- if (success)
- result = &g_fields->m_lldb_python_dir;
- } break;
- case lldb::ePathTypeClangDir: {
- static llvm::once_flag g_once_flag;
- static bool success = false;
- llvm::call_once(g_once_flag, []() {
- success =
- HostInfo::ComputeClangDirectory(g_fields->m_lldb_clang_resource_dir);
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log)
- log->Printf(
- "HostInfoBase::GetLLDBPath(ePathTypeClangResourceDir) => '%s'",
- g_fields->m_lldb_clang_resource_dir.GetPath().c_str());
- });
- if (success)
- result = &g_fields->m_lldb_clang_resource_dir;
- } break;
- case lldb::ePathTypeLLDBSystemPlugins: {
- static llvm::once_flag g_once_flag;
- static bool success = false;
- llvm::call_once(g_once_flag, []() {
- success = HostInfo::ComputeSystemPluginsDirectory(
- g_fields->m_lldb_system_plugin_dir);
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log)
- log->Printf(
- "HostInfoBase::GetLLDBPath(ePathTypeLLDBSystemPlugins) => '%s'",
- g_fields->m_lldb_system_plugin_dir.GetPath().c_str());
- });
- if (success)
- result = &g_fields->m_lldb_system_plugin_dir;
- } break;
- case lldb::ePathTypeLLDBUserPlugins: {
- static llvm::once_flag g_once_flag;
- static bool success = false;
- llvm::call_once(g_once_flag, []() {
- success = HostInfo::ComputeUserPluginsDirectory(
- g_fields->m_lldb_user_plugin_dir);
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log)
- log->Printf(
- "HostInfoBase::GetLLDBPath(ePathTypeLLDBUserPlugins) => '%s'",
- g_fields->m_lldb_user_plugin_dir.GetPath().c_str());
- });
- if (success)
- result = &g_fields->m_lldb_user_plugin_dir;
- } break;
- case lldb::ePathTypeLLDBTempSystemDir: {
- static llvm::once_flag g_once_flag;
- static bool success = false;
- llvm::call_once(g_once_flag, []() {
- success = HostInfo::ComputeProcessTempFileDirectory(
- g_fields->m_lldb_process_tmp_dir);
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log)
- log->Printf(
- "HostInfoBase::GetLLDBPath(ePathTypeLLDBTempSystemDir) => '%s'",
- g_fields->m_lldb_process_tmp_dir.GetPath().c_str());
- });
- if (success)
- result = &g_fields->m_lldb_process_tmp_dir;
- } break;
- case lldb::ePathTypeGlobalLLDBTempSystemDir: {
- static llvm::once_flag g_once_flag;
- static bool success = false;
- llvm::call_once(g_once_flag, []() {
- success = HostInfo::ComputeGlobalTempFileDirectory(
- g_fields->m_lldb_global_tmp_dir);
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log)
- log->Printf("HostInfoBase::GetLLDBPath("
- "ePathTypeGlobalLLDBTempSystemDir) => '%s'",
- g_fields->m_lldb_global_tmp_dir.GetPath().c_str());
- });
- if (success)
- result = &g_fields->m_lldb_global_tmp_dir;
- } break;
- }
+FileSpec HostInfoBase::GetHeaderDir() {
+ static llvm::once_flag g_once_flag;
+ static bool success = false;
+ llvm::call_once(g_once_flag, []() {
+ success = HostInfo::ComputeHeaderDirectory(g_fields->m_lldb_headers_dir);
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ LLDB_LOG(log, "header dir -> `{0}`", g_fields->m_lldb_headers_dir);
+ });
+ return success ? g_fields->m_lldb_headers_dir : FileSpec();
+}
- if (!result)
- return false;
- file_spec = *result;
- return true;
+FileSpec HostInfoBase::GetSystemPluginDir() {
+ static llvm::once_flag g_once_flag;
+ static bool success = false;
+ llvm::call_once(g_once_flag, []() {
+ success = HostInfo::ComputeSystemPluginsDirectory(
+ g_fields->m_lldb_system_plugin_dir);
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ LLDB_LOG(log, "system plugin dir -> `{0}`",
+ g_fields->m_lldb_system_plugin_dir);
+ });
+ return success ? g_fields->m_lldb_system_plugin_dir : FileSpec();
+}
+
+FileSpec HostInfoBase::GetUserPluginDir() {
+ static llvm::once_flag g_once_flag;
+ static bool success = false;
+ llvm::call_once(g_once_flag, []() {
+ success =
+ HostInfo::ComputeUserPluginsDirectory(g_fields->m_lldb_user_plugin_dir);
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ LLDB_LOG(log, "user plugin dir -> `{0}`", g_fields->m_lldb_user_plugin_dir);
+ });
+ return success ? g_fields->m_lldb_user_plugin_dir : FileSpec();
+}
+
+FileSpec HostInfoBase::GetProcessTempDir() {
+ static llvm::once_flag g_once_flag;
+ static bool success = false;
+ llvm::call_once(g_once_flag, []() {
+ success = HostInfo::ComputeProcessTempFileDirectory(
+ g_fields->m_lldb_process_tmp_dir);
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ LLDB_LOG(log, "process temp dir -> `{0}`",
+ g_fields->m_lldb_process_tmp_dir);
+ });
+ return success ? g_fields->m_lldb_process_tmp_dir : FileSpec();
+}
+
+FileSpec HostInfoBase::GetGlobalTempDir() {
+ static llvm::once_flag g_once_flag;
+ static bool success = false;
+ llvm::call_once(g_once_flag, []() {
+ success = HostInfo::ComputeGlobalTempFileDirectory(
+ g_fields->m_lldb_global_tmp_dir);
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ LLDB_LOG(log, "global temp dir -> `{0}`", g_fields->m_lldb_global_tmp_dir);
+ });
+ return success ? g_fields->m_lldb_global_tmp_dir : FileSpec();
}
ArchSpec HostInfoBase::GetAugmentedArchSpec(llvm::StringRef triple) {
@@ -282,14 +217,12 @@ ArchSpec HostInfoBase::GetAugmentedArchSpec(llvm::StringRef triple) {
bool HostInfoBase::ComputeSharedLibraryDirectory(FileSpec &file_spec) {
// To get paths related to LLDB we get the path to the executable that
- // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB",
- // on linux this is assumed to be the "lldb" main executable. If LLDB on
- // linux is actually in a shared library (liblldb.so) then this function will
- // need to be modified to "do the right thing".
+ // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB".
+ // On other posix systems, we will get .../lib(64|32)?/liblldb.so.
- FileSpec lldb_file_spec(
- Host::GetModuleFileSpecForHostAddress(reinterpret_cast<void *>(
- reinterpret_cast<intptr_t>(HostInfoBase::GetLLDBPath))));
+ FileSpec lldb_file_spec(Host::GetModuleFileSpecForHostAddress(
+ reinterpret_cast<void *>(reinterpret_cast<intptr_t>(
+ HostInfoBase::ComputeSharedLibraryDirectory))));
// This is necessary because when running the testsuite the shlib might be a
// symbolic link inside the Python resource dir.
@@ -302,7 +235,8 @@ bool HostInfoBase::ComputeSharedLibraryDirectory(FileSpec &file_spec) {
}
bool HostInfoBase::ComputeSupportExeDirectory(FileSpec &file_spec) {
- return GetLLDBPath(lldb::ePathTypeLLDBShlibDir, file_spec);
+ file_spec = GetShlibDir();
+ return bool(file_spec);
}
bool HostInfoBase::ComputeProcessTempFileDirectory(FileSpec &file_spec) {
@@ -353,11 +287,9 @@ bool HostInfoBase::ComputeSystemPluginsDirectory(FileSpec &file_spec) {
return false;
}
-bool HostInfoBase::ComputeClangDirectory(FileSpec &file_spec) { return false; }
-
bool HostInfoBase::ComputeUserPluginsDirectory(FileSpec &file_spec) {
- // TODO(zturner): Figure out how to compute the user plugins directory for all
- // platforms.
+ // TODO(zturner): Figure out how to compute the user plugins directory for
+ // all platforms.
return false;
}
@@ -375,6 +307,7 @@ void HostInfoBase::ComputeHostArchitectureSupport(ArchSpec &arch_32,
case llvm::Triple::aarch64:
case llvm::Triple::ppc64:
+ case llvm::Triple::ppc64le:
case llvm::Triple::x86_64:
arch_64.SetTriple(triple);
arch_32.SetTriple(triple.get32BitArchVariant());
diff --git a/source/Host/common/MainLoop.cpp b/source/Host/common/MainLoop.cpp
index 6cbb5a842562..65158c942934 100644
--- a/source/Host/common/MainLoop.cpp
+++ b/source/Host/common/MainLoop.cpp
@@ -26,7 +26,7 @@
#if HAVE_SYS_EVENT_H
#include <sys/event.h>
-#elif defined(LLVM_ON_WIN32)
+#elif defined(_WIN32)
#include <winsock2.h>
#elif defined(__ANDROID__)
#include <sys/syscall.h>
@@ -34,14 +34,14 @@
#include <poll.h>
#endif
-#ifdef LLVM_ON_WIN32
+#ifdef _WIN32
#define POLL WSAPoll
#else
#define POLL poll
#endif
#if SIGNAL_POLLING_UNSUPPORTED
-#ifdef LLVM_ON_WIN32
+#ifdef _WIN32
typedef int sigset_t;
typedef int siginfo_t;
#endif
@@ -209,8 +209,8 @@ Status MainLoop::RunImpl::Poll() {
void MainLoop::RunImpl::ProcessEvents() {
#ifdef __ANDROID__
- // Collect first all readable file descriptors into a separate vector and then
- // iterate over it to invoke callbacks. Iterating directly over
+ // Collect first all readable file descriptors into a separate vector and
+ // then iterate over it to invoke callbacks. Iterating directly over
// loop.m_read_fds is not possible because the callbacks can modify the
// container which could invalidate the iterator.
std::vector<IOObject::WaitableHandle> fds;
@@ -262,7 +262,7 @@ MainLoop::~MainLoop() {
MainLoop::ReadHandleUP MainLoop::RegisterReadObject(const IOObjectSP &object_sp,
const Callback &callback,
Status &error) {
-#ifdef LLVM_ON_WIN32
+#ifdef _WIN32
if (object_sp->GetFdType() != IOObject:: eFDTypeSocket) {
error.SetErrorString("MainLoop: non-socket types unsupported on Windows");
return nullptr;
@@ -285,8 +285,7 @@ MainLoop::ReadHandleUP MainLoop::RegisterReadObject(const IOObjectSP &object_sp,
}
// We shall block the signal, then install the signal handler. The signal will
-// be unblocked in
-// the Run() function to check for signal delivery.
+// be unblocked in the Run() function to check for signal delivery.
MainLoop::SignalHandleUP
MainLoop::RegisterSignal(int signo, const Callback &callback, Status &error) {
#ifdef SIGNAL_POLLING_UNSUPPORTED
@@ -321,9 +320,9 @@ MainLoop::RegisterSignal(int signo, const Callback &callback, Status &error) {
assert(ret == 0);
#endif
- // If we're using kqueue, the signal needs to be unblocked in order to recieve
- // it. If using pselect/ppoll, we need to block it, and later unblock it as a
- // part of the system call.
+ // If we're using kqueue, the signal needs to be unblocked in order to
+ // recieve it. If using pselect/ppoll, we need to block it, and later unblock
+ // it as a part of the system call.
ret = pthread_sigmask(HAVE_SYS_EVENT_H ? SIG_UNBLOCK : SIG_BLOCK,
&new_action.sa_mask, &old_set);
assert(ret == 0 && "pthread_sigmask failed");
diff --git a/source/Host/common/MonitoringProcessLauncher.cpp b/source/Host/common/MonitoringProcessLauncher.cpp
index f1fcd0b44c15..76c11454f573 100644
--- a/source/Host/common/MonitoringProcessLauncher.cpp
+++ b/source/Host/common/MonitoringProcessLauncher.cpp
@@ -8,11 +8,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/MonitoringProcessLauncher.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/HostProcess.h"
-#include "lldb/Target/Platform.h"
-#include "lldb/Target/Process.h"
#include "lldb/Target/ProcessLaunchInfo.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
@@ -32,36 +28,23 @@ MonitoringProcessLauncher::LaunchProcess(const ProcessLaunchInfo &launch_info,
ProcessLaunchInfo resolved_info(launch_info);
error.Clear();
- char exe_path[PATH_MAX];
-
- PlatformSP host_platform_sp(Platform::GetHostPlatform());
-
- const ArchSpec &arch_spec = resolved_info.GetArchitecture();
FileSpec exe_spec(resolved_info.GetExecutableFile());
llvm::sys::fs::file_status stats;
status(exe_spec.GetPath(), stats);
- if (!is_regular_file(stats)) {
- ModuleSpec module_spec(exe_spec, arch_spec);
- lldb::ModuleSP exe_module_sp;
- error =
- host_platform_sp->ResolveExecutable(module_spec, exe_module_sp, NULL);
-
- if (error.Fail())
- return HostProcess();
-
- if (exe_module_sp) {
- exe_spec = exe_module_sp->GetFileSpec();
- status(exe_spec.GetPath(), stats);
- }
+ if (!exists(stats)) {
+ exe_spec.ResolvePath();
+ status(exe_spec.GetPath(), stats);
+ }
+ if (!exists(stats)) {
+ exe_spec.ResolveExecutableLocation();
+ status(exe_spec.GetPath(), stats);
}
- if (exists(stats)) {
- exe_spec.GetPath(exe_path, sizeof(exe_path));
- } else {
- resolved_info.GetExecutableFile().GetPath(exe_path, sizeof(exe_path));
- error.SetErrorStringWithFormat("executable doesn't exist: '%s'", exe_path);
+ if (!exists(stats)) {
+ error.SetErrorStringWithFormatv("executable doesn't exist: '{0}'",
+ exe_spec);
return HostProcess();
}
@@ -74,18 +57,9 @@ MonitoringProcessLauncher::LaunchProcess(const ProcessLaunchInfo &launch_info,
if (process.GetProcessId() != LLDB_INVALID_PROCESS_ID) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- Host::MonitorChildProcessCallback callback =
- launch_info.GetMonitorProcessCallback();
-
- bool monitor_signals = false;
- if (callback) {
- // If the ProcessLaunchInfo specified a callback, use that.
- monitor_signals = launch_info.GetMonitorSignals();
- } else {
- callback = Process::SetProcessExitStatus;
- }
-
- process.StartMonitoring(callback, monitor_signals);
+ assert(launch_info.GetMonitorProcessCallback());
+ process.StartMonitoring(launch_info.GetMonitorProcessCallback(),
+ launch_info.GetMonitorSignals());
if (log)
log->PutCString("started monitoring child process.");
} else {
diff --git a/source/Host/common/NativeBreakpointList.cpp b/source/Host/common/NativeBreakpointList.cpp
index ce5eb94a8d1f..cfcbe0831064 100644
--- a/source/Host/common/NativeBreakpointList.cpp
+++ b/source/Host/common/NativeBreakpointList.cpp
@@ -104,8 +104,8 @@ Status NativeBreakpointList::DecRef(lldb::addr_t addr) {
return error;
}
- // Breakpoint has no more references. Disable it if it's not
- // already disabled.
+ // Breakpoint has no more references. Disable it if it's not already
+ // disabled.
if (log)
log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64
" -- removing due to no remaining references",
diff --git a/source/Host/common/NativeProcessProtocol.cpp b/source/Host/common/NativeProcessProtocol.cpp
index 1fcb11b8b6f5..3e8648f81473 100644
--- a/source/Host/common/NativeProcessProtocol.cpp
+++ b/source/Host/common/NativeProcessProtocol.cpp
@@ -8,14 +8,11 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/common/NativeProcessProtocol.h"
-#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/common/NativeRegisterContext.h"
#include "lldb/Host/common/NativeThreadProtocol.h"
#include "lldb/Host/common/SoftwareBreakpoint.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/Process.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
#include "lldb/lldb-enumerations.h"
@@ -139,29 +136,28 @@ NativeProcessProtocol::GetHardwareDebugSupportInfo() const {
Status NativeProcessProtocol::SetWatchpoint(lldb::addr_t addr, size_t size,
uint32_t watch_flags,
bool hardware) {
- // This default implementation assumes setting the watchpoint for
- // the process will require setting the watchpoint for each of the
- // threads. Furthermore, it will track watchpoints set for the
- // process and will add them to each thread that is attached to
- // via the (FIXME implement) OnThreadAttached () method.
+ // This default implementation assumes setting the watchpoint for the process
+ // will require setting the watchpoint for each of the threads. Furthermore,
+ // it will track watchpoints set for the process and will add them to each
+ // thread that is attached to via the (FIXME implement) OnThreadAttached ()
+ // method.
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
// Update the thread list
UpdateThreads();
- // Keep track of the threads we successfully set the watchpoint
- // for. If one of the thread watchpoint setting operations fails,
- // back off and remove the watchpoint for all the threads that
- // were successfully set so we get back to a consistent state.
+ // Keep track of the threads we successfully set the watchpoint for. If one
+ // of the thread watchpoint setting operations fails, back off and remove the
+ // watchpoint for all the threads that were successfully set so we get back
+ // to a consistent state.
std::vector<NativeThreadProtocol *> watchpoint_established_threads;
- // Tell each thread to set a watchpoint. In the event that
- // hardware watchpoints are requested but the SetWatchpoint fails,
- // try to set a software watchpoint as a fallback. It's
- // conceivable that if there are more threads than hardware
- // watchpoints available, some of the threads will fail to set
- // hardware watchpoints while software ones may be available.
+ // Tell each thread to set a watchpoint. In the event that hardware
+ // watchpoints are requested but the SetWatchpoint fails, try to set a
+ // software watchpoint as a fallback. It's conceivable that if there are
+ // more threads than hardware watchpoints available, some of the threads will
+ // fail to set hardware watchpoints while software ones may be available.
std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
for (const auto &thread : m_threads) {
assert(thread && "thread list should not have a NULL thread!");
@@ -169,8 +165,8 @@ Status NativeProcessProtocol::SetWatchpoint(lldb::addr_t addr, size_t size,
Status thread_error =
thread->SetWatchpoint(addr, size, watch_flags, hardware);
if (thread_error.Fail() && hardware) {
- // Try software watchpoints since we failed on hardware watchpoint setting
- // and we may have just run out of hardware watchpoints.
+ // Try software watchpoints since we failed on hardware watchpoint
+ // setting and we may have just run out of hardware watchpoints.
thread_error = thread->SetWatchpoint(addr, size, watch_flags, false);
if (thread_error.Success())
LLDB_LOG(log,
@@ -178,13 +174,12 @@ Status NativeProcessProtocol::SetWatchpoint(lldb::addr_t addr, size_t size,
}
if (thread_error.Success()) {
- // Remember that we set this watchpoint successfully in
- // case we need to clear it later.
+ // Remember that we set this watchpoint successfully in case we need to
+ // clear it later.
watchpoint_established_threads.push_back(thread.get());
} else {
- // Unset the watchpoint for each thread we successfully
- // set so that we get back to a consistent state of "not
- // set" for the watchpoint.
+ // Unset the watchpoint for each thread we successfully set so that we
+ // get back to a consistent state of "not set" for the watchpoint.
for (auto unwatch_thread_sp : watchpoint_established_threads) {
Status remove_error = unwatch_thread_sp->RemoveWatchpoint(addr);
if (remove_error.Fail())
@@ -210,9 +205,9 @@ Status NativeProcessProtocol::RemoveWatchpoint(lldb::addr_t addr) {
const Status thread_error = thread->RemoveWatchpoint(addr);
if (thread_error.Fail()) {
- // Keep track of the first thread error if any threads
- // fail. We want to try to remove the watchpoint from
- // every thread, though, even if one or more have errors.
+ // Keep track of the first thread error if any threads fail. We want to
+ // try to remove the watchpoint from every thread, though, even if one or
+ // more have errors.
if (!overall_error.Fail())
overall_error = thread_error;
}
@@ -228,9 +223,9 @@ NativeProcessProtocol::GetHardwareBreakpointMap() const {
Status NativeProcessProtocol::SetHardwareBreakpoint(lldb::addr_t addr,
size_t size) {
- // This default implementation assumes setting a hardware breakpoint for
- // this process will require setting same hardware breakpoint for each
- // of its existing threads. New thread will do the same once created.
+ // This default implementation assumes setting a hardware breakpoint for this
+ // process will require setting same hardware breakpoint for each of its
+ // existing threads. New thread will do the same once created.
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
// Update the thread list
@@ -256,13 +251,13 @@ Status NativeProcessProtocol::SetHardwareBreakpoint(lldb::addr_t addr,
Status thread_error = thread->SetHardwareBreakpoint(addr, size);
if (thread_error.Success()) {
- // Remember that we set this breakpoint successfully in
- // case we need to clear it later.
+ // Remember that we set this breakpoint successfully in case we need to
+ // clear it later.
breakpoint_established_threads.push_back(thread.get());
} else {
- // Unset the breakpoint for each thread we successfully
- // set so that we get back to a consistent state of "not
- // set" for this hardware breakpoint.
+ // Unset the breakpoint for each thread we successfully set so that we
+ // get back to a consistent state of "not set" for this hardware
+ // breakpoint.
for (auto rollback_thread_sp : breakpoint_established_threads) {
Status remove_error =
rollback_thread_sp->RemoveHardwareBreakpoint(addr);
@@ -322,8 +317,8 @@ bool NativeProcessProtocol::UnregisterNativeDelegate(
remove(m_delegates.begin(), m_delegates.end(), &native_delegate),
m_delegates.end());
- // We removed the delegate if the count of delegates shrank after
- // removing all copies of the given native_delegate from the vector.
+ // We removed the delegate if the count of delegates shrank after removing
+ // all copies of the given native_delegate from the vector.
return m_delegates.size() < initial_size;
}
@@ -412,8 +407,8 @@ void NativeProcessProtocol::SetState(lldb::StateType state,
// Give process a chance to do any stop id bump processing, such as
// clearing cached data that is invalidated each time the process runs.
- // Note if/when we support some threads running, we'll end up needing
- // to manage this per thread and per process.
+ // Note if/when we support some threads running, we'll end up needing to
+ // manage this per thread and per process.
DoStopIDBumped(m_stop_id);
}
@@ -431,26 +426,4 @@ void NativeProcessProtocol::DoStopIDBumped(uint32_t /* newBumpId */) {
// Default implementation does nothing.
}
-Status NativeProcessProtocol::ResolveProcessArchitecture(lldb::pid_t pid,
- ArchSpec &arch) {
- // Grab process info for the running process.
- ProcessInstanceInfo process_info;
- if (!Host::GetProcessInfo(pid, process_info))
- return Status("failed to get process info");
-
- // Resolve the executable module.
- ModuleSpecList module_specs;
- if (!ObjectFile::GetModuleSpecifications(process_info.GetExecutableFile(), 0,
- 0, module_specs))
- return Status("failed to get module specifications");
- lldbassert(module_specs.GetSize() == 1);
-
- arch = module_specs.GetModuleSpecRefAtIndex(0).GetArchitecture();
- if (arch.IsValid())
- return Status();
- else
- return Status(
- "failed to retrieve a valid architecture from the exe module");
-}
-
NativeProcessProtocol::Factory::~Factory() = default;
diff --git a/source/Host/common/NativeRegisterContext.cpp b/source/Host/common/NativeRegisterContext.cpp
index 60eaebdc94cd..49b8284da970 100644
--- a/source/Host/common/NativeRegisterContext.cpp
+++ b/source/Host/common/NativeRegisterContext.cpp
@@ -28,13 +28,12 @@ NativeRegisterContext::NativeRegisterContext(NativeThreadProtocol &thread)
NativeRegisterContext::~NativeRegisterContext() {}
// FIXME revisit invalidation, process stop ids, etc. Right now we don't
-// support caching in NativeRegisterContext. We can do this later by
-// utilizing NativeProcessProtocol::GetStopID () and adding a stop id to
+// support caching in NativeRegisterContext. We can do this later by utilizing
+// NativeProcessProtocol::GetStopID () and adding a stop id to
// NativeRegisterContext.
// void
-// NativeRegisterContext::InvalidateIfNeeded (bool force)
-// {
+// NativeRegisterContext::InvalidateIfNeeded (bool force) {
// ProcessSP process_sp (m_thread.GetProcess());
// bool invalidate = force;
// uint32_t process_stop_id = UINT32_MAX;
@@ -365,8 +364,8 @@ Status NativeRegisterContext::ReadRegisterValueFromMemory(
// We now have a memory buffer that contains the part or all of the register
// value. Set the register value using this memory data.
// TODO: we might need to add a parameter to this function in case the byte
- // order of the memory data doesn't match the process. For now we are assuming
- // they are the same.
+ // order of the memory data doesn't match the process. For now we are
+ // assuming they are the same.
reg_value.SetFromMemoryData(reg_info, src, src_len, process.GetByteOrder(),
error);
@@ -385,8 +384,7 @@ Status NativeRegisterContext::WriteRegisterValueToMemory(
// TODO: we might need to add a parameter to this function in case the byte
// order of the memory data doesn't match the process. For now we are
- // assuming
- // they are the same.
+ // assuming they are the same.
const size_t bytes_copied = reg_value.GetAsMemoryData(
reg_info, dst, dst_len, process.GetByteOrder(), error);
diff --git a/source/Host/common/NativeThreadProtocol.cpp b/source/Host/common/NativeThreadProtocol.cpp
index 3f3915e006da..0c648e40eb5c 100644
--- a/source/Host/common/NativeThreadProtocol.cpp
+++ b/source/Host/common/NativeThreadProtocol.cpp
@@ -19,36 +19,3 @@ using namespace lldb_private;
NativeThreadProtocol::NativeThreadProtocol(NativeProcessProtocol &process,
lldb::tid_t tid)
: m_process(process), m_tid(tid) {}
-
-Status NativeThreadProtocol::ReadRegister(uint32_t reg,
- RegisterValue &reg_value) {
- NativeRegisterContext &register_context = GetRegisterContext();
-
- const RegisterInfo *const reg_info =
- register_context.GetRegisterInfoAtIndex(reg);
- if (!reg_info)
- return Status("no register info for reg num %" PRIu32, reg);
-
- return register_context.ReadRegister(reg_info, reg_value);
- ;
-}
-
-Status NativeThreadProtocol::WriteRegister(uint32_t reg,
- const RegisterValue &reg_value) {
- NativeRegisterContext& register_context = GetRegisterContext();
-
- const RegisterInfo *const reg_info =
- register_context.GetRegisterInfoAtIndex(reg);
- if (!reg_info)
- return Status("no register info for reg num %" PRIu32, reg);
-
- return register_context.WriteRegister(reg_info, reg_value);
-}
-
-Status NativeThreadProtocol::SaveAllRegisters(lldb::DataBufferSP &data_sp) {
- return GetRegisterContext().WriteAllRegisterValues(data_sp);
-}
-
-Status NativeThreadProtocol::RestoreAllRegisters(lldb::DataBufferSP &data_sp) {
- return GetRegisterContext().ReadAllRegisterValues(data_sp);
-}
diff --git a/source/Host/common/PseudoTerminal.cpp b/source/Host/common/PseudoTerminal.cpp
index 9657cb6523dc..c9b290078e18 100644
--- a/source/Host/common/PseudoTerminal.cpp
+++ b/source/Host/common/PseudoTerminal.cpp
@@ -35,10 +35,10 @@ PseudoTerminal::PseudoTerminal()
//----------------------------------------------------------------------
// Destructor
//
-// The destructor will close the master and slave file descriptors
-// if they are valid and ownership has not been released using the
-// ReleaseMasterFileDescriptor() or the ReleaseSaveFileDescriptor()
-// member functions.
+// The destructor will close the master and slave file descriptors if they are
+// valid and ownership has not been released using the
+// ReleaseMasterFileDescriptor() or the ReleaseSaveFileDescriptor() member
+// functions.
//----------------------------------------------------------------------
PseudoTerminal::~PseudoTerminal() {
CloseMasterFileDescriptor();
@@ -66,15 +66,14 @@ void PseudoTerminal::CloseSlaveFileDescriptor() {
}
//----------------------------------------------------------------------
-// Open the first available pseudo terminal with OFLAG as the
-// permissions. The file descriptor is stored in this object and can
-// be accessed with the MasterFileDescriptor() accessor. The
-// ownership of the master file descriptor can be released using
-// the ReleaseMasterFileDescriptor() accessor. If this object has
-// a valid master files descriptor when its destructor is called, it
-// will close the master file descriptor, therefore clients must
-// call ReleaseMasterFileDescriptor() if they wish to use the master
-// file descriptor after this object is out of scope or destroyed.
+// Open the first available pseudo terminal with OFLAG as the permissions. The
+// file descriptor is stored in this object and can be accessed with the
+// MasterFileDescriptor() accessor. The ownership of the master file descriptor
+// can be released using the ReleaseMasterFileDescriptor() accessor. If this
+// object has a valid master files descriptor when its destructor is called, it
+// will close the master file descriptor, therefore clients must call
+// ReleaseMasterFileDescriptor() if they wish to use the master file descriptor
+// after this object is out of scope or destroyed.
//
// RETURNS:
// True when successful, false indicating an error occurred.
@@ -118,12 +117,12 @@ bool PseudoTerminal::OpenFirstAvailableMaster(int oflag, char *error_str,
}
//----------------------------------------------------------------------
-// Open the slave pseudo terminal for the current master pseudo
-// terminal. A master pseudo terminal should already be valid prior to
-// calling this function (see OpenFirstAvailableMaster()).
-// The file descriptor is stored this object's member variables and can
-// be accessed via the GetSlaveFileDescriptor(), or released using the
-// ReleaseSlaveFileDescriptor() member function.
+// Open the slave pseudo terminal for the current master pseudo terminal. A
+// master pseudo terminal should already be valid prior to calling this
+// function (see OpenFirstAvailableMaster()). The file descriptor is stored
+// this object's member variables and can be accessed via the
+// GetSlaveFileDescriptor(), or released using the ReleaseSlaveFileDescriptor()
+// member function.
//
// RETURNS:
// True when successful, false indicating an error occurred.
@@ -152,8 +151,8 @@ bool PseudoTerminal::OpenSlave(int oflag, char *error_str, size_t error_len) {
}
//----------------------------------------------------------------------
-// Get the name of the slave pseudo terminal. A master pseudo terminal
-// should already be valid prior to calling this function (see
+// Get the name of the slave pseudo terminal. A master pseudo terminal should
+// already be valid prior to calling this function (see
// OpenFirstAvailableMaster()).
//
// RETURNS:
@@ -185,18 +184,16 @@ const char *PseudoTerminal::GetSlaveName(char *error_str,
// Fork a child process and have its stdio routed to a pseudo terminal.
//
// In the parent process when a valid pid is returned, the master file
-// descriptor can be used as a read/write access to stdio of the
-// child process.
+// descriptor can be used as a read/write access to stdio of the child process.
//
-// In the child process the stdin/stdout/stderr will already be routed
-// to the slave pseudo terminal and the master file descriptor will be
-// closed as it is no longer needed by the child process.
+// In the child process the stdin/stdout/stderr will already be routed to the
+// slave pseudo terminal and the master file descriptor will be closed as it is
+// no longer needed by the child process.
//
-// This class will close the file descriptors for the master/slave
-// when the destructor is called, so be sure to call
-// ReleaseMasterFileDescriptor() or ReleaseSlaveFileDescriptor() if any
-// file descriptors are going to be used past the lifespan of this
-// object.
+// This class will close the file descriptors for the master/slave when the
+// destructor is called, so be sure to call ReleaseMasterFileDescriptor() or
+// ReleaseSlaveFileDescriptor() if any file descriptors are going to be used
+// past the lifespan of this object.
//
// RETURNS:
// in the parent process: the pid of the child, or -1 if fork fails
@@ -261,49 +258,47 @@ lldb::pid_t PseudoTerminal::Fork(char *error_str, size_t error_len) {
}
//----------------------------------------------------------------------
-// The master file descriptor accessor. This object retains ownership
-// of the master file descriptor when this accessor is used. Use
-// ReleaseMasterFileDescriptor() if you wish this object to release
-// ownership of the master file descriptor.
+// The master file descriptor accessor. This object retains ownership of the
+// master file descriptor when this accessor is used. Use
+// ReleaseMasterFileDescriptor() if you wish this object to release ownership
+// of the master file descriptor.
//
-// Returns the master file descriptor, or -1 if the master file
-// descriptor is not currently valid.
+// Returns the master file descriptor, or -1 if the master file descriptor is
+// not currently valid.
//----------------------------------------------------------------------
int PseudoTerminal::GetMasterFileDescriptor() const { return m_master_fd; }
//----------------------------------------------------------------------
// The slave file descriptor accessor.
//
-// Returns the slave file descriptor, or -1 if the slave file
-// descriptor is not currently valid.
+// Returns the slave file descriptor, or -1 if the slave file descriptor is not
+// currently valid.
//----------------------------------------------------------------------
int PseudoTerminal::GetSlaveFileDescriptor() const { return m_slave_fd; }
//----------------------------------------------------------------------
-// Release ownership of the master pseudo terminal file descriptor
-// without closing it. The destructor for this class will close the
-// master file descriptor if the ownership isn't released using this
-// call and the master file descriptor has been opened.
+// Release ownership of the master pseudo terminal file descriptor without
+// closing it. The destructor for this class will close the master file
+// descriptor if the ownership isn't released using this call and the master
+// file descriptor has been opened.
//----------------------------------------------------------------------
int PseudoTerminal::ReleaseMasterFileDescriptor() {
- // Release ownership of the master pseudo terminal file
- // descriptor without closing it. (the destructor for this
- // class will close it otherwise!)
+ // Release ownership of the master pseudo terminal file descriptor without
+ // closing it. (the destructor for this class will close it otherwise!)
int fd = m_master_fd;
m_master_fd = invalid_fd;
return fd;
}
//----------------------------------------------------------------------
-// Release ownership of the slave pseudo terminal file descriptor
-// without closing it. The destructor for this class will close the
-// slave file descriptor if the ownership isn't released using this
-// call and the slave file descriptor has been opened.
+// Release ownership of the slave pseudo terminal file descriptor without
+// closing it. The destructor for this class will close the slave file
+// descriptor if the ownership isn't released using this call and the slave
+// file descriptor has been opened.
//----------------------------------------------------------------------
int PseudoTerminal::ReleaseSlaveFileDescriptor() {
- // Release ownership of the slave pseudo terminal file
- // descriptor without closing it (the destructor for this
- // class will close it otherwise!)
+ // Release ownership of the slave pseudo terminal file descriptor without
+ // closing it (the destructor for this class will close it otherwise!)
int fd = m_slave_fd;
m_slave_fd = invalid_fd;
return fd;
diff --git a/source/Host/common/Socket.cpp b/source/Host/common/Socket.cpp
index 4c23e4eb560c..875291bc115f 100644
--- a/source/Host/common/Socket.cpp
+++ b/source/Host/common/Socket.cpp
@@ -160,18 +160,17 @@ Status Socket::TcpListen(llvm::StringRef host_and_port,
error = listen_socket->Listen(host_and_port, backlog);
if (error.Success()) {
- // 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".
+ // 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 = listen_socket->GetLocalPortNumber();
- // Set the port predicate since when doing a listen://<host>:<port>
- // it often needs to accept the incoming connection which is a blocking
- // 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.
+ // Set the port predicate since when doing a listen://<host>:<port> 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.
if (predicate)
predicate->SetValue(port, eBroadcastAlways);
socket = listen_socket.release();
@@ -282,8 +281,7 @@ bool Socket::DecodeHostAndPort(llvm::StringRef host_and_port,
}
// If this was unsuccessful, then check if it's simply a signed 32-bit
- // integer, representing
- // a port with an empty host.
+ // integer, representing a port with an empty host.
host_str.clear();
port_str.clear();
bool ok = false;
@@ -436,8 +434,8 @@ NativeSocket Socket::AcceptSocket(NativeSocket sockfd, struct sockaddr *addr,
error.Clear();
#if defined(ANDROID_USE_ACCEPT_WORKAROUND)
// Hack:
- // This enables static linking lldb-server to an API 21 libc, but still having
- // it run on older devices. It is necessary because API 21 libc's
+ // This enables static linking lldb-server to an API 21 libc, but still
+ // having it run on older devices. It is necessary because API 21 libc's
// implementation of accept() uses the accept4 syscall(), which is not
// available in older kernels. Using an older libc would fix this issue, but
// introduce other ones, as the old libraries were quite buggy.
diff --git a/source/Host/common/SoftwareBreakpoint.cpp b/source/Host/common/SoftwareBreakpoint.cpp
index 14dbafd94c03..353dadf6ce6d 100644
--- a/source/Host/common/SoftwareBreakpoint.cpp
+++ b/source/Host/common/SoftwareBreakpoint.cpp
@@ -17,9 +17,8 @@
using namespace lldb_private;
-// -------------------------------------------------------------------
-// static members
-// -------------------------------------------------------------------
+// ------------------------------------------------------------------- static
+// members -------------------------------------------------------------------
Status SoftwareBreakpoint::CreateSoftwareBreakpoint(
NativeProcessProtocol &process, lldb::addr_t addr, size_t size_hint,
@@ -34,8 +33,7 @@ Status SoftwareBreakpoint::CreateSoftwareBreakpoint(
__FUNCTION__);
// Ask the NativeProcessProtocol subclass to fill in the correct software
- // breakpoint
- // trap for the breakpoint site.
+ // breakpoint trap for the breakpoint site.
size_t bp_opcode_size = 0;
const uint8_t *bp_opcode_bytes = NULL;
Status error = process.GetSoftwareBreakpointTrapOpcode(
@@ -98,9 +96,8 @@ Status SoftwareBreakpoint::CreateSoftwareBreakpoint(
log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64 " -- SUCCESS",
__FUNCTION__, addr);
- // Set the breakpoint and verified it was written properly. Now
- // create a breakpoint remover that understands how to undo this
- // breakpoint.
+ // Set the breakpoint and verified it was written properly. Now create a
+ // breakpoint remover that understands how to undo this breakpoint.
breakpoint_sp.reset(new SoftwareBreakpoint(process, addr, saved_opcode_bytes,
bp_opcode_bytes, bp_opcode_size));
return Status();
@@ -280,8 +277,8 @@ Status SoftwareBreakpoint::DoDisable() {
// Make sure the breakpoint opcode exists at this address
if (::memcmp(curr_break_op, m_trap_opcodes, m_opcode_size) == 0) {
break_op_found = true;
- // We found a valid breakpoint opcode at this address, now restore
- // the saved opcode.
+ // We found a valid breakpoint opcode at this address, now restore the
+ // saved opcode.
size_t bytes_written = 0;
error = m_process.WriteMemory(m_addr, m_saved_opcodes, m_opcode_size,
bytes_written);
diff --git a/source/Host/common/Symbols.cpp b/source/Host/common/Symbols.cpp
index 3f70fdc4bf95..d7e0c13112aa 100644
--- a/source/Host/common/Symbols.cpp
+++ b/source/Host/common/Symbols.cpp
@@ -8,8 +8,8 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/Symbols.h"
-#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ArchSpec.h"
@@ -91,7 +91,7 @@ static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
::strncat(path, exec_fspec->GetFilename().AsCString(),
sizeof(path) - strlen(path) - 1);
- dsym_fspec.SetFile(path, false);
+ dsym_fspec.SetFile(path, false, FileSpec::Style::native);
ModuleSpecList module_specs;
ModuleSpec matched_module_spec;
@@ -111,15 +111,15 @@ static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
// Add a ".dSYM" name to each directory component of the path,
// stripping off components. e.g. we may have a binary like
- // /S/L/F/Foundation.framework/Versions/A/Foundation
- // and
+ // /S/L/F/Foundation.framework/Versions/A/Foundation and
// /S/L/F/Foundation.framework.dSYM
//
- // so we'll need to start with /S/L/F/Foundation.framework/Versions/A,
- // add the .dSYM part to the "A", and if that doesn't exist, strip off
- // the "A" and try it again with "Versions", etc., until we find a
- // dSYM bundle or we've stripped off enough path components that
- // there's no need to continue.
+ // so we'll need to start with
+ // /S/L/F/Foundation.framework/Versions/A, add the .dSYM part to the
+ // "A", and if that doesn't exist, strip off the "A" and try it again
+ // with "Versions", etc., until we find a dSYM bundle or we've
+ // stripped off enough path components that there's no need to
+ // continue.
for (int i = 0; i < 4; i++) {
// Does this part of the path have a "." character - could it be a
@@ -131,7 +131,8 @@ static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
dsym_fspec = parent_dirs;
dsym_fspec.RemoveLastPathComponent();
- // If the current directory name is "Foundation.framework", see if
+ // If the current directory name is "Foundation.framework", see
+ // if
// "Foundation.framework.dSYM/Contents/Resources/DWARF/Foundation"
// exists & has the right uuid.
std::string dsym_fn = fn;
@@ -222,14 +223,18 @@ FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) {
Target::GetDefaultDebugFileSearchPaths());
// Add module directory.
- const ConstString &file_dir = module_spec.GetFileSpec().GetDirectory();
+ FileSpec module_file_spec = module_spec.GetFileSpec();
+ // We keep the unresolved pathname if it fails.
+ FileSystem::ResolveSymbolicLink(module_file_spec, module_file_spec);
+
+ const ConstString &file_dir = module_file_spec.GetDirectory();
debug_file_search_paths.AppendIfUnique(
FileSpec(file_dir.AsCString("."), true));
// Add current working directory.
debug_file_search_paths.AppendIfUnique(FileSpec(".", true));
-#ifndef LLVM_ON_WIN32
+#ifndef _WIN32
#if defined(__NetBSD__)
// Add /usr/libdata/debug directory.
debug_file_search_paths.AppendIfUnique(
@@ -238,7 +243,7 @@ FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) {
// Add /usr/lib/debug directory.
debug_file_search_paths.AppendIfUnique(FileSpec("/usr/lib/debug", true));
#endif
-#endif // LLVM_ON_WIN32
+#endif // _WIN32
std::string uuid_str;
const UUID &module_uuid = module_spec.GetUUID();
@@ -246,6 +251,8 @@ FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) {
// Some debug files are stored in the .build-id directory like this:
// /usr/lib/debug/.build-id/ff/e7fe727889ad82bb153de2ad065b2189693315.debug
uuid_str = module_uuid.GetAsString("");
+ std::transform(uuid_str.begin(), uuid_str.end(), uuid_str.begin(),
+ ::tolower);
uuid_str.insert(2, 1, '/');
uuid_str = uuid_str + ".debug";
}
@@ -275,7 +282,7 @@ FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) {
FileSpec file_spec(filename, true);
if (llvm::sys::fs::equivalent(file_spec.GetPath(),
- module_spec.GetFileSpec().GetPath()))
+ module_file_spec.GetPath()))
continue;
if (file_spec.Exists()) {
@@ -287,10 +294,9 @@ FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) {
if (num_specs == 1) {
ModuleSpec mspec;
if (specs.GetModuleSpecAtIndex(0, mspec)) {
- // Skip the uuids check if module_uuid is invalid.
- // For example, this happens for *.dwp files since
- // at the moment llvm-dwp doesn't output build ids,
- // nor does binutils dwp.
+ // Skip the uuids check if module_uuid is invalid. For example,
+ // this happens for *.dwp files since at the moment llvm-dwp
+ // doesn't output build ids, nor does binutils dwp.
if (!module_uuid.IsValid() || module_uuid == mspec.GetUUID())
return file_spec;
}
diff --git a/source/Host/common/TCPSocket.cpp b/source/Host/common/TCPSocket.cpp
index f896944bb1b3..1a10336f1dfc 100644
--- a/source/Host/common/TCPSocket.cpp
+++ b/source/Host/common/TCPSocket.cpp
@@ -26,11 +26,11 @@
#include <sys/socket.h>
#endif
-#if defined(LLVM_ON_WIN32)
+#if defined(_WIN32)
#include <winsock2.h>
#endif
-#ifdef LLVM_ON_WIN32
+#ifdef _WIN32
#define CLOSE_SOCKET closesocket
typedef const char *set_socket_option_arg_type;
#else
diff --git a/source/Host/common/TaskPool.cpp b/source/Host/common/TaskPool.cpp
index 156a07942998..c54b9a8ae56b 100644
--- a/source/Host/common/TaskPool.cpp
+++ b/source/Host/common/TaskPool.cpp
@@ -49,8 +49,8 @@ void TaskPool::AddTaskImpl(std::function<void()> &&task_fn) {
TaskPoolImpl::TaskPoolImpl() : m_thread_count(0) {}
unsigned GetHardwareConcurrencyHint() {
- // std::thread::hardware_concurrency may return 0
- // if the value is not well defined or not computable.
+ // std::thread::hardware_concurrency may return 0 if the value is not well
+ // defined or not computable.
static const unsigned g_hardware_concurrency =
std::max(1u, std::thread::hardware_concurrency());
return g_hardware_concurrency;
@@ -64,9 +64,8 @@ void TaskPoolImpl::AddTask(std::function<void()> &&task_fn) {
if (m_thread_count < GetHardwareConcurrencyHint()) {
m_thread_count++;
// Note that this detach call needs to happen with the m_tasks_mutex held.
- // This prevents the thread
- // from exiting prematurely and triggering a linux libc bug
- // (https://sourceware.org/bugzilla/show_bug.cgi?id=19951).
+ // This prevents the thread from exiting prematurely and triggering a linux
+ // libc bug (https://sourceware.org/bugzilla/show_bug.cgi?id=19951).
lldb_private::ThreadLauncher::LaunchThread("task-pool.worker", WorkerPtr,
this, nullptr, min_stack_size)
.Release();
diff --git a/source/Host/common/Terminal.cpp b/source/Host/common/Terminal.cpp
index 022b3fa50a8f..be912fbe6155 100644
--- a/source/Host/common/Terminal.cpp
+++ b/source/Host/common/Terminal.cpp
@@ -9,6 +9,7 @@
#include "lldb/Host/Terminal.h"
+#include "lldb/Host/Config.h"
#include "lldb/Host/PosixApi.h"
#include "llvm/ADT/STLExtras.h"
@@ -107,9 +108,9 @@ void TerminalState::Clear() {
}
//----------------------------------------------------------------------
-// Save the current state of the TTY for the file descriptor "fd"
-// and if "save_process_group" is true, attempt to save the process
-// group info for the TTY.
+// Save the current state of the TTY for the file descriptor "fd" and if
+// "save_process_group" is true, attempt to save the process group info for the
+// TTY.
//----------------------------------------------------------------------
bool TerminalState::Save(int fd, bool save_process_group) {
m_tty.SetFileDescriptor(fd);
@@ -142,8 +143,8 @@ bool TerminalState::Save(int fd, bool save_process_group) {
}
//----------------------------------------------------------------------
-// Restore the state of the TTY using the cached values from a
-// previous call to Save().
+// Restore the state of the TTY using the cached values from a previous call to
+// Save().
//----------------------------------------------------------------------
bool TerminalState::Restore() const {
#ifndef LLDB_DISABLE_POSIX
@@ -173,8 +174,8 @@ bool TerminalState::Restore() const {
}
//----------------------------------------------------------------------
-// Returns true if this object has valid saved TTY state settings
-// that can be used to restore a previous state.
+// Returns true if this object has valid saved TTY state settings that can be
+// used to restore a previous state.
//----------------------------------------------------------------------
bool TerminalState::IsValid() const {
return m_tty.FileDescriptorIsValid() &&
@@ -236,21 +237,20 @@ bool TerminalStateSwitcher::Restore(uint32_t idx) const {
m_ttystates[idx].IsValid())
return true;
- // Set the state to match the index passed in and only update the
- // current state if there are no errors.
+ // Set the state to match the index passed in and only update the current
+ // state if there are no errors.
if (m_ttystates[idx].Restore()) {
m_currentState = idx;
return true;
}
- // We failed to set the state. The tty state was invalid or not
- // initialized.
+ // We failed to set the state. The tty state was invalid or not initialized.
return false;
}
//------------------------------------------------------------------
-// Save the state at index "idx" for file descriptor "fd" and
-// save the process group if requested.
+// Save the state at index "idx" for file descriptor "fd" and save the process
+// group if requested.
//
// Returns true if the restore was successful, false otherwise.
//------------------------------------------------------------------
diff --git a/source/Host/common/UDPSocket.cpp b/source/Host/common/UDPSocket.cpp
index 21dacbc626ee..96bcc6a150a9 100644
--- a/source/Host/common/UDPSocket.cpp
+++ b/source/Host/common/UDPSocket.cpp
@@ -69,8 +69,8 @@ Status UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit,
if (!DecodeHostAndPort(name, host_str, port_str, port, &error))
return error;
- // At this point we have setup the receive port, now we need to
- // setup the UDP send socket
+ // At this point we have setup the receive port, now we need to setup the UDP
+ // send socket
struct addrinfo hints;
struct addrinfo *service_info_list = nullptr;
diff --git a/source/Host/common/XML.cpp b/source/Host/common/XML.cpp
index c3169bd6e08d..7468a3d7ac65 100644
--- a/source/Host/common/XML.cpp
+++ b/source/Host/common/XML.cpp
@@ -151,6 +151,18 @@ llvm::StringRef XMLNode::GetAttributeValue(const char *name,
return llvm::StringRef();
}
+bool XMLNode::GetAttributeValueAsUnsigned(const char *name, uint64_t &value,
+ uint64_t fail_value, int base) const {
+#if defined(LIBXML2_DEFINED)
+ llvm::StringRef str_value = GetAttributeValue(name, "");
+#else
+ llvm::StringRef str_value;
+#endif
+ bool success = false;
+ value = StringConvert::ToUInt64(str_value.data(), fail_value, base, &success);
+ return success;
+}
+
void XMLNode::ForEachChildNode(NodeCallback const &callback) const {
#if defined(LIBXML2_DEFINED)
if (IsValid())
@@ -240,8 +252,8 @@ void XMLNode::ForEachSiblingElementWithName(
if (node->type != XML_ELEMENT_NODE)
continue;
- // If name is nullptr, we take all nodes of type "t", else
- // just the ones whose name matches
+ // If name is nullptr, we take all nodes of type "t", else just the ones
+ // whose name matches
if (name) {
if (strcmp((const char *)node->name, name) != 0)
continue; // Name mismatch, ignore this one
diff --git a/source/Host/freebsd/Host.cpp b/source/Host/freebsd/Host.cpp
index 124a8a760133..87552bc2a27e 100644
--- a/source/Host/freebsd/Host.cpp
+++ b/source/Host/freebsd/Host.cpp
@@ -26,12 +26,9 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/Module.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
-#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
-#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
@@ -78,9 +75,11 @@ GetFreeBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
size_t pathname_len = sizeof(pathname);
mib[2] = KERN_PROC_PATHNAME;
if (::sysctl(mib, 4, pathname, &pathname_len, NULL, 0) == 0)
- process_info.GetExecutableFile().SetFile(pathname, false);
+ process_info.GetExecutableFile().SetFile(pathname, false,
+ FileSpec::Style::native);
else
- process_info.GetExecutableFile().SetFile(cstr, false);
+ process_info.GetExecutableFile().SetFile(cstr, false,
+ FileSpec::Style::native);
if (!(match_info_ptr == NULL ||
NameMatches(process_info.GetExecutableFile().GetFilename().GetCString(),
@@ -195,9 +194,8 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
continue;
// Every thread is a process in FreeBSD, but all the threads of a single
- // process have the same pid. Do not store the process info in the
- // result list if a process with given identifier is already registered
- // there.
+ // process have the same pid. Do not store the process info in the result
+ // list if a process with given identifier is already registered there.
bool already_registered = false;
for (uint32_t pi = 0;
!already_registered && (const int)kinfo.ki_numthreads > 1 &&
@@ -243,14 +241,7 @@ bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
return false;
}
-size_t Host::GetEnvironment(StringList &env) {
- char **host_env = environ;
- char *env_entry;
- size_t i;
- for (i = 0; (env_entry = host_env[i]) != NULL; ++i)
- env.AppendString(env_entry);
- return i;
-}
+Environment Host::GetEnvironment() { return Environment(environ); }
Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
return Status("unimplemented");
diff --git a/source/Host/freebsd/HostInfoFreeBSD.cpp b/source/Host/freebsd/HostInfoFreeBSD.cpp
index 9c82fcca7563..18eae3eb7606 100644
--- a/source/Host/freebsd/HostInfoFreeBSD.cpp
+++ b/source/Host/freebsd/HostInfoFreeBSD.cpp
@@ -18,16 +18,17 @@
using namespace lldb_private;
-bool HostInfoFreeBSD::GetOSVersion(uint32_t &major, uint32_t &minor,
- uint32_t &update) {
+llvm::VersionTuple HostInfoFreeBSD::GetOSVersion() {
struct utsname un;
::memset(&un, 0, sizeof(utsname));
if (uname(&un) < 0)
- return false;
+ return llvm::VersionTuple();
- int status = sscanf(un.release, "%u.%u", &major, &minor);
- return status == 2;
+ unsigned major, minor;
+ if (2 == sscanf(un.release, "%u.%u", &major, &minor))
+ return llvm::VersionTuple(major, minor);
+ return llvm::VersionTuple();
}
bool HostInfoFreeBSD::GetOSBuildString(std::string &s) {
@@ -68,9 +69,9 @@ FileSpec HostInfoFreeBSD::GetProgramFileSpec() {
if (sysctl(exe_path_mib, 4, NULL, &exe_path_size, NULL, 0) == 0) {
char *exe_path = new char[exe_path_size];
if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0)
- g_program_filespec.SetFile(exe_path, false);
+ g_program_filespec.SetFile(exe_path, false, FileSpec::Style::native);
delete[] exe_path;
}
}
return g_program_filespec;
-} \ No newline at end of file
+}
diff --git a/source/Host/linux/Host.cpp b/source/Host/linux/Host.cpp
index f43090eadf81..1a0eb767eb34 100644
--- a/source/Host/linux/Host.cpp
+++ b/source/Host/linux/Host.cpp
@@ -20,7 +20,9 @@
// C++ Includes
// Other libraries and framework includes
+#include "llvm/Object/ELF.h"
#include "llvm/Support/ScopedPrinter.h"
+
// Project includes
#include "lldb/Target/Process.h"
#include "lldb/Utility/Log.h"
@@ -29,12 +31,9 @@
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/linux/Support.h"
-#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/DataBufferLLVM.h"
#include "lldb/Utility/DataExtractor.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Symbol/ObjectFile.h"
-
using namespace lldb;
using namespace lldb_private;
@@ -123,28 +122,27 @@ static bool IsDirNumeric(const char *dname) {
return true;
}
-static bool GetELFProcessCPUType(llvm::StringRef exe_path,
- ProcessInstanceInfo &process_info) {
- // Clear the architecture.
- process_info.GetArchitecture().Clear();
+static ArchSpec GetELFProcessCPUType(llvm::StringRef exe_path) {
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- ModuleSpecList specs;
- FileSpec filespec(exe_path, false);
- const size_t num_specs =
- ObjectFile::GetModuleSpecifications(filespec, 0, 0, specs);
- // GetModuleSpecifications() could fail if the executable has been deleted or
- // is locked.
- // But it shouldn't return more than 1 architecture.
- assert(num_specs <= 1 && "Linux plugin supports only a single architecture");
- if (num_specs == 1) {
- ModuleSpec module_spec;
- if (specs.GetModuleSpecAtIndex(0, module_spec) &&
- module_spec.GetArchitecture().IsValid()) {
- process_info.GetArchitecture() = module_spec.GetArchitecture();
- return true;
- }
+ auto buffer_sp = DataBufferLLVM::CreateSliceFromPath(exe_path, 0x20, 0);
+ if (!buffer_sp)
+ return ArchSpec();
+
+ uint8_t exe_class =
+ llvm::object::getElfArchType(
+ {buffer_sp->GetChars(), size_t(buffer_sp->GetByteSize())})
+ .first;
+
+ switch (exe_class) {
+ case llvm::ELF::ELFCLASS32:
+ return HostInfo::GetArchitecture(HostInfo::eArchKind32);
+ case llvm::ELF::ELFCLASS64:
+ return HostInfo::GetArchitecture(HostInfo::eArchKind64);
+ default:
+ LLDB_LOG(log, "Unknown elf class ({0}) in file {1}", exe_class, exe_path);
+ return ArchSpec();
}
- return false;
}
static bool GetProcessAndStatInfo(::pid_t pid,
@@ -173,7 +171,7 @@ static bool GetProcessAndStatInfo(::pid_t pid,
llvm::StringRef PathRef = ExePath;
PathRef.consume_back(" (deleted)");
- GetELFProcessCPUType(PathRef, process_info);
+ process_info.SetArchitecture(GetELFProcessCPUType(PathRef));
// Get the process environment.
auto BufferOrError = getProcFile(pid, "environ");
@@ -192,14 +190,14 @@ static bool GetProcessAndStatInfo(::pid_t pid,
return false;
process_info.SetProcessID(pid);
- process_info.GetExecutableFile().SetFile(PathRef, false);
- process_info.GetArchitecture().MergeFrom(HostInfo::GetArchitecture());
+ process_info.GetExecutableFile().SetFile(PathRef, false,
+ FileSpec::Style::native);
llvm::StringRef Rest = Environ->getBuffer();
while (!Rest.empty()) {
llvm::StringRef Var;
std::tie(Var, Rest) = Rest.split('\0');
- process_info.GetEnvironmentEntries().AppendArgument(Var);
+ process_info.GetEnvironment().insert(Var);
}
llvm::StringRef Arg0;
@@ -249,8 +247,8 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
if (State == ProcessState::Zombie)
continue;
- // Check for user match if we're not matching all users and not running as
- // root.
+ // Check for user match if we're not matching all users and not running
+ // as root.
if (!all_users && (our_uid != 0) && (process_info.GetUserID() != our_uid))
continue;
@@ -297,14 +295,7 @@ bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
return GetProcessAndStatInfo(pid, process_info, State, tracerpid);
}
-size_t Host::GetEnvironment(StringList &env) {
- char **host_env = environ;
- char *env_entry;
- size_t i;
- for (i = 0; (env_entry = host_env[i]) != NULL; ++i)
- env.AppendString(env_entry);
- return i;
-}
+Environment Host::GetEnvironment() { return Environment(environ); }
Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
return Status("unimplemented");
diff --git a/source/Host/linux/HostInfoLinux.cpp b/source/Host/linux/HostInfoLinux.cpp
index 8d59cda249e8..1d95010e2f73 100644
--- a/source/Host/linux/HostInfoLinux.cpp
+++ b/source/Host/linux/HostInfoLinux.cpp
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/Host/Config.h"
#include "lldb/Host/linux/HostInfoLinux.h"
#include "lldb/Utility/Log.h"
@@ -25,12 +26,8 @@ using namespace lldb_private;
namespace {
struct HostInfoLinuxFields {
- HostInfoLinuxFields() : m_os_major(0), m_os_minor(0), m_os_update(0) {}
-
std::string m_distribution_id;
- uint32_t m_os_major;
- uint32_t m_os_minor;
- uint32_t m_os_update;
+ llvm::VersionTuple m_os_version;
};
HostInfoLinuxFields *g_fields = nullptr;
@@ -42,35 +39,21 @@ void HostInfoLinux::Initialize() {
g_fields = new HostInfoLinuxFields();
}
-bool HostInfoLinux::GetOSVersion(uint32_t &major, uint32_t &minor,
- uint32_t &update) {
- static bool success = false;
+llvm::VersionTuple HostInfoLinux::GetOSVersion() {
static llvm::once_flag g_once_flag;
llvm::call_once(g_once_flag, []() {
-
struct utsname un;
- if (uname(&un) == 0) {
- int status = sscanf(un.release, "%u.%u.%u", &g_fields->m_os_major,
- &g_fields->m_os_minor, &g_fields->m_os_update);
- if (status == 3)
- success = true;
- else {
- // Some kernels omit the update version, so try looking for just "X.Y"
- // and
- // set update to 0.
- g_fields->m_os_update = 0;
- status = sscanf(un.release, "%u.%u", &g_fields->m_os_major,
- &g_fields->m_os_minor);
- if (status == 2)
- success = true;
- }
- }
+ if (uname(&un) != 0)
+ return;
+
+ llvm::StringRef release = un.release;
+ // The kernel release string can include a lot of stuff (e.g.
+ // 4.9.0-6-amd64). We're only interested in the numbered prefix.
+ release = release.substr(0, release.find_first_not_of("0123456789."));
+ g_fields->m_os_version.tryParse(release);
});
- major = g_fields->m_os_major;
- minor = g_fields->m_os_minor;
- update = g_fields->m_os_update;
- return success;
+ return g_fields->m_os_version;
}
bool HostInfoLinux::GetOSBuildString(std::string &s) {
@@ -99,8 +82,8 @@ bool HostInfoLinux::GetOSKernelDescription(std::string &s) {
}
llvm::StringRef HostInfoLinux::GetDistributionId() {
- // Try to run 'lbs_release -i', and use that response
- // for the distribution id.
+ // Try to run 'lbs_release -i', and use that response for the distribution
+ // id.
static llvm::once_flag g_once_flag;
llvm::call_once(g_once_flag, []() {
@@ -108,8 +91,7 @@ llvm::StringRef HostInfoLinux::GetDistributionId() {
if (log)
log->Printf("attempting to determine Linux distribution...");
- // check if the lsb_release command exists at one of the
- // following paths
+ // check if the lsb_release command exists at one of the following paths
const char *const exe_paths[] = {"/bin/lsb_release",
"/usr/bin/lsb_release"};
@@ -188,7 +170,7 @@ FileSpec HostInfoLinux::GetProgramFileSpec() {
ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
if (len > 0) {
exe_path[len] = 0;
- g_program_filespec.SetFile(exe_path, false);
+ g_program_filespec.SetFile(exe_path, false, FileSpec::Style::native);
}
}
@@ -204,15 +186,15 @@ bool HostInfoLinux::ComputeSupportExeDirectory(FileSpec &file_spec) {
}
bool HostInfoLinux::ComputeSystemPluginsDirectory(FileSpec &file_spec) {
- FileSpec temp_file("/usr/lib/lldb/plugins", true);
+ FileSpec temp_file("/usr/lib" LLDB_LIBDIR_SUFFIX "/lldb/plugins", true);
file_spec.GetDirectory().SetCString(temp_file.GetPath().c_str());
return true;
}
bool HostInfoLinux::ComputeUserPluginsDirectory(FileSpec &file_spec) {
// XDG Base Directory Specification
- // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
- // If XDG_DATA_HOME exists, use that, otherwise use ~/.local/share/lldb.
+ // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html If
+ // XDG_DATA_HOME exists, use that, otherwise use ~/.local/share/lldb.
const char *xdg_data_home = getenv("XDG_DATA_HOME");
if (xdg_data_home && xdg_data_home[0]) {
std::string user_plugin_dir(xdg_data_home);
diff --git a/source/Host/macosx/Symbols.cpp b/source/Host/macosx/Symbols.cpp
index 98c110b1bed6..b01c48e51d90 100644
--- a/source/Host/macosx/Symbols.cpp
+++ b/source/Host/macosx/Symbols.cpp
@@ -23,7 +23,7 @@
#include "Host/macosx/cfcpp/CFCData.h"
#include "Host/macosx/cfcpp/CFCReleaser.h"
#include "Host/macosx/cfcpp/CFCString.h"
-#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -55,6 +55,13 @@ CFDictionaryRef DBGCopyDSYMPropertyLists(CFURLRef dsym_url);
int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
ModuleSpec &return_module_spec) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ if (!ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) {
+ if (log)
+ log->Printf("Spotlight lookup for .dSYM bundles is disabled.");
+ return 0;
+ }
+
return_module_spec = module_spec;
return_module_spec.GetFileSpec().Clear();
return_module_spec.GetSymbolFileSpec().Clear();
@@ -69,8 +76,8 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
if (uuid && uuid->IsValid()) {
// Try and locate the dSYM file using DebugSymbols first
- const UInt8 *module_uuid = (const UInt8 *)uuid->GetBytes();
- if (module_uuid != NULL) {
+ llvm::ArrayRef<uint8_t> module_uuid = uuid->GetBytes();
+ if (module_uuid.size() == 16) {
CFCReleaser<CFUUIDRef> module_uuid_ref(::CFUUIDCreateWithBytes(
NULL, module_uuid[0], module_uuid[1], module_uuid[2], module_uuid[3],
module_uuid[4], module_uuid[5], module_uuid[6], module_uuid[7],
@@ -80,7 +87,6 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
if (module_uuid_ref.get()) {
CFCReleaser<CFURLRef> exec_url;
const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
if (exec_fspec) {
char exec_cf_path[PATH_MAX];
if (exec_fspec->GetPath(exec_cf_path, sizeof(exec_cf_path)))
@@ -241,52 +247,53 @@ FileSpec Symbols::FindSymbolFileInBundle(const FileSpec &dsym_bundle_fspec,
const lldb_private::UUID *uuid,
const ArchSpec *arch) {
char path[PATH_MAX];
+ if (dsym_bundle_fspec.GetPath(path, sizeof(path)) == 0)
+ return {};
- FileSpec dsym_fspec;
+ ::strncat(path, "/Contents/Resources/DWARF", sizeof(path) - strlen(path) - 1);
- if (dsym_bundle_fspec.GetPath(path, sizeof(path))) {
- ::strncat(path, "/Contents/Resources/DWARF",
- sizeof(path) - strlen(path) - 1);
+ DIR *dirp = opendir(path);
+ if (!dirp)
+ return {};
- lldb_utility::CleanUp<DIR *, int> dirp(opendir(path), NULL, closedir);
- if (dirp.is_valid()) {
- dsym_fspec.GetDirectory().SetCString(path);
- struct dirent *dp;
- while ((dp = readdir(dirp.get())) != NULL) {
- // Only search directories
- if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) {
- if (dp->d_namlen == 1 && dp->d_name[0] == '.')
- continue;
+ // Make sure we close the directory before exiting this scope.
+ CleanUp cleanup_dir(closedir, dirp);
- if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.')
- continue;
- }
+ FileSpec dsym_fspec;
+ dsym_fspec.GetDirectory().SetCString(path);
+ struct dirent *dp;
+ while ((dp = readdir(dirp)) != NULL) {
+ // Only search directories
+ if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) {
+ if (dp->d_namlen == 1 && dp->d_name[0] == '.')
+ continue;
- if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN) {
- dsym_fspec.GetFilename().SetCString(dp->d_name);
- ModuleSpecList module_specs;
- if (ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0,
- module_specs)) {
- ModuleSpec spec;
- for (size_t i = 0; i < module_specs.GetSize(); ++i) {
- bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec);
- UNUSED_IF_ASSERT_DISABLED(got_spec);
- assert(got_spec);
- if ((uuid == NULL ||
- (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) &&
- (arch == NULL ||
- (spec.GetArchitecturePtr() &&
- spec.GetArchitecture().IsCompatibleMatch(*arch)))) {
- return dsym_fspec;
- }
- }
+ if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.')
+ continue;
+ }
+
+ if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN) {
+ dsym_fspec.GetFilename().SetCString(dp->d_name);
+ ModuleSpecList module_specs;
+ if (ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, module_specs)) {
+ ModuleSpec spec;
+ for (size_t i = 0; i < module_specs.GetSize(); ++i) {
+ bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec);
+ UNUSED_IF_ASSERT_DISABLED(got_spec);
+ assert(got_spec);
+ if ((uuid == NULL ||
+ (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) &&
+ (arch == NULL ||
+ (spec.GetArchitecturePtr() &&
+ spec.GetArchitecture().IsCompatibleMatch(*arch)))) {
+ return dsym_fspec;
}
}
}
}
}
- dsym_fspec.Clear();
- return dsym_fspec;
+
+ return {};
}
static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
@@ -302,7 +309,8 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
(CFDictionaryRef)uuid_dict, CFSTR("DBGSymbolRichExecutable"));
if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
if (CFCString::FileSystemRepresentation(cf_str, str)) {
- module_spec.GetFileSpec().SetFile(str.c_str(), true);
+ module_spec.GetFileSpec().SetFile(str.c_str(), true,
+ FileSpec::Style::native);
if (log) {
log->Printf(
"From dsymForUUID plist: Symbol rich executable is at '%s'",
@@ -315,7 +323,8 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
CFSTR("DBGDSYMPath"));
if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
if (CFCString::FileSystemRepresentation(cf_str, str)) {
- module_spec.GetSymbolFileSpec().SetFile(str.c_str(), true);
+ module_spec.GetSymbolFileSpec().SetFile(str.c_str(), true,
+ FileSpec::Style::native);
success = true;
if (log) {
log->Printf("From dsymForUUID plist: dSYM is at '%s'", str.c_str());
@@ -333,28 +342,13 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
std::string DBGBuildSourcePath;
std::string DBGSourcePath;
- cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
- CFSTR("DBGBuildSourcePath"));
- if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
- CFCString::FileSystemRepresentation(cf_str, DBGBuildSourcePath);
- }
-
- cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
- CFSTR("DBGSourcePath"));
- if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
- CFCString::FileSystemRepresentation(cf_str, DBGSourcePath);
- }
-
- if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
- if (DBGSourcePath[0] == '~') {
- FileSpec resolved_source_path(DBGSourcePath.c_str(), true);
- DBGSourcePath = resolved_source_path.GetPath();
- }
- module_spec.GetSourceMappingList().Append(
- ConstString(DBGBuildSourcePath.c_str()),
- ConstString(DBGSourcePath.c_str()), true);
- }
-
+ // If DBGVersion 1 or DBGVersion missing, ignore DBGSourcePathRemapping.
+ // If DBGVersion 2, strip last two components of path remappings from
+ // entries to fix an issue with a specific set of
+ // DBGSourcePathRemapping entries that lldb worked
+ // with.
+ // If DBGVersion 3, trust & use the source path remappings as-is.
+ //
cf_dict = (CFDictionaryRef)CFDictionaryGetValue(
(CFDictionaryRef)uuid_dict, CFSTR("DBGSourcePathRemapping"));
if (cf_dict && CFGetTypeID(cf_dict) == CFDictionaryGetTypeID()) {
@@ -401,10 +395,9 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
}
if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
// In the "old style" DBGSourcePathRemapping dictionary, the
- // DBGSourcePath values
- // (the "values" half of key-value path pairs) were wrong. Ignore
- // them and use the
- // universal DBGSourcePath string from earlier.
+ // DBGSourcePath values (the "values" half of key-value path pairs)
+ // were wrong. Ignore them and use the universal DBGSourcePath
+ // string from earlier.
if (new_style_source_remapping_dictionary == true &&
!original_DBGSourcePath_value.empty()) {
DBGSourcePath = original_DBGSourcePath_value;
@@ -414,9 +407,9 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
DBGSourcePath = resolved_source_path.GetPath();
}
// With version 2 of DBGSourcePathRemapping, we can chop off the
- // last two filename parts from the source remapping and get a
- // more general source remapping that still works. Add this as
- // another option in addition to the full source path remap.
+ // last two filename parts from the source remapping and get a more
+ // general source remapping that still works. Add this as another
+ // option in addition to the full source path remap.
module_spec.GetSourceMappingList().Append(
ConstString(DBGBuildSourcePath.c_str()),
ConstString(DBGSourcePath.c_str()), true);
@@ -439,6 +432,32 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
free(values);
}
}
+
+
+ // If we have a DBGBuildSourcePath + DBGSourcePath pair, append them to the
+ // source remappings list.
+
+ cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
+ CFSTR("DBGBuildSourcePath"));
+ if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
+ CFCString::FileSystemRepresentation(cf_str, DBGBuildSourcePath);
+ }
+
+ cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
+ CFSTR("DBGSourcePath"));
+ if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
+ CFCString::FileSystemRepresentation(cf_str, DBGSourcePath);
+ }
+
+ if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
+ if (DBGSourcePath[0] == '~') {
+ FileSpec resolved_source_path(DBGSourcePath.c_str(), true);
+ DBGSourcePath = resolved_source_path.GetPath();
+ }
+ module_spec.GetSourceMappingList().Append(
+ ConstString(DBGBuildSourcePath.c_str()),
+ ConstString(DBGSourcePath.c_str()), true);
+ }
}
return success;
}
@@ -450,8 +469,7 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
const FileSpec *file_spec_ptr = module_spec.GetFileSpecPtr();
// It's expensive to check for the DBGShellCommands defaults setting, only do
- // it once per
- // lldb run and cache the result.
+ // it once per lldb run and cache the result.
static bool g_have_checked_for_dbgshell_command = false;
static const char *g_dbgshell_command = NULL;
if (g_have_checked_for_dbgshell_command == false) {
@@ -473,8 +491,7 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
}
// When g_dbgshell_command is NULL, the user has not enabled the use of an
- // external program
- // to find the symbols, don't run it for them.
+ // external program to find the symbols, don't run it for them.
if (force_lookup == false && g_dbgshell_command == NULL) {
return false;
}
@@ -489,12 +506,14 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
getenv("LLDB_APPLE_DSYMFORUUID_EXECUTABLE");
FileSpec dsym_for_uuid_exe_spec;
if (dsym_for_uuid_exe_path_cstr) {
- dsym_for_uuid_exe_spec.SetFile(dsym_for_uuid_exe_path_cstr, true);
+ dsym_for_uuid_exe_spec.SetFile(dsym_for_uuid_exe_path_cstr, true,
+ FileSpec::Style::native);
g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
}
if (!g_dsym_for_uuid_exe_exists) {
- dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID", false);
+ dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID", false,
+ FileSpec::Style::native);
g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
if (!g_dsym_for_uuid_exe_exists) {
long bufsize;
@@ -508,14 +527,16 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
tilde_rc && tilde_rc->pw_dir) {
std::string dsymforuuid_path(tilde_rc->pw_dir);
dsymforuuid_path += "/bin/dsymForUUID";
- dsym_for_uuid_exe_spec.SetFile(dsymforuuid_path.c_str(), false);
+ dsym_for_uuid_exe_spec.SetFile(dsymforuuid_path.c_str(), false,
+ FileSpec::Style::native);
g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
}
}
}
}
if (!g_dsym_for_uuid_exe_exists && g_dbgshell_command != NULL) {
- dsym_for_uuid_exe_spec.SetFile(g_dbgshell_command, true);
+ dsym_for_uuid_exe_spec.SetFile(g_dbgshell_command, true,
+ FileSpec::Style::native);
g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
}
@@ -561,8 +582,9 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
&exit_status, // Exit status
&signo, // Signal int *
&command_output, // Command output
- 30, // Large timeout to allow for long dsym download times
- false); // Don't run in a shell (we don't need shell expansion)
+ std::chrono::seconds(
+ 30), // Large timeout to allow for long dsym download times
+ false); // Don't run in a shell (we don't need shell expansion)
if (error.Success() && exit_status == 0 && !command_output.empty()) {
CFCData data(CFDataCreateWithBytesNoCopy(
NULL, (const UInt8 *)command_output.data(), command_output.size(),
diff --git a/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp b/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp
index 201ec9a8f5c2..0c52aa3ed051 100644
--- a/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp
+++ b/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp
@@ -352,9 +352,8 @@ bool CFCMutableDictionary::AddValueUInt64(CFStringRef key, uint64_t value,
CFMutableDictionaryRef dict = Dictionary(can_create);
if (dict != NULL) {
// The number may appear negative if the MSBit is set in "value". Due to a
- // limitation of
- // CFNumber, there isn't a way to have it show up otherwise as of this
- // writing.
+ // limitation of CFNumber, there isn't a way to have it show up otherwise
+ // as of this writing.
CFCReleaser<CFNumberRef> cf_number(
::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &value));
if (cf_number.get()) {
@@ -371,9 +370,8 @@ bool CFCMutableDictionary::SetValueUInt64(CFStringRef key, uint64_t value,
CFMutableDictionaryRef dict = Dictionary(can_create);
if (dict != NULL) {
// The number may appear negative if the MSBit is set in "value". Due to a
- // limitation of
- // CFNumber, there isn't a way to have it show up otherwise as of this
- // writing.
+ // limitation of CFNumber, there isn't a way to have it show up otherwise
+ // as of this writing.
CFCReleaser<CFNumberRef> cf_number(
::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &value));
if (cf_number.get()) {
@@ -390,9 +388,8 @@ bool CFCMutableDictionary::AddValueDouble(CFStringRef key, double value,
CFMutableDictionaryRef dict = Dictionary(can_create);
if (dict != NULL) {
// The number may appear negative if the MSBit is set in "value". Due to a
- // limitation of
- // CFNumber, there isn't a way to have it show up otherwise as of this
- // writing.
+ // limitation of CFNumber, there isn't a way to have it show up otherwise
+ // as of this writing.
CFCReleaser<CFNumberRef> cf_number(
::CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value));
if (cf_number.get()) {
@@ -409,9 +406,8 @@ bool CFCMutableDictionary::SetValueDouble(CFStringRef key, double value,
CFMutableDictionaryRef dict = Dictionary(can_create);
if (dict != NULL) {
// The number may appear negative if the MSBit is set in "value". Due to a
- // limitation of
- // CFNumber, there isn't a way to have it show up otherwise as of this
- // writing.
+ // limitation of CFNumber, there isn't a way to have it show up otherwise
+ // as of this writing.
CFCReleaser<CFNumberRef> cf_number(
::CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value));
if (cf_number.get()) {
diff --git a/source/Host/macosx/cfcpp/CFCString.cpp b/source/Host/macosx/cfcpp/CFCString.cpp
index 0d3853c60a72..6191f873c98a 100644
--- a/source/Host/macosx/cfcpp/CFCString.cpp
+++ b/source/Host/macosx/cfcpp/CFCString.cpp
@@ -88,9 +88,8 @@ const char *CFCString::UTF8(std::string &str) {
return CFCString::UTF8(get(), str);
}
-// Static function that puts a copy of the UTF8 contents of CF_STR into STR
-// and returns the C string pointer that is contained in STR when successful,
-// else
+// Static function that puts a copy of the UTF8 contents of CF_STR into STR and
+// returns the C string pointer that is contained in STR when successful, else
// NULL is returned. This allows the std::string parameter to own the extracted
// string,
// and also allows that string to be returned as a C string pointer that can be
@@ -129,9 +128,9 @@ const char *CFCString::ExpandTildeInPath(const char *path,
// Static function that puts a copy of the file system representation of CF_STR
// into STR and returns the C string pointer that is contained in STR when
-// successful, else NULL is returned. This allows the std::string parameter
-// to own the extracted string, and also allows that string to be returned as
-// a C string pointer that can be used.
+// successful, else NULL is returned. This allows the std::string parameter to
+// own the extracted string, and also allows that string to be returned as a C
+// string pointer that can be used.
const char *CFCString::FileSystemRepresentation(CFStringRef cf_str,
std::string &str) {
diff --git a/source/Host/macosx/objcxx/CMakeLists.txt b/source/Host/macosx/objcxx/CMakeLists.txt
new file mode 100644
index 000000000000..77e3091dc4fe
--- /dev/null
+++ b/source/Host/macosx/objcxx/CMakeLists.txt
@@ -0,0 +1,20 @@
+
+remove_module_flags()
+include_directories(..)
+
+add_lldb_library(lldbHostMacOSXObjCXX
+ Host.mm
+ HostInfoMacOSX.mm
+ HostThreadMacOSX.mm
+
+ LINK_LIBS
+ lldbCore
+ lldbSymbol
+ lldbTarget
+ lldbUtility
+ ${EXTRA_LIBS}
+
+ LINK_COMPONENTS
+ Object
+ Support
+ )
diff --git a/source/Host/macosx/Host.mm b/source/Host/macosx/objcxx/Host.mm
index 7359815fdf70..a70bf0421ec4 100644
--- a/source/Host/macosx/Host.mm
+++ b/source/Host/macosx/objcxx/Host.mm
@@ -54,13 +54,10 @@
#include <sys/types.h>
#include <unistd.h>
-#include "lldb/Core/Communication.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Target/Platform.h"
+#include "lldb/Target/ProcessLaunchInfo.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/CleanUp.h"
@@ -72,15 +69,16 @@
#include "lldb/Utility/NameMatches.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StructuredData.h"
+#include "lldb/lldb-defines.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Errno.h"
-#include "cfcpp/CFCBundle.h"
-#include "cfcpp/CFCMutableArray.h"
-#include "cfcpp/CFCMutableDictionary.h"
-#include "cfcpp/CFCReleaser.h"
-#include "cfcpp/CFCString.h"
+#include "../cfcpp/CFCBundle.h"
+#include "../cfcpp/CFCMutableArray.h"
+#include "../cfcpp/CFCMutableDictionary.h"
+#include "../cfcpp/CFCReleaser.h"
+#include "../cfcpp/CFCString.h"
#include <objc/objc-auto.h>
@@ -107,7 +105,7 @@ bool Host::GetBundleDirectory(const FileSpec &file,
if (file.GetPath(path, sizeof(path))) {
CFCBundle bundle(path);
if (bundle.GetPath(path, sizeof(path))) {
- bundle_directory.SetFile(path, false);
+ bundle_directory.SetFile(path, false, FileSpec::Style::native);
return true;
}
}
@@ -127,7 +125,7 @@ bool Host::ResolveExecutableInBundle(FileSpec &file) {
if (url.get()) {
if (::CFURLGetFileSystemRepresentation(url.get(), YES, (UInt8 *)path,
sizeof(path))) {
- file.SetFile(path, false);
+ file.SetFile(path, false, FileSpec::Style::native);
return true;
}
}
@@ -184,175 +182,6 @@ static bool WaitForProcessToSIGSTOP(const lldb::pid_t pid,
}
#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__)
-// static lldb::pid_t
-// LaunchInNewTerminalWithCommandFile
-//(
-// const char **argv,
-// const char **envp,
-// const char *working_dir,
-// const ArchSpec *arch_spec,
-// bool stop_at_entry,
-// bool disable_aslr
-//)
-//{
-// if (!argv || !argv[0])
-// return LLDB_INVALID_PROCESS_ID;
-//
-// OSStatus error = 0;
-//
-// FileSpec program (argv[0], false);
-//
-//
-// std::string unix_socket_name;
-//
-// char temp_file_path[PATH_MAX];
-// const char *tmpdir = ::getenv ("TMPDIR");
-// if (tmpdir == NULL)
-// tmpdir = "/tmp/";
-// ::snprintf (temp_file_path, sizeof(temp_file_path), "%s%s-XXXXXX", tmpdir,
-// program.GetFilename().AsCString());
-//
-// if (::mktemp (temp_file_path) == NULL)
-// return LLDB_INVALID_PROCESS_ID;
-//
-// unix_socket_name.assign (temp_file_path);
-//
-// ::strlcat (temp_file_path, ".command", sizeof (temp_file_path));
-//
-// StreamFile command_file;
-// command_file.GetFile().Open (temp_file_path,
-// File::eOpenOptionWrite |
-// File::eOpenOptionCanCreate,
-// lldb::eFilePermissionsDefault);
-//
-// if (!command_file.GetFile().IsValid())
-// return LLDB_INVALID_PROCESS_ID;
-//
-// FileSpec darwin_debug_file_spec;
-// if (!HostInfo::GetLLDBPath (ePathTypeSupportExecutableDir,
-// darwin_debug_file_spec))
-// return LLDB_INVALID_PROCESS_ID;
-// darwin_debug_file_spec.GetFilename().SetCString("darwin-debug");
-//
-// if (!darwin_debug_file_spec.Exists())
-// return LLDB_INVALID_PROCESS_ID;
-//
-// char launcher_path[PATH_MAX];
-// darwin_debug_file_spec.GetPath(launcher_path, sizeof(launcher_path));
-// command_file.Printf("\"%s\" ", launcher_path);
-//
-// command_file.Printf("--unix-socket=%s ", unix_socket_name.c_str());
-//
-// if (arch_spec && arch_spec->IsValid())
-// {
-// command_file.Printf("--arch=%s ", arch_spec->GetArchitectureName());
-// }
-//
-// if (disable_aslr)
-// {
-// command_file.PutCString("--disable-aslr ");
-// }
-//
-// command_file.PutCString("-- ");
-//
-// if (argv)
-// {
-// for (size_t i=0; argv[i] != NULL; ++i)
-// {
-// command_file.Printf("\"%s\" ", argv[i]);
-// }
-// }
-// command_file.PutCString("\necho Process exited with status $?\n");
-// command_file.GetFile().Close();
-// if (::chmod (temp_file_path, S_IRWXU | S_IRWXG) != 0)
-// return LLDB_INVALID_PROCESS_ID;
-//
-// CFCMutableDictionary cf_env_dict;
-//
-// const bool can_create = true;
-// if (envp)
-// {
-// for (size_t i=0; envp[i] != NULL; ++i)
-// {
-// const char *env_entry = envp[i];
-// const char *equal_pos = strchr(env_entry, '=');
-// if (equal_pos)
-// {
-// std::string env_key (env_entry, equal_pos);
-// std::string env_val (equal_pos + 1);
-// CFCString cf_env_key (env_key.c_str(), kCFStringEncodingUTF8);
-// CFCString cf_env_val (env_val.c_str(), kCFStringEncodingUTF8);
-// cf_env_dict.AddValue (cf_env_key.get(), cf_env_val.get(),
-// can_create);
-// }
-// }
-// }
-//
-// LSApplicationParameters app_params;
-// ::memset (&app_params, 0, sizeof (app_params));
-// app_params.flags = kLSLaunchDontAddToRecents | kLSLaunchAsync;
-// app_params.argv = NULL;
-// app_params.environment = (CFDictionaryRef)cf_env_dict.get();
-//
-// CFCReleaser<CFURLRef> command_file_url
-// (::CFURLCreateFromFileSystemRepresentation (NULL,
-// (const UInt8 *)temp_file_path,
-// strlen(temp_file_path),
-// false));
-//
-// CFCMutableArray urls;
-//
-// // Terminal.app will open the ".command" file we have created
-// // and run our process inside it which will wait at the entry point
-// // for us to attach.
-// urls.AppendValue(command_file_url.get());
-//
-//
-// lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
-//
-// Status lldb_error;
-// // Sleep and wait a bit for debugserver to start to listen...
-// char connect_url[128];
-// ::snprintf (connect_url, sizeof(connect_url), "unix-accept://%s",
-// unix_socket_name.c_str());
-//
-// // Spawn a new thread to accept incoming connection on the connect_url
-// // so we can grab the pid from the inferior
-// lldb::thread_t accept_thread = Host::ThreadCreate
-// (unix_socket_name.c_str(),
-// AcceptPIDFromInferior,
-// connect_url,
-// &lldb_error);
-//
-// ProcessSerialNumber psn;
-// error = LSOpenURLsWithRole(urls.get(), kLSRolesShell, NULL, &app_params,
-// &psn, 1);
-// if (error == noErr)
-// {
-// thread_result_t accept_thread_result = NULL;
-// if (Host::ThreadJoin (accept_thread, &accept_thread_result,
-// &lldb_error))
-// {
-// if (accept_thread_result)
-// {
-// pid = (intptr_t)accept_thread_result;
-//
-// // Wait for process to be stopped the entry point by watching
-// // for the process status to be set to SSTOP which indicates
-// it it
-// // SIGSTOP'ed at the entry point
-// WaitForProcessToSIGSTOP (pid, 5);
-// }
-// }
-// }
-// else
-// {
-// Host::ThreadCancel (accept_thread, &lldb_error);
-// }
-//
-// return pid;
-//}
-
const char *applscript_in_new_tty = "tell application \"Terminal\"\n"
" activate\n"
" do script \"/bin/bash -c '%s';exit\"\n"
@@ -388,9 +217,8 @@ LaunchInNewTerminalWithAppleScript(const char *exe_path,
}
StreamString command;
- FileSpec darwin_debug_file_spec;
- if (!HostInfo::GetLLDBPath(ePathTypeSupportExecutableDir,
- darwin_debug_file_spec)) {
+ FileSpec darwin_debug_file_spec = HostInfo::GetSupportExeDir();
+ if (!darwin_debug_file_spec) {
error.SetErrorString("can't locate the 'darwin-debug' executable");
return error;
}
@@ -431,33 +259,16 @@ LaunchInNewTerminalWithAppleScript(const char *exe_path,
command.PutCString(" --disable-aslr");
// We are launching on this host in a terminal. So compare the environment on
- // the host
- // to what is supplied in the launch_info. Any items that aren't in the host
- // environment
- // need to be sent to darwin-debug. If we send all environment entries, we
- // might blow the
- // max command line length, so we only send user modified entries.
- const char **envp =
- launch_info.GetEnvironmentEntries().GetConstArgumentVector();
-
- StringList host_env;
- const size_t host_env_count = Host::GetEnvironment(host_env);
+ // the host to what is supplied in the launch_info. Any items that aren't in
+ // the host environment need to be sent to darwin-debug. If we send all
+ // environment entries, we might blow the max command line length, so we only
+ // send user modified entries.
+ Environment host_env = Host::GetEnvironment();
- if (envp && envp[0]) {
- const char *env_entry;
- for (size_t env_idx = 0; (env_entry = envp[env_idx]) != NULL; ++env_idx) {
- bool add_entry = true;
- for (size_t i = 0; i < host_env_count; ++i) {
- const char *host_env_entry = host_env.GetStringAtIndex(i);
- if (strcmp(env_entry, host_env_entry) == 0) {
- add_entry = false;
- break;
- }
- }
- if (add_entry) {
- command.Printf(" --env='%s'", env_entry);
- }
- }
+ for (const auto &KV : launch_info.GetEnvironment()) {
+ auto host_entry = host_env.find(KV.first());
+ if (host_entry == host_env.end() || host_entry->second != KV.second)
+ command.Format(" --env='{0}'", Environment::compose(KV));
}
command.PutCString(" -- ");
@@ -479,19 +290,8 @@ LaunchInNewTerminalWithAppleScript(const char *exe_path,
StreamString applescript_source;
- // if (tty_name && tty_name[0])
- // {
- // applescript_source.Printf (applscript_in_existing_tty,
- // tty_command,
- // tty_name);
- // }
- // else
- // {
applescript_source.Printf(applscript_in_new_tty,
command.GetString().str().c_str());
- // }
-
- // puts (script_source);
NSAppleScript *applescript = [[NSAppleScript alloc]
initWithSource:[NSString stringWithCString:applescript_source.GetString()
.str()
@@ -641,14 +441,7 @@ bool Host::OpenFileInExternalEditor(const FileSpec &file_spec,
#endif // #if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__)
}
-size_t Host::GetEnvironment(StringList &env) {
- char **host_env = *_NSGetEnviron();
- char *env_entry;
- size_t i;
- for (i = 0; (env_entry = host_env[i]) != NULL; ++i)
- env.AppendString(env_entry);
- return i;
-}
+Environment Host::GetEnvironment() { return Environment(*_NSGetEnviron()); }
static bool GetMacOSXProcessCPUType(ProcessInstanceInfo &process_info) {
if (process_info.ProcessIDIsValid()) {
@@ -748,7 +541,8 @@ static bool GetMacOSXProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
triple_arch == llvm::Triple::x86_64);
const char *cstr = data.GetCStr(&offset);
if (cstr) {
- process_info.GetExecutableFile().SetFile(cstr, false);
+ process_info.GetExecutableFile().SetFile(cstr, false,
+ FileSpec::Style::native);
if (match_info_ptr == NULL ||
NameMatches(
@@ -770,7 +564,7 @@ static bool GetMacOSXProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
proc_args.AppendArgument(llvm::StringRef(cstr));
}
- Args &proc_env = process_info.GetEnvironmentEntries();
+ Environment &proc_env = process_info.GetEnvironment();
while ((cstr = data.GetCStr(&offset))) {
if (cstr[0] == '\0')
break;
@@ -785,7 +579,7 @@ static bool GetMacOSXProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
llvm::Triple::MacOSX);
}
- proc_env.AppendArgument(llvm::StringRef(cstr));
+ proc_env.insert(cstr);
}
return true;
}
@@ -939,6 +733,17 @@ static void PackageXPCArguments(xpc_object_t message, const char *prefix,
}
}
+static void PackageXPCEnvironment(xpc_object_t message, llvm::StringRef prefix,
+ const Environment &env) {
+ xpc_dictionary_set_int64(message, (prefix + "Count").str().c_str(),
+ env.size());
+ size_t i = 0;
+ for (const auto &KV : env) {
+ xpc_dictionary_set_string(message, (prefix + llvm::Twine(i)).str().c_str(),
+ Environment::compose(KV).c_str());
+ }
+}
+
/*
A valid authorizationRef means that
- there is the LaunchUsingXPCRightName rights in the /etc/authorization
@@ -1045,14 +850,11 @@ static short GetPosixspawnFlags(const ProcessLaunchInfo &launch_info) {
if (g_use_close_on_exec_flag == eLazyBoolCalculate) {
g_use_close_on_exec_flag = eLazyBoolNo;
- uint32_t major, minor, update;
- if (HostInfo::GetOSVersion(major, minor, update)) {
+ llvm::VersionTuple version = HostInfo::GetOSVersion();
+ if (version > llvm::VersionTuple(10, 7)) {
// Kernel panic if we use the POSIX_SPAWN_CLOEXEC_DEFAULT on 10.7 or
// earlier
- if (major > 10 || (major == 10 && minor > 7)) {
- // Only enable for 10.8 and later OS versions
- g_use_close_on_exec_flag = eLazyBoolYes;
- }
+ g_use_close_on_exec_flag = eLazyBoolYes;
}
}
#else
@@ -1141,8 +943,8 @@ static Status LaunchProcessXPC(const char *exe_path,
PackageXPCArguments(message, LauncherXPCServiceArgPrefxKey,
launch_info.GetArguments());
- PackageXPCArguments(message, LauncherXPCServiceEnvPrefxKey,
- launch_info.GetEnvironmentEntries());
+ PackageXPCEnvironment(message, LauncherXPCServiceEnvPrefxKey,
+ launch_info.GetEnvironment());
// Posix spawn stuff.
xpc_dictionary_set_int64(message, LauncherXPCServiceCPUTypeKey,
@@ -1294,10 +1096,8 @@ static Status LaunchProcessPosixSpawn(const char *exe_path,
return error;
}
- // Make a quick class that will cleanup the posix spawn attributes in case
- // we return in the middle of this function.
- lldb_utility::CleanUp<posix_spawnattr_t *, int> posix_spawnattr_cleanup(
- &attr, posix_spawnattr_destroy);
+ // Make sure we clean up the posix spawn attributes before exiting this scope.
+ CleanUp cleanup_attr(posix_spawnattr_destroy, &attr);
sigset_t no_signals;
sigset_t all_signals;
@@ -1356,8 +1156,7 @@ static Status LaunchProcessPosixSpawn(const char *exe_path,
const char *tmp_argv[2];
char *const *argv = const_cast<char *const *>(
launch_info.GetArguments().GetConstArgumentVector());
- char *const *envp = const_cast<char *const *>(
- launch_info.GetEnvironmentEntries().GetConstArgumentVector());
+ Environment::Envp envp = launch_info.GetEnvironment().getEnvp();
if (argv == NULL) {
// posix_spawn gets very unhappy if it doesn't have at least the program
// name in argv[0]. One of the side affects I have noticed is the
@@ -1400,11 +1199,8 @@ static Status LaunchProcessPosixSpawn(const char *exe_path,
return error;
}
- // Make a quick class that will cleanup the posix spawn attributes in case
- // we return in the middle of this function.
- lldb_utility::CleanUp<posix_spawn_file_actions_t *, int>
- posix_spawn_file_actions_cleanup(&file_actions,
- posix_spawn_file_actions_destroy);
+ // Make sure we clean up the posix file actions before exiting this scope.
+ CleanUp cleanup_fileact(posix_spawn_file_actions_destroy, &file_actions);
for (size_t i = 0; i < num_file_actions; ++i) {
const FileAction *launch_file_action =
@@ -1425,7 +1221,8 @@ static Status LaunchProcessPosixSpawn(const char *exe_path,
"error: {0}, ::posix_spawnp(pid => {1}, path = '{2}', "
"file_actions = {3}, "
"attr = {4}, argv = {5}, envp = {6} )",
- error, result_pid, exe_path, &file_actions, &attr, argv, envp);
+ error, result_pid, exe_path, &file_actions, &attr, argv,
+ envp.get());
if (log) {
for (int ii = 0; argv[ii]; ++ii)
LLDB_LOG(log, "argv[{0}] = '{1}'", ii, argv[ii]);
@@ -1441,7 +1238,7 @@ static Status LaunchProcessPosixSpawn(const char *exe_path,
LLDB_LOG(log,
"error: {0}, ::posix_spawnp ( pid => {1}, path = '{2}', "
"file_actions = NULL, attr = {3}, argv = {4}, envp = {5} )",
- error, result_pid, exe_path, &attr, argv, envp);
+ error, result_pid, exe_path, &attr, argv, envp.get());
if (log) {
for (int ii = 0; argv[ii]; ++ii)
LLDB_LOG(log, "argv[{0}] = '{1}'", ii, argv[ii]);
@@ -1476,36 +1273,28 @@ static bool ShouldLaunchUsingXPC(ProcessLaunchInfo &launch_info) {
Status Host::LaunchProcess(ProcessLaunchInfo &launch_info) {
Status error;
- char exe_path[PATH_MAX];
- PlatformSP host_platform_sp(Platform::GetHostPlatform());
-
- ModuleSpec exe_module_spec(launch_info.GetExecutableFile(),
- launch_info.GetArchitecture());
-
- if (!llvm::sys::fs::is_regular_file(
- exe_module_spec.GetFileSpec().GetPath())) {
- lldb::ModuleSP exe_module_sp;
- error = host_platform_sp->ResolveExecutable(exe_module_spec, exe_module_sp,
- NULL);
-
- if (error.Fail())
- return error;
+ FileSpec exe_spec(launch_info.GetExecutableFile());
- if (exe_module_sp)
- exe_module_spec.GetFileSpec() = exe_module_sp->GetFileSpec();
+ llvm::sys::fs::file_status stats;
+ status(exe_spec.GetPath(), stats);
+ if (!exists(stats)) {
+ exe_spec.ResolvePath();
+ status(exe_spec.GetPath(), stats);
}
-
- if (exe_module_spec.GetFileSpec().Exists()) {
- exe_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
- } else {
- launch_info.GetExecutableFile().GetPath(exe_path, sizeof(exe_path));
- error.SetErrorStringWithFormat("executable doesn't exist: '%s'", exe_path);
+ if (!exists(stats)) {
+ exe_spec.ResolveExecutableLocation();
+ status(exe_spec.GetPath(), stats);
+ }
+ if (!exists(stats)) {
+ error.SetErrorStringWithFormatv("executable doesn't exist: '{0}'",
+ launch_info.GetExecutableFile());
return error;
}
if (launch_info.GetFlags().Test(eLaunchFlagLaunchInTTY)) {
#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__)
- return LaunchInNewTerminalWithAppleScript(exe_path, launch_info);
+ return LaunchInNewTerminalWithAppleScript(exe_spec.GetPath().c_str(),
+ launch_info);
#else
error.SetErrorString("launching a process in a new terminal is not "
"supported on iOS devices");
@@ -1516,9 +1305,10 @@ Status Host::LaunchProcess(ProcessLaunchInfo &launch_info) {
lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
if (ShouldLaunchUsingXPC(launch_info)) {
- error = LaunchProcessXPC(exe_path, launch_info, pid);
+ error = LaunchProcessXPC(exe_spec.GetPath().c_str(), launch_info, pid);
} else {
- error = LaunchProcessPosixSpawn(exe_path, launch_info, pid);
+ error =
+ LaunchProcessPosixSpawn(exe_spec.GetPath().c_str(), launch_info, pid);
}
if (pid != LLDB_INVALID_PROCESS_ID) {
@@ -1526,15 +1316,9 @@ Status Host::LaunchProcess(ProcessLaunchInfo &launch_info) {
launch_info.SetProcessID(pid);
// Make sure we reap any processes we spawn or we will have zombies.
- if (!launch_info.MonitorProcess()) {
- const bool monitor_signals = false;
- Host::MonitorChildProcessCallback callback = nullptr;
-
- if (!launch_info.GetFlags().Test(lldb::eLaunchFlagDontSetExitStatus))
- callback = Process::SetProcessExitStatus;
-
- StartMonitoringChildProcess(callback, pid, monitor_signals);
- }
+ bool monitoring = launch_info.MonitorProcess();
+ UNUSED_IF_ASSERT_DISABLED(monitoring);
+ assert(monitoring);
} else {
// Invalid process ID, something didn't go well
if (error.Success())
@@ -1546,9 +1330,8 @@ Status Host::LaunchProcess(ProcessLaunchInfo &launch_info) {
Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
Status error;
if (launch_info.GetFlags().Test(eLaunchFlagShellExpandArguments)) {
- FileSpec expand_tool_spec;
- if (!HostInfo::GetLLDBPath(lldb::ePathTypeSupportExecutableDir,
- expand_tool_spec)) {
+ FileSpec expand_tool_spec = HostInfo::GetSupportExeDir();
+ if (!expand_tool_spec) {
error.SetErrorString(
"could not get support executable directory for lldb-argdumper tool");
return error;
@@ -1583,7 +1366,8 @@ Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
launch_info.SetWorkingDirectory(working_dir);
}
}
- RunShellCommand(expand_command, cwd, &status, nullptr, &output, 10);
+ RunShellCommand(expand_command, cwd, &status, nullptr, &output,
+ std::chrono::seconds(10));
if (status != 0) {
error.SetErrorStringWithFormat("lldb-argdumper exited with error %d",
diff --git a/source/Host/macosx/HostInfoMacOSX.mm b/source/Host/macosx/objcxx/HostInfoMacOSX.mm
index 8774c76ef2da..a39d26aa31ae 100644
--- a/source/Host/macosx/HostInfoMacOSX.mm
+++ b/source/Host/macosx/objcxx/HostInfoMacOSX.mm
@@ -7,18 +7,15 @@
//
//===----------------------------------------------------------------------===//
-#if !defined(LLDB_DISABLE_PYTHON)
-#include "Plugins/ScriptInterpreter/Python/lldb-python.h"
-#endif
-
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/macosx/HostInfoMacOSX.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/SafeMachO.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
// C++ Includes
@@ -30,7 +27,7 @@
#include <sys/syslimits.h>
#include <sys/types.h>
-// Objective C/C++ includes
+// Objective-C/C++ includes
#include <CoreFoundation/CoreFoundation.h>
#include <Foundation/Foundation.h>
#include <mach-o/dyld.h>
@@ -75,32 +72,21 @@ bool HostInfoMacOSX::GetOSKernelDescription(std::string &s) {
return false;
}
-bool HostInfoMacOSX::GetOSVersion(uint32_t &major, uint32_t &minor,
- uint32_t &update) {
- static uint32_t g_major = 0;
- static uint32_t g_minor = 0;
- static uint32_t g_update = 0;
+llvm::VersionTuple HostInfoMacOSX::GetOSVersion() {
+ static llvm::VersionTuple g_version;
- if (g_major == 0) {
+ if (g_version.empty()) {
@autoreleasepool {
NSDictionary *version_info = [NSDictionary
dictionaryWithContentsOfFile:
@"/System/Library/CoreServices/SystemVersion.plist"];
NSString *version_value = [version_info objectForKey:@"ProductVersion"];
const char *version_str = [version_value UTF8String];
- if (version_str)
- Args::StringToVersion(llvm::StringRef(version_str), g_major, g_minor,
- g_update);
+ g_version.tryParse(version_str);
}
}
- if (g_major != 0) {
- major = g_major;
- minor = g_minor;
- update = g_update;
- return true;
- }
- return false;
+ return g_version;
}
FileSpec HostInfoMacOSX::GetProgramFileSpec() {
@@ -111,13 +97,15 @@ FileSpec HostInfoMacOSX::GetProgramFileSpec() {
uint32_t len = sizeof(program_fullpath);
int err = _NSGetExecutablePath(program_fullpath, &len);
if (err == 0)
- g_program_filespec.SetFile(program_fullpath, false);
+ g_program_filespec.SetFile(program_fullpath, false,
+ FileSpec::Style::native);
else if (err == -1) {
char *large_program_fullpath = (char *)::malloc(len + 1);
err = _NSGetExecutablePath(large_program_fullpath, &len);
if (err == 0)
- g_program_filespec.SetFile(large_program_fullpath, false);
+ g_program_filespec.SetFile(large_program_fullpath, false,
+ FileSpec::Style::native);
::free(large_program_fullpath);
}
@@ -126,8 +114,8 @@ FileSpec HostInfoMacOSX::GetProgramFileSpec() {
}
bool HostInfoMacOSX::ComputeSupportExeDirectory(FileSpec &file_spec) {
- FileSpec lldb_file_spec;
- if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
+ FileSpec lldb_file_spec = GetShlibDir();
+ if (!lldb_file_spec)
return false;
std::string raw_path = lldb_file_spec.GetPath();
@@ -179,8 +167,8 @@ bool HostInfoMacOSX::ComputeSupportExeDirectory(FileSpec &file_spec) {
}
bool HostInfoMacOSX::ComputeHeaderDirectory(FileSpec &file_spec) {
- FileSpec lldb_file_spec;
- if (!HostInfo::GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
+ FileSpec lldb_file_spec = GetShlibDir();
+ if (!lldb_file_spec)
return false;
std::string raw_path = lldb_file_spec.GetPath();
@@ -196,58 +184,9 @@ bool HostInfoMacOSX::ComputeHeaderDirectory(FileSpec &file_spec) {
return true;
}
-bool HostInfoMacOSX::ComputePythonDirectory(FileSpec &file_spec) {
-#ifndef LLDB_DISABLE_PYTHON
- FileSpec lldb_file_spec;
- if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
- return false;
-
- std::string raw_path = lldb_file_spec.GetPath();
-
- size_t framework_pos = raw_path.find("LLDB.framework");
- if (framework_pos != std::string::npos) {
- framework_pos += strlen("LLDB.framework");
- raw_path.resize(framework_pos);
- raw_path.append("/Resources/Python");
- } else {
- llvm::SmallString<256> python_version_dir;
- llvm::raw_svector_ostream os(python_version_dir);
- os << "/python" << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION
- << "/site-packages";
-
- // We may get our string truncated. Should we protect this with an assert?
- raw_path.append(python_version_dir.c_str());
- }
- file_spec.GetDirectory().SetString(
- llvm::StringRef(raw_path.c_str(), raw_path.size()));
- return true;
-#else
- return false;
-#endif
-}
-
-bool HostInfoMacOSX::ComputeClangDirectory(FileSpec &file_spec) {
- FileSpec lldb_file_spec;
- if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
- return false;
-
- std::string raw_path = lldb_file_spec.GetPath();
-
- size_t framework_pos = raw_path.find("LLDB.framework");
- if (framework_pos == std::string::npos)
- return HostInfoPosix::ComputeClangDirectory(file_spec);
-
- framework_pos += strlen("LLDB.framework");
- raw_path.resize(framework_pos);
- raw_path.append("/Resources/Clang");
-
- file_spec.SetFile(raw_path.c_str(), true);
- return true;
-}
-
bool HostInfoMacOSX::ComputeSystemPluginsDirectory(FileSpec &file_spec) {
- FileSpec lldb_file_spec;
- if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
+ FileSpec lldb_file_spec = GetShlibDir();
+ if (!lldb_file_spec)
return false;
std::string raw_path = lldb_file_spec.GetPath();
diff --git a/source/Host/macosx/HostThreadMacOSX.mm b/source/Host/macosx/objcxx/HostThreadMacOSX.mm
index c5051cdf30d7..c5051cdf30d7 100644
--- a/source/Host/macosx/HostThreadMacOSX.mm
+++ b/source/Host/macosx/objcxx/HostThreadMacOSX.mm
diff --git a/source/Host/netbsd/Host.cpp b/source/Host/netbsd/Host.cpp
index d927f95f0675..bfd5a74ffcc2 100644
--- a/source/Host/netbsd/Host.cpp
+++ b/source/Host/netbsd/Host.cpp
@@ -25,12 +25,9 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/Module.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
-#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
-#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
@@ -48,14 +45,7 @@ extern char **environ;
using namespace lldb;
using namespace lldb_private;
-size_t Host::GetEnvironment(StringList &env) {
- char **host_env = environ;
- char *env_entry;
- size_t i;
- for (i = 0; (env_entry = host_env[i]) != NULL; ++i)
- env.AppendString(env_entry);
- return i;
-}
+Environment Host::GetEnvironment() { return Environment(environ); }
static bool GetNetBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
ProcessInstanceInfo &process_info) {
@@ -80,7 +70,8 @@ static bool GetNetBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
if (!cstr)
return false;
- process_info.GetExecutableFile().SetFile(cstr, false);
+ process_info.GetExecutableFile().SetFile(cstr, false,
+ FileSpec::Style::native);
if (!(match_info_ptr == NULL ||
NameMatches(process_info.GetExecutableFile().GetFilename().GetCString(),
@@ -202,9 +193,8 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
continue;
// Every thread is a process in NetBSD, but all the threads of a single
- // process have the same pid. Do not store the process info in the
- // result list if a process with given identifier is already registered
- // there.
+ // process have the same pid. Do not store the process info in the result
+ // list if a process with given identifier is already registered there.
if (proc_kinfo[i].p_nlwps > 1) {
bool already_registered = false;
for (size_t pi = 0; pi < process_infos.GetSize(); pi++) {
diff --git a/source/Host/netbsd/HostInfoNetBSD.cpp b/source/Host/netbsd/HostInfoNetBSD.cpp
index 428183bbe2c3..dfbce310509d 100644
--- a/source/Host/netbsd/HostInfoNetBSD.cpp
+++ b/source/Host/netbsd/HostInfoNetBSD.cpp
@@ -21,30 +21,26 @@
using namespace lldb_private;
-bool HostInfoNetBSD::GetOSVersion(uint32_t &major, uint32_t &minor,
- uint32_t &update) {
+llvm::VersionTuple HostInfoNetBSD::GetOSVersion() {
struct utsname un;
::memset(&un, 0, sizeof(un));
if (::uname(&un) < 0)
- return false;
+ return llvm::VersionTuple();
/* Accept versions like 7.99.21 and 6.1_STABLE */
+ uint32_t major, minor, update;
int status = ::sscanf(un.release, "%" PRIu32 ".%" PRIu32 ".%" PRIu32, &major,
&minor, &update);
switch (status) {
- case 0:
- return false;
case 1:
- minor = 0;
- /* FALLTHROUGH */
+ return llvm::VersionTuple(major);
case 2:
- update = 0;
- /* FALLTHROUGH */
+ return llvm::VersionTuple(major, minor);
case 3:
- default:
- return true;
+ return llvm::VersionTuple(major, minor, update);
}
+ return llvm::VersionTuple();
}
bool HostInfoNetBSD::GetOSBuildString(std::string &s) {
@@ -89,7 +85,7 @@ FileSpec HostInfoNetBSD::GetProgramFileSpec() {
len = sizeof(path);
if (sysctl(name, __arraycount(name), path, &len, NULL, 0) != -1) {
- g_program_filespec.SetFile(path, false);
+ g_program_filespec.SetFile(path, false, FileSpec::Style::native);
}
}
return g_program_filespec;
diff --git a/source/Host/openbsd/Host.cpp b/source/Host/openbsd/Host.cpp
index 0535256b9aa1..49e9c290a027 100644
--- a/source/Host/openbsd/Host.cpp
+++ b/source/Host/openbsd/Host.cpp
@@ -22,12 +22,9 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/Module.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
-#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
-#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
@@ -45,16 +42,17 @@ extern char **environ;
using namespace lldb;
using namespace lldb_private;
-size_t Host::GetEnvironment(StringList &env) {
+Environment Host::GetEnvironment() {
+ Environment env;
char *v;
char **var = environ;
for (; var != NULL && *var != NULL; ++var) {
v = strchr(*var, (int)'-');
if (v == NULL)
continue;
- env.AppendString(v);
+ env.insert(v);
}
- return env.GetSize();
+ return env;
}
static bool
@@ -74,7 +72,8 @@ GetOpenBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
cstr = data.GetCStr(&offset);
if (cstr) {
- process_info.GetExecutableFile().SetFile(cstr, false);
+ process_info.GetExecutableFile().SetFile(cstr, false,
+ FileSpec::Style::native);
if (!(match_info_ptr == NULL ||
NameMatches(
diff --git a/source/Host/posix/ConnectionFileDescriptorPosix.cpp b/source/Host/posix/ConnectionFileDescriptorPosix.cpp
index 3797650105ce..c21bb786a896 100644
--- a/source/Host/posix/ConnectionFileDescriptorPosix.cpp
+++ b/source/Host/posix/ConnectionFileDescriptorPosix.cpp
@@ -189,15 +189,14 @@ ConnectionStatus ConnectionFileDescriptor::Connect(llvm::StringRef path,
}
#ifndef LLDB_DISABLE_POSIX
else if ((addr = GetURLAddress(path, FD_SCHEME))) {
- // Just passing a native file descriptor within this current process
- // that is already opened (possibly from a service or other source).
+ // Just passing a native file descriptor within this current process that
+ // is already opened (possibly from a service or other source).
int fd = -1;
if (!addr->getAsInteger(0, fd)) {
- // We have what looks to be a valid file descriptor, but we
- // should make sure it is. We currently are doing this by trying to
- // get the flags from the file descriptor and making sure it
- // isn't a bad fd.
+ // We have what looks to be a valid file descriptor, but we should make
+ // sure it is. We currently are doing this by trying to get the flags
+ // from the file descriptor and making sure it isn't a bad fd.
errno = 0;
int flags = ::fcntl(fd, F_GETFL, 0);
if (flags == -1 || errno == EBADF) {
@@ -208,20 +207,18 @@ ConnectionStatus ConnectionFileDescriptor::Connect(llvm::StringRef path,
m_write_sp.reset();
return eConnectionStatusError;
} else {
- // 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.
+ // 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.
// TODO: Since are using a URL to open connection we should
- // eventually parse options using the web standard where we
- // have "fd://123?opt1=value;opt2=value" and we can have an
- // 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.
+ // eventually parse options using the web standard where we have
+ // "fd://123?opt1=value;opt2=value" and we can have an 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.
std::unique_ptr<TCPSocket> tcp_socket;
tcp_socket.reset(new TCPSocket(fd, false, false));
- // Try and get a socket option from this file descriptor to
- // see if this is a socket and set m_is_socket accordingly.
+ // 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);
@@ -320,13 +317,11 @@ ConnectionStatus ConnectionFileDescriptor::Disconnect(Status *error_ptr) {
m_read_sp->GetFdType() == IOObject::eFDTypeSocket)
static_cast<Socket &>(*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.
+ // 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;
@@ -430,11 +425,11 @@ size_t ConnectionFileDescriptor::Read(void *dst, size_t dst_len,
case EINVAL: // The pointer associated with fildes was negative.
case EIO: // An I/O error occurred while reading from the file system.
// The process group is orphaned.
- // The file is a regular file, nbyte is greater than 0,
- // the starting position is before the end-of-file, and
- // the starting position is greater than or equal to the
- // offset maximum established for the open file
- // descriptor associated with fildes.
+ // The file is a regular file, nbyte is greater than 0, the
+ // starting position is before the end-of-file, and the
+ // starting position is greater than or equal to the offset
+ // maximum established for the open file descriptor
+ // associated with fildes.
case EISDIR: // An attempt is made to read a directory.
case ENOBUFS: // An attempt to allocate a memory buffer fails.
case ENOMEM: // Insufficient memory is available.
@@ -550,15 +545,15 @@ ConnectionStatus
ConnectionFileDescriptor::BytesAvailable(const Timeout<std::micro> &timeout,
Status *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.
+ // Read. If we ever get used more generally we will need to lock here as
+ // well.
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_CONNECTION));
LLDB_LOG(log, "this = {0}, timeout = {1}", this, timeout);
- // 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()
+ // 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 IOObject::WaitableHandle handle = m_read_sp->GetWaitableHandle();
const int pipe_fd = m_pipe.GetReadFileDescriptor();
@@ -570,10 +565,9 @@ ConnectionFileDescriptor::BytesAvailable(const Timeout<std::micro> &timeout,
select_helper.FDSetRead(handle);
#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.
+ // 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;
@@ -603,11 +597,10 @@ ConnectionFileDescriptor::BytesAvailable(const Timeout<std::micro> &timeout,
return eConnectionStatusTimedOut;
case EAGAIN: // The kernel was (perhaps temporarily) unable to
- // allocate the requested number of file descriptors,
- // or we have non-blocking IO
+ // 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.
+ // expired and before any of the selected events occurred.
break; // Lets keep reading to until we timeout
}
} else {
@@ -615,8 +608,8 @@ ConnectionFileDescriptor::BytesAvailable(const Timeout<std::micro> &timeout,
return eConnectionStatusSuccess;
if (select_helper.FDIsSetRead(pipe_fd)) {
- // There is an interrupt or exit command in the command pipe
- // Read the data from that pipe:
+ // There is an interrupt or exit command in the command pipe Read the
+ // data from that pipe:
char c;
ssize_t bytes_read = llvm::sys::RetryAfterSignal(-1, ::read, pipe_fd, &c, 1);
@@ -753,14 +746,10 @@ ConnectionStatus ConnectionFileDescriptor::ConnectUDP(llvm::StringRef s,
return eConnectionStatusSuccess;
}
-uint16_t ConnectionFileDescriptor::GetListeningPort(uint32_t timeout_sec) {
- uint16_t bound_port = 0;
- if (timeout_sec == UINT32_MAX)
- m_port_predicate.WaitForValueNotEqualTo(0, bound_port);
- else
- m_port_predicate.WaitForValueNotEqualTo(0, bound_port,
- std::chrono::seconds(timeout_sec));
- return bound_port;
+uint16_t
+ConnectionFileDescriptor::GetListeningPort(const Timeout<std::micro> &timeout) {
+ auto Result = m_port_predicate.WaitForValueNotEqualTo(0, timeout);
+ return Result ? *Result : 0;
}
bool ConnectionFileDescriptor::GetChildProcessesInherit() const {
diff --git a/source/Host/posix/FileSystem.cpp b/source/Host/posix/FileSystem.cpp
index 3ece0677f991..60be642df608 100644
--- a/source/Host/posix/FileSystem.cpp
+++ b/source/Host/posix/FileSystem.cpp
@@ -16,11 +16,6 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
-#ifdef __linux__
-#include <linux/magic.h>
-#include <sys/mount.h>
-#include <sys/statfs.h>
-#endif
#if defined(__NetBSD__)
#include <sys/statvfs.h>
#endif
@@ -52,7 +47,7 @@ Status FileSystem::Readlink(const FileSpec &src, FileSpec &dst) {
error.SetErrorToErrno();
else {
buf[count] = '\0'; // Success
- dst.SetFile(buf, false);
+ dst.SetFile(buf, false, FileSpec::Style::native);
}
return error;
}
diff --git a/source/Host/posix/HostInfoPosix.cpp b/source/Host/posix/HostInfoPosix.cpp
index da9e1fb366cc..62c70fa3edc1 100644
--- a/source/Host/posix/HostInfoPosix.cpp
+++ b/source/Host/posix/HostInfoPosix.cpp
@@ -7,15 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#if !defined(LLDB_DISABLE_PYTHON)
-#include "Plugins/ScriptInterpreter/Python/lldb-python.h"
-#endif
-
#include "lldb/Host/posix/HostInfoPosix.h"
#include "lldb/Utility/Log.h"
-#include "clang/Basic/Version.h"
-#include "clang/Config/config.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Path.h"
@@ -103,8 +97,7 @@ const char *HostInfoPosix::LookupGroupName(uint32_t gid,
}
} else {
// The threadsafe version isn't currently working for me on darwin, but the
- // non-threadsafe version
- // is, so I am calling it below.
+ // non-threadsafe version is, so I am calling it below.
group_info_ptr = ::getgrgid(gid);
if (group_info_ptr) {
group_name.assign(group_info_ptr->gr_name);
@@ -132,8 +125,8 @@ bool HostInfoPosix::ComputePathRelativeToLibrary(FileSpec &file_spec,
llvm::StringRef dir) {
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- FileSpec lldb_file_spec;
- if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
+ FileSpec lldb_file_spec = GetShlibDir();
+ if (!lldb_file_spec)
return false;
std::string raw_path = lldb_file_spec.GetPath();
@@ -141,8 +134,8 @@ bool HostInfoPosix::ComputePathRelativeToLibrary(FileSpec &file_spec,
llvm::StringRef parent_path = llvm::sys::path::parent_path(raw_path);
// Most Posix systems (e.g. Linux/*BSD) will attempt to replace a */lib with
- // */bin as the base directory for helper exe programs. This will fail if the
- // /lib and /bin directories are rooted in entirely different trees.
+ // */bin as the base directory for helper exe programs. This will fail if
+ // the /lib and /bin directories are rooted in entirely different trees.
if (log)
log->Printf("HostInfoPosix::ComputePathRelativeToLibrary() attempting to "
"derive the %s path from this path: %s",
@@ -169,59 +162,12 @@ bool HostInfoPosix::ComputeSupportExeDirectory(FileSpec &file_spec) {
return ComputePathRelativeToLibrary(file_spec, "/bin");
}
-bool HostInfoPosix::ComputeClangDirectory(FileSpec &file_spec) {
- return ComputePathRelativeToLibrary(
- file_spec, (llvm::Twine("/lib") + CLANG_LIBDIR_SUFFIX + "/clang/" +
- CLANG_VERSION_STRING)
- .str());
-}
-
bool HostInfoPosix::ComputeHeaderDirectory(FileSpec &file_spec) {
FileSpec temp_file("/opt/local/include/lldb", false);
file_spec.GetDirectory().SetCString(temp_file.GetPath().c_str());
return true;
}
-bool HostInfoPosix::ComputePythonDirectory(FileSpec &file_spec) {
-#ifndef LLDB_DISABLE_PYTHON
- FileSpec lldb_file_spec;
- if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
- return false;
-
- char raw_path[PATH_MAX];
- lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
-
-#if defined(LLDB_PYTHON_RELATIVE_LIBDIR)
- // Build the path by backing out of the lib dir, then building
- // with whatever the real python interpreter uses. (e.g. lib
- // for most, lib64 on RHEL x86_64).
- char python_path[PATH_MAX];
- ::snprintf(python_path, sizeof(python_path), "%s/../%s", raw_path,
- LLDB_PYTHON_RELATIVE_LIBDIR);
-
- char final_path[PATH_MAX];
- realpath(python_path, final_path);
- file_spec.GetDirectory().SetCString(final_path);
-
- return true;
-#else
- llvm::SmallString<256> python_version_dir;
- llvm::raw_svector_ostream os(python_version_dir);
- os << "/python" << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION
- << "/site-packages";
-
- // We may get our string truncated. Should we protect this with an assert?
- ::strncat(raw_path, python_version_dir.c_str(),
- sizeof(raw_path) - strlen(raw_path) - 1);
-
- file_spec.GetDirectory().SetCString(raw_path);
- return true;
-#endif
-#else
- return false;
-#endif
-}
-
bool HostInfoPosix::GetEnvironmentVar(const std::string &var_name,
std::string &var) {
if (const char *pvar = ::getenv(var_name.c_str())) {
diff --git a/source/Host/posix/HostThreadPosix.cpp b/source/Host/posix/HostThreadPosix.cpp
index 71abb76dc600..13de42f763ec 100644
--- a/source/Host/posix/HostThreadPosix.cpp
+++ b/source/Host/posix/HostThreadPosix.cpp
@@ -41,14 +41,11 @@ Status HostThreadPosix::Join(lldb::thread_result_t *result) {
Status HostThreadPosix::Cancel() {
Status error;
if (IsJoinable()) {
-#ifndef __ANDROID__
#ifndef __FreeBSD__
llvm_unreachable("someone is calling HostThread::Cancel()");
-#endif
+#else
int err = ::pthread_cancel(m_thread);
error.SetError(err, eErrorTypePOSIX);
-#else
- error.SetErrorString("HostThreadPosix::Cancel() not supported on Android");
#endif
}
return error;
diff --git a/source/Host/posix/PipePosix.cpp b/source/Host/posix/PipePosix.cpp
index da99fd702424..b321cad64275 100644
--- a/source/Host/posix/PipePosix.cpp
+++ b/source/Host/posix/PipePosix.cpp
@@ -127,18 +127,14 @@ Status PipePosix::CreateWithUniqueName(llvm::StringRef prefix,
llvm::SmallVectorImpl<char> &name) {
llvm::SmallString<PATH_MAX> named_pipe_path;
llvm::SmallString<PATH_MAX> pipe_spec((prefix + ".%%%%%%").str());
- FileSpec tmpdir_file_spec;
- tmpdir_file_spec.Clear();
- if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) {
- tmpdir_file_spec.AppendPathComponent(pipe_spec.c_str());
- } else {
+ FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir();
+ if (!tmpdir_file_spec)
tmpdir_file_spec.AppendPathComponent("/tmp");
- tmpdir_file_spec.AppendPathComponent(pipe_spec.c_str());
- }
+ tmpdir_file_spec.AppendPathComponent(pipe_spec);
// It's possible that another process creates the target path after we've
- // verified it's available but before we create it, in which case we
- // should try again.
+ // verified it's available but before we create it, in which case we should
+ // try again.
Status error;
do {
llvm::sys::fs::createUniqueFile(tmpdir_file_spec.GetPath(),
diff --git a/source/Host/posix/ProcessLauncherPosixFork.cpp b/source/Host/posix/ProcessLauncherPosixFork.cpp
index ac1d9011c2b7..46ce3e3d224f 100644
--- a/source/Host/posix/ProcessLauncherPosixFork.cpp
+++ b/source/Host/posix/ProcessLauncherPosixFork.cpp
@@ -38,17 +38,12 @@
using namespace lldb;
using namespace lldb_private;
-static void FixupEnvironment(Args &env) {
+static void FixupEnvironment(Environment &env) {
#ifdef __ANDROID__
// If there is no PATH variable specified inside the environment then set the
// path to /system/bin. It is required because the default path used by
// execve() is wrong on android.
- static const char *path = "PATH=";
- for (auto &entry : env.entries()) {
- if (entry.ref.startswith(path))
- return;
- }
- env.AppendArgument(llvm::StringRef("PATH=/system/bin"));
+ env.try_emplace("PATH", "/system/bin");
#endif
}
@@ -95,10 +90,6 @@ static void DupDescriptor(int error_fd, const FileSpec &file_spec, int fd,
static void LLVM_ATTRIBUTE_NORETURN ChildFunc(int error_fd,
const ProcessLaunchInfo &info) {
- // Do not inherit setgid powers.
- if (setgid(getgid()) != 0)
- ExitWithError(error_fd, "setgid");
-
if (info.GetFlags().Test(eLaunchFlagLaunchInSeparateProcessGroup)) {
if (setpgid(0, 0) != 0)
ExitWithError(error_fd, "setpgid");
@@ -132,23 +123,26 @@ static void LLVM_ATTRIBUTE_NORETURN ChildFunc(int error_fd,
ExitWithError(error_fd, "chdir");
DisableASLRIfRequested(error_fd, info);
- Args env = info.GetEnvironmentEntries();
+ Environment env = info.GetEnvironment();
FixupEnvironment(env);
- const char **envp = env.GetConstArgumentVector();
+ Environment::Envp envp = env.getEnvp();
- // Clear the signal mask to prevent the child from being affected by
- // any masking done by the parent.
+ // Clear the signal mask to prevent the child from being affected by any
+ // masking done by the parent.
sigset_t set;
if (sigemptyset(&set) != 0 ||
pthread_sigmask(SIG_SETMASK, &set, nullptr) != 0)
ExitWithError(error_fd, "pthread_sigmask");
if (info.GetFlags().Test(eLaunchFlagDebug)) {
+ // Do not inherit setgid powers.
+ if (setgid(getgid()) != 0)
+ ExitWithError(error_fd, "setgid");
+
// HACK:
// Close everything besides stdin, stdout, and stderr that has no file
// action to avoid leaking. Only do this when debugging, as elsewhere we
- // actually rely on
- // passing open descriptors to child processes.
+ // actually rely on passing open descriptors to child processes.
for (int fd = 3; fd < sysconf(_SC_OPEN_MAX); ++fd)
if (!info.GetFileActionForFD(fd) && fd != error_fd)
close(fd);
@@ -159,26 +153,20 @@ static void LLVM_ATTRIBUTE_NORETURN ChildFunc(int error_fd,
}
// Execute. We should never return...
- execve(argv[0], const_cast<char *const *>(argv),
- const_cast<char *const *>(envp));
+ execve(argv[0], const_cast<char *const *>(argv), envp);
#if defined(__linux__)
if (errno == ETXTBSY) {
- // On android M and earlier we can get this error because the adb deamon can
- // hold a write
- // handle on the executable even after it has finished uploading it. This
- // state lasts
- // only a short time and happens only when there are many concurrent adb
- // commands being
- // issued, such as when running the test suite. (The file remains open when
- // someone does
- // an "adb shell" command in the fork() child before it has had a chance to
- // exec.) Since
- // this state should clear up quickly, wait a while and then give it one
- // more go.
+ // On android M and earlier we can get this error because the adb deamon
+ // can hold a write handle on the executable even after it has finished
+ // uploading it. This state lasts only a short time and happens only when
+ // there are many concurrent adb commands being issued, such as when
+ // running the test suite. (The file remains open when someone does an "adb
+ // shell" command in the fork() child before it has had a chance to exec.)
+ // Since this state should clear up quickly, wait a while and then give it
+ // one more go.
usleep(50000);
- execve(argv[0], const_cast<char *const *>(argv),
- const_cast<char *const *>(envp));
+ execve(argv[0], const_cast<char *const *>(argv), envp);
}
#endif
diff --git a/source/Host/windows/ConnectionGenericFileWindows.cpp b/source/Host/windows/ConnectionGenericFileWindows.cpp
index 41bdb5f41fb6..e59e190dcb2d 100644
--- a/source/Host/windows/ConnectionGenericFileWindows.cpp
+++ b/source/Host/windows/ConnectionGenericFileWindows.cpp
@@ -21,12 +21,10 @@ using namespace lldb_private;
namespace {
// This is a simple helper class to package up the information needed to return
-// from a Read/Write
-// operation function. Since there is a lot of code to be run before exit
-// regardless of whether the
-// operation succeeded or failed, combined with many possible return paths, this
-// is the cleanest
-// way to represent it.
+// from a Read/Write operation function. Since there is a lot of code to be
+// run before exit regardless of whether the operation succeeded or failed,
+// combined with many possible return paths, this is the cleanest way to
+// represent it.
class ReturnInfo {
public:
void Set(size_t bytes, ConnectionStatus status, DWORD error_code) {
@@ -78,11 +76,9 @@ void ConnectionGenericFile::InitializeEventHandles() {
m_event_handles[kInterruptEvent] = CreateEvent(NULL, FALSE, FALSE, NULL);
// Note, we should use a manual reset event for the hEvent argument of the
- // OVERLAPPED. This
- // is because both WaitForMultipleObjects and GetOverlappedResult (if you set
- // the bWait
- // argument to TRUE) will wait for the event to be signalled. If we use an
- // auto-reset event,
+ // OVERLAPPED. This is because both WaitForMultipleObjects and
+ // GetOverlappedResult (if you set the bWait argument to TRUE) will wait for
+ // the event to be signalled. If we use an auto-reset event,
// WaitForMultipleObjects will reset the event, return successfully, and then
// GetOverlappedResult will block since the event is no longer signalled.
m_event_handles[kBytesAvailableEvent] =
@@ -147,8 +143,7 @@ lldb::ConnectionStatus ConnectionGenericFile::Disconnect(Status *error_ptr) {
return eConnectionStatusSuccess;
// Reset the handle so that after we unblock any pending reads, subsequent
- // calls to Read() will
- // see a disconnected state.
+ // calls to Read() will see a disconnected state.
HANDLE old_file = m_file;
m_file = INVALID_HANDLE_VALUE;
@@ -157,8 +152,7 @@ lldb::ConnectionStatus ConnectionGenericFile::Disconnect(Status *error_ptr) {
::CancelIoEx(old_file, &m_overlapped);
// Close the file handle if we owned it, but don't close the event handles.
- // We could always
- // reconnect with the same Connection instance.
+ // We could always reconnect with the same Connection instance.
if (m_owns_file)
::CloseHandle(old_file);
@@ -190,8 +184,7 @@ size_t ConnectionGenericFile::Read(void *dst, size_t dst_len,
if (result || ::GetLastError() == ERROR_IO_PENDING) {
if (!result) {
// The expected return path. The operation is pending. Wait for the
- // operation to complete
- // or be interrupted.
+ // operation to complete or be interrupted.
DWORD milliseconds =
timeout
? std::chrono::duration_cast<std::chrono::milliseconds>(*timeout)
@@ -219,11 +212,9 @@ size_t ConnectionGenericFile::Read(void *dst, size_t dst_len,
// The data is ready. Figure out how much was read and return;
if (!::GetOverlappedResult(m_file, &m_overlapped, &bytes_read, FALSE)) {
DWORD result_error = ::GetLastError();
- // ERROR_OPERATION_ABORTED occurs when someone calls Disconnect() during a
- // blocking read.
- // This triggers a call to CancelIoEx, which causes the operation to
- // complete and the
- // result to be ERROR_OPERATION_ABORTED.
+ // ERROR_OPERATION_ABORTED occurs when someone calls Disconnect() during
+ // a blocking read. This triggers a call to CancelIoEx, which causes the
+ // operation to complete and the result to be ERROR_OPERATION_ABORTED.
if (result_error == ERROR_HANDLE_EOF ||
result_error == ERROR_OPERATION_ABORTED ||
result_error == ERROR_BROKEN_PIPE)
@@ -250,9 +241,9 @@ finish:
if (error_ptr)
*error_ptr = return_info.GetError();
- // kBytesAvailableEvent is a manual reset event. Make sure it gets reset here
- // so that any
- // subsequent operations don't immediately see bytes available.
+ // kBytesAvailableEvent is a manual reset event. Make sure it gets reset
+ // here so that any subsequent operations don't immediately see bytes
+ // available.
ResetEvent(m_event_handles[kBytesAvailableEvent]);
IncrementFilePointer(return_info.GetBytes());
@@ -284,7 +275,8 @@ size_t ConnectionGenericFile::Write(const void *src, size_t src_len,
m_overlapped.hEvent = NULL;
- // Writes are not interruptible like reads are, so just block until it's done.
+ // Writes are not interruptible like reads are, so just block until it's
+ // done.
result = ::WriteFile(m_file, src, src_len, NULL, &m_overlapped);
if (!result && ::GetLastError() != ERROR_IO_PENDING) {
return_info.Set(0, eConnectionStatusError, ::GetLastError());
diff --git a/source/Host/windows/EditLineWin.cpp b/source/Host/windows/EditLineWin.cpp
index 133cd6225467..3bccc4e1a2c9 100644
--- a/source/Host/windows/EditLineWin.cpp
+++ b/source/Host/windows/EditLineWin.cpp
@@ -316,8 +316,8 @@ int el_get(EditLine *el, int code, ...) {
}
int el_source(EditLine *el, const char *file) {
- // init edit line by reading the contents of 'file'
- // nothing to do here on windows...
+ // init edit line by reading the contents of 'file' nothing to do here on
+ // windows...
return 0;
}
@@ -342,8 +342,8 @@ void history_end(History *) {
}
int history(History *, HistEvent *, int op, ...) {
- // perform operation 'op' on the history list with
- // optional arguments as needed by the operation.
+ // perform operation 'op' on the history list with optional arguments as
+ // needed by the operation.
return 0;
}
diff --git a/source/Host/windows/FileSystem.cpp b/source/Host/windows/FileSystem.cpp
index 02b7e550f86c..9309b89f2baf 100644
--- a/source/Host/windows/FileSystem.cpp
+++ b/source/Host/windows/FileSystem.cpp
@@ -75,7 +75,7 @@ Status FileSystem::Readlink(const FileSpec &src, FileSpec &dst) {
else if (!llvm::convertWideToUTF8(buf.data(), path))
error.SetErrorString(PATH_CONVERSION_ERROR);
else
- dst.SetFile(path, false);
+ dst.SetFile(path, false, FileSpec::Style::native);
::CloseHandle(h);
return error;
diff --git a/source/Host/windows/Host.cpp b/source/Host/windows/Host.cpp
index 4458ce25e607..cc6c454d36b1 100644
--- a/source/Host/windows/Host.cpp
+++ b/source/Host/windows/Host.cpp
@@ -35,8 +35,7 @@ using namespace lldb_private;
namespace {
bool GetTripleForProcess(const FileSpec &executable, llvm::Triple &triple) {
// Open the PE File as a binary file, and parse just enough information to
- // determine the
- // machine type.
+ // determine the machine type.
File imageBinary(executable.GetPath().c_str(), File::eOpenOptionRead,
lldb::eFilePermissionsUserRead);
imageBinary.SeekFromStart(0x3c);
@@ -63,8 +62,8 @@ bool GetTripleForProcess(const FileSpec &executable, llvm::Triple &triple) {
}
bool GetExecutableForProcess(const AutoHandle &handle, std::string &path) {
- // Get the process image path. MAX_PATH isn't long enough, paths can actually
- // be up to 32KB.
+ // Get the process image path. MAX_PATH isn't long enough, paths can
+ // actually be up to 32KB.
std::vector<wchar_t> buffer(PATH_MAX);
DWORD dwSize = buffer.size();
if (!::QueryFullProcessImageNameW(handle.get(), 0, &buffer[0], &dwSize))
@@ -75,10 +74,9 @@ bool GetExecutableForProcess(const AutoHandle &handle, std::string &path) {
void GetProcessExecutableAndTriple(const AutoHandle &handle,
ProcessInstanceInfo &process) {
// We may not have permissions to read the path from the process. So start
- // off by
- // setting the executable file to whatever Toolhelp32 gives us, and then try
- // to
- // enhance this with more detailed information, but fail gracefully.
+ // off by setting the executable file to whatever Toolhelp32 gives us, and
+ // then try to enhance this with more detailed information, but fail
+ // gracefully.
std::string executable;
llvm::Triple triple;
triple.setVendor(llvm::Triple::PC);
@@ -124,7 +122,7 @@ FileSpec Host::GetModuleFileSpecForHostAddress(const void *host_addr) {
std::string path;
if (!llvm::convertWideToUTF8(buffer.data(), path))
return module_filespec;
- module_filespec.SetFile(path, false);
+ module_filespec.SetFile(path, false, FileSpec::Style::native);
return module_filespec;
}
@@ -184,9 +182,8 @@ HostThread Host::StartMonitoringChildProcess(
Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
Status error;
if (launch_info.GetFlags().Test(eLaunchFlagShellExpandArguments)) {
- FileSpec expand_tool_spec;
- if (!HostInfo::GetLLDBPath(lldb::ePathTypeSupportExecutableDir,
- expand_tool_spec)) {
+ FileSpec expand_tool_spec = HostInfo::GetSupportExeDir();
+ if (!expand_tool_spec) {
error.SetErrorString("could not find support executable directory for "
"the lldb-argdumper tool");
return error;
@@ -209,7 +206,7 @@ Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
std::string output;
std::string command = expand_command.GetString();
RunShellCommand(command.c_str(), launch_info.GetWorkingDirectory(), &status,
- nullptr, &output, 10);
+ nullptr, &output, std::chrono::seconds(10));
if (status != 0) {
error.SetErrorStringWithFormat("lldb-argdumper exited with error %d",
@@ -258,13 +255,12 @@ Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
return error;
}
-size_t Host::GetEnvironment(StringList &env) {
+Environment Host::GetEnvironment() {
+ Environment env;
// The environment block on Windows is a contiguous buffer of NULL terminated
- // strings,
- // where the end of the environment block is indicated by two consecutive
- // NULLs.
+ // strings, where the end of the environment block is indicated by two
+ // consecutive NULLs.
LPWCH environment_block = ::GetEnvironmentStringsW();
- env.Clear();
while (*environment_block != L'\0') {
std::string current_var;
auto current_var_size = wcslen(environment_block) + 1;
@@ -273,9 +269,9 @@ size_t Host::GetEnvironment(StringList &env) {
continue;
}
if (current_var[0] != '=')
- env.AppendString(current_var);
+ env.insert(current_var);
environment_block += current_var_size;
}
- return env.GetSize();
+ return env;
}
diff --git a/source/Host/windows/HostInfoWindows.cpp b/source/Host/windows/HostInfoWindows.cpp
index 53a24ad1893e..bd3f74f2e2f3 100644
--- a/source/Host/windows/HostInfoWindows.cpp
+++ b/source/Host/windows/HostInfoWindows.cpp
@@ -42,39 +42,33 @@ size_t HostInfoWindows::GetPageSize() {
return systemInfo.dwPageSize;
}
-bool HostInfoWindows::GetOSVersion(uint32_t &major, uint32_t &minor,
- uint32_t &update) {
+llvm::VersionTuple HostInfoWindows::GetOSVersion() {
OSVERSIONINFOEX info;
ZeroMemory(&info, sizeof(OSVERSIONINFOEX));
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
#pragma warning(push)
#pragma warning(disable : 4996)
- // Starting with Microsoft SDK for Windows 8.1, this function is deprecated in
- // favor of the
- // new Windows Version Helper APIs. Since we don't specify a minimum SDK
- // version, it's easier
- // to simply disable the warning rather than try to support both APIs.
- if (GetVersionEx((LPOSVERSIONINFO)&info) == 0) {
- return false;
- }
+ // Starting with Microsoft SDK for Windows 8.1, this function is deprecated
+ // in favor of the new Windows Version Helper APIs. Since we don't specify a
+ // minimum SDK version, it's easier to simply disable the warning rather than
+ // try to support both APIs.
+ if (GetVersionEx((LPOSVERSIONINFO)&info) == 0)
+ return llvm::VersionTuple();
#pragma warning(pop)
- major = info.dwMajorVersion;
- minor = info.dwMinorVersion;
- update = info.wServicePackMajor;
-
- return true;
+ return llvm::VersionTuple(info.dwMajorVersion, info.dwMinorVersion,
+ info.wServicePackMajor);
}
bool HostInfoWindows::GetOSBuildString(std::string &s) {
s.clear();
- uint32_t major, minor, update;
- if (!GetOSVersion(major, minor, update))
+ llvm::VersionTuple version = GetOSVersion();
+ if (version.empty())
return false;
llvm::raw_string_ostream stream(s);
- stream << "Windows NT " << major << "." << minor << "." << update;
+ stream << "Windows NT " << version.getAsString();
return true;
}
@@ -98,27 +92,20 @@ FileSpec HostInfoWindows::GetProgramFileSpec() {
::GetModuleFileNameW(NULL, buffer.data(), buffer.size());
std::string path;
llvm::convertWideToUTF8(buffer.data(), path);
- m_program_filespec.SetFile(path, false);
+ m_program_filespec.SetFile(path, false, FileSpec::Style::native);
});
return m_program_filespec;
}
FileSpec HostInfoWindows::GetDefaultShell() {
+ // Try to retrieve ComSpec from the environment. On the rare occasion
+ // that it fails, try a well-known path for ComSpec instead.
+
std::string shell;
- GetEnvironmentVar("ComSpec", shell);
- return FileSpec(shell, false);
-}
+ if (GetEnvironmentVar("ComSpec", shell))
+ return FileSpec(shell, false);
-bool HostInfoWindows::ComputePythonDirectory(FileSpec &file_spec) {
- FileSpec lldb_file_spec;
- if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
- return false;
- llvm::SmallString<64> path(lldb_file_spec.GetDirectory().AsCString());
- llvm::sys::path::remove_filename(path);
- llvm::sys::path::append(path, "lib", "site-packages");
- std::replace(path.begin(), path.end(), '\\', '/');
- file_spec.GetDirectory().SetString(path.c_str());
- return true;
+ return FileSpec("C:\\Windows\\system32\\cmd.exe", false);
}
bool HostInfoWindows::GetEnvironmentVar(const std::string &var_name,
diff --git a/source/Host/windows/HostProcessWindows.cpp b/source/Host/windows/HostProcessWindows.cpp
index 49d42ce05422..ce75c14cdcf4 100644
--- a/source/Host/windows/HostProcessWindows.cpp
+++ b/source/Host/windows/HostProcessWindows.cpp
@@ -57,7 +57,7 @@ Status HostProcessWindows::GetMainModule(FileSpec &file_spec) const {
if (::GetProcessImageFileNameW(m_process, wpath.data(), wpath.size())) {
std::string path;
if (llvm::convertWideToUTF8(wpath.data(), path))
- file_spec.SetFile(path, false);
+ file_spec.SetFile(path, false, FileSpec::Style::native);
else
error.SetErrorString("Error converting path to UTF-8");
} else
@@ -88,8 +88,8 @@ HostThread HostProcessWindows::StartMonitoring(
info->callback = callback;
// Since the life of this HostProcessWindows instance and the life of the
- // process may be different, duplicate the handle so that
- // the monitor thread can have ownership over its own copy of the handle.
+ // process may be different, duplicate the handle so that the monitor thread
+ // can have ownership over its own copy of the handle.
HostThread result;
if (::DuplicateHandle(GetCurrentProcess(), m_process, GetCurrentProcess(),
&info->process_handle, 0, FALSE, DUPLICATE_SAME_ACCESS))
diff --git a/source/Host/windows/PipeWindows.cpp b/source/Host/windows/PipeWindows.cpp
index e8f4753d11e2..1951c9ca193a 100644
--- a/source/Host/windows/PipeWindows.cpp
+++ b/source/Host/windows/PipeWindows.cpp
@@ -40,11 +40,9 @@ PipeWindows::PipeWindows() {
PipeWindows::~PipeWindows() { Close(); }
Status PipeWindows::CreateNew(bool child_process_inherit) {
- // Even for anonymous pipes, we open a named pipe. This is because you cannot
- // get
- // overlapped i/o on Windows without using a named pipe. So we synthesize a
- // unique
- // name.
+ // Even for anonymous pipes, we open a named pipe. This is because you
+ // cannot get overlapped i/o on Windows without using a named pipe. So we
+ // synthesize a unique name.
uint32_t serial = g_pipe_serial.fetch_add(1);
std::string pipe_name;
llvm::raw_string_ostream pipe_name_stream(pipe_name);
@@ -65,8 +63,8 @@ Status PipeWindows::CreateNew(llvm::StringRef name,
std::string pipe_path = "\\\\.\\Pipe\\";
pipe_path.append(name);
- // Always open for overlapped i/o. We implement blocking manually in Read and
- // Write.
+ // Always open for overlapped i/o. We implement blocking manually in Read
+ // and Write.
DWORD read_mode = FILE_FLAG_OVERLAPPED;
m_read = ::CreateNamedPipeA(
pipe_path.c_str(), PIPE_ACCESS_INBOUND | read_mode,
@@ -250,12 +248,10 @@ Status PipeWindows::ReadWithTimeout(void *buf, size_t size,
DWORD wait_result = ::WaitForSingleObject(m_read_overlapped.hEvent, timeout);
if (wait_result != WAIT_OBJECT_0) {
// The operation probably failed. However, if it timed out, we need to
- // cancel the I/O.
- // Between the time we returned from WaitForSingleObject and the time we
- // call CancelIoEx,
- // the operation may complete. If that hapens, CancelIoEx will fail and
- // return ERROR_NOT_FOUND.
- // If that happens, the original operation should be considered to have been
+ // cancel the I/O. Between the time we returned from WaitForSingleObject
+ // and the time we call CancelIoEx, the operation may complete. If that
+ // hapens, CancelIoEx will fail and return ERROR_NOT_FOUND. If that
+ // happens, the original operation should be considered to have been
// successful.
bool failed = true;
DWORD failure_error = ::GetLastError();
@@ -268,9 +264,8 @@ Status PipeWindows::ReadWithTimeout(void *buf, size_t size,
return Status(failure_error, eErrorTypeWin32);
}
- // Now we call GetOverlappedResult setting bWait to false, since we've already
- // waited
- // as long as we're willing to.
+ // Now we call GetOverlappedResult setting bWait to false, since we've
+ // already waited as long as we're willing to.
if (!GetOverlappedResult(m_read, &m_read_overlapped, &sys_bytes_read, FALSE))
return Status(::GetLastError(), eErrorTypeWin32);
diff --git a/source/Host/windows/ProcessLauncherWindows.cpp b/source/Host/windows/ProcessLauncherWindows.cpp
index 56089742f093..553dd9d286da 100644
--- a/source/Host/windows/ProcessLauncherWindows.cpp
+++ b/source/Host/windows/ProcessLauncherWindows.cpp
@@ -21,14 +21,15 @@ using namespace lldb;
using namespace lldb_private;
namespace {
-void CreateEnvironmentBuffer(const Args &env, std::vector<char> &buffer) {
- if (env.GetArgumentCount() == 0)
+void CreateEnvironmentBuffer(const Environment &env,
+ std::vector<char> &buffer) {
+ if (env.size() == 0)
return;
// Environment buffer is a null terminated list of null terminated strings
- for (auto &entry : env.entries()) {
+ for (const auto &KV : env) {
std::wstring warg;
- if (llvm::ConvertUTF8toWide(entry.ref, warg)) {
+ if (llvm::ConvertUTF8toWide(Environment::compose(KV), warg)) {
buffer.insert(buffer.end(), (char *)warg.c_str(),
(char *)(warg.c_str() + warg.size() + 1));
}
@@ -75,9 +76,8 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
if (launch_info.GetFlags().Test(eLaunchFlagDebug))
flags |= DEBUG_ONLY_THIS_PROCESS;
- auto &env = const_cast<Args &>(launch_info.GetEnvironmentEntries());
LPVOID env_block = nullptr;
- ::CreateEnvironmentBuffer(env, environment);
+ ::CreateEnvironmentBuffer(launch_info.GetEnvironment(), environment);
if (!environment.empty())
env_block = environment.data();
@@ -96,6 +96,12 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
wexecutable.c_str(), &wcommandLine[0], NULL, NULL, TRUE, flags, env_block,
wworkingDirectory.size() == 0 ? NULL : wworkingDirectory.c_str(),
&startupinfo, &pi);
+
+ if (!result) {
+ // Call GetLastError before we make any other system calls.
+ error.SetError(::GetLastError(), eErrorTypeWin32);
+ }
+
if (result) {
// Do not call CloseHandle on pi.hProcess, since we want to pass that back
// through the HostProcess.
@@ -110,7 +116,8 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
::CloseHandle(stderr_handle);
if (!result)
- error.SetError(::GetLastError(), eErrorTypeWin32);
+ return HostProcess();
+
return HostProcess(pi.hProcess);
}
diff --git a/source/Initialization/CMakeLists.txt b/source/Initialization/CMakeLists.txt
index 7a100588e009..f8ee7c64cbb9 100644
--- a/source/Initialization/CMakeLists.txt
+++ b/source/Initialization/CMakeLists.txt
@@ -1,7 +1,3 @@
-if ( CMAKE_SYSTEM_NAME MATCHES "Darwin" )
- list(APPEND EXTRA_PLUGINS lldbPluginObjectFileMachO)
-endif()
-
if ( CMAKE_SYSTEM_NAME MATCHES "Linux|Android|FreeBSD|NetBSD" )
list(APPEND EXTRA_PLUGINS lldbPluginProcessPOSIX)
endif()
@@ -23,8 +19,6 @@ add_lldb_library(lldbInitialization
lldbPluginInstructionMIPS64
lldbPluginObjectContainerBSDArchive
lldbPluginObjectContainerMachOArchive
- lldbPluginObjectFileELF
- lldbPluginObjectFilePECOFF
lldbPluginProcessGDBRemote
${EXTRA_PLUGINS}
${LLDB_SYSTEM_LIBS}
diff --git a/source/Initialization/SystemInitializerCommon.cpp b/source/Initialization/SystemInitializerCommon.cpp
index a8fc46c119d8..006ab23595c7 100644
--- a/source/Initialization/SystemInitializerCommon.cpp
+++ b/source/Initialization/SystemInitializerCommon.cpp
@@ -14,18 +14,12 @@
#include "Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h"
#include "Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h"
#include "Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h"
-#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
-#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"
#include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Timer.h"
-#if defined(__APPLE__)
-#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
-#endif
-
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
#endif
@@ -35,7 +29,6 @@
#include "lldb/Host/windows/windows.h"
#endif
-#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/TargetSelect.h"
#include <string>
@@ -69,9 +62,6 @@ void SystemInitializerCommon::Initialize() {
}
#endif
-#if not defined(__APPLE__)
- llvm::EnablePrettyStackTrace();
-#endif
Log::Initialize();
HostInfo::Initialize();
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
@@ -81,8 +71,6 @@ void SystemInitializerCommon::Initialize() {
// Initialize plug-ins
ObjectContainerBSDArchive::Initialize();
- ObjectFileELF::Initialize();
- ObjectFilePECOFF::Initialize();
EmulateInstructionARM::Initialize();
EmulateInstructionMIPS::Initialize();
@@ -93,9 +81,6 @@ void SystemInitializerCommon::Initialize() {
//----------------------------------------------------------------------
ObjectContainerUniversalMachO::Initialize();
-#if defined(__APPLE__)
- ObjectFileMachO::Initialize();
-#endif
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
ProcessPOSIXLog::Initialize();
#endif
@@ -108,17 +93,12 @@ void SystemInitializerCommon::Terminate() {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
ObjectContainerBSDArchive::Terminate();
- ObjectFileELF::Terminate();
- ObjectFilePECOFF::Terminate();
EmulateInstructionARM::Terminate();
EmulateInstructionMIPS::Terminate();
EmulateInstructionMIPS64::Terminate();
ObjectContainerUniversalMachO::Terminate();
-#if defined(__APPLE__)
- ObjectFileMachO::Terminate();
-#endif
#if defined(_MSC_VER)
ProcessWindowsLog::Terminate();
diff --git a/source/Interpreter/Args.cpp b/source/Interpreter/Args.cpp
deleted file mode 100644
index 07e5191f898a..000000000000
--- a/source/Interpreter/Args.cpp
+++ /dev/null
@@ -1,1500 +0,0 @@
-//===-- Args.cpp ------------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// C Includes
-#include <cstdlib>
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "lldb/DataFormatters/FormatManager.h"
-#include "lldb/Host/OptionParser.h"
-#include "lldb/Interpreter/Args.h"
-#include "lldb/Interpreter/CommandInterpreter.h"
-#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Interpreter/Options.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/Stream.h"
-#include "lldb/Utility/StreamString.h"
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringSwitch.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-
-// A helper function for argument parsing.
-// Parses the initial part of the first argument using normal double quote
-// rules:
-// backslash escapes the double quote and itself. The parsed string is appended
-// to the second
-// argument. The function returns the unparsed portion of the string, starting
-// at the closing
-// quote.
-static llvm::StringRef ParseDoubleQuotes(llvm::StringRef quoted,
- std::string &result) {
- // Inside double quotes, '\' and '"' are special.
- static const char *k_escapable_characters = "\"\\";
- while (true) {
- // Skip over over regular characters and append them.
- size_t regular = quoted.find_first_of(k_escapable_characters);
- result += quoted.substr(0, regular);
- quoted = quoted.substr(regular);
-
- // If we have reached the end of string or the closing quote, we're done.
- if (quoted.empty() || quoted.front() == '"')
- break;
-
- // We have found a backslash.
- quoted = quoted.drop_front();
-
- if (quoted.empty()) {
- // A lone backslash at the end of string, let's just append it.
- result += '\\';
- break;
- }
-
- // If the character after the backslash is not a whitelisted escapable
- // character, we
- // leave the character sequence untouched.
- if (strchr(k_escapable_characters, quoted.front()) == nullptr)
- result += '\\';
-
- result += quoted.front();
- quoted = quoted.drop_front();
- }
-
- return quoted;
-}
-
-static size_t ArgvToArgc(const char **argv) {
- if (!argv)
- return 0;
- size_t count = 0;
- while (*argv++)
- ++count;
- return count;
-}
-
-// A helper function for SetCommandString. Parses a single argument from the
-// command string, processing quotes and backslashes in a shell-like manner.
-// The function returns a tuple consisting of the parsed argument, the quote
-// char used, and the unparsed portion of the string starting at the first
-// unqouted, unescaped whitespace character.
-static std::tuple<std::string, char, llvm::StringRef>
-ParseSingleArgument(llvm::StringRef command) {
- // Argument can be split into multiple discontiguous pieces, for example:
- // "Hello ""World"
- // this would result in a single argument "Hello World" (without the quotes)
- // since the quotes would be removed and there is not space between the
- // strings.
- std::string arg;
-
- // Since we can have multiple quotes that form a single command
- // in a command like: "Hello "world'!' (which will make a single
- // argument "Hello world!") we remember the first quote character
- // we encounter and use that for the quote character.
- char first_quote_char = '\0';
-
- bool arg_complete = false;
- do {
- // Skip over over regular characters and append them.
- size_t regular = command.find_first_of(" \t\"'`\\");
- arg += command.substr(0, regular);
- command = command.substr(regular);
-
- if (command.empty())
- break;
-
- char special = command.front();
- command = command.drop_front();
- switch (special) {
- case '\\':
- if (command.empty()) {
- arg += '\\';
- break;
- }
-
- // If the character after the backslash is not a whitelisted escapable
- // character, we
- // leave the character sequence untouched.
- if (strchr(" \t\\'\"`", command.front()) == nullptr)
- arg += '\\';
-
- arg += command.front();
- command = command.drop_front();
-
- break;
-
- case ' ':
- case '\t':
- // We are not inside any quotes, we just found a space after an
- // argument. We are done.
- arg_complete = true;
- break;
-
- case '"':
- case '\'':
- case '`':
- // We found the start of a quote scope.
- if (first_quote_char == '\0')
- first_quote_char = special;
-
- if (special == '"')
- command = ParseDoubleQuotes(command, arg);
- else {
- // For single quotes, we simply skip ahead to the matching quote
- // character
- // (or the end of the string).
- size_t quoted = command.find(special);
- arg += command.substr(0, quoted);
- command = command.substr(quoted);
- }
-
- // If we found a closing quote, skip it.
- if (!command.empty())
- command = command.drop_front();
-
- break;
- }
- } while (!arg_complete);
-
- return std::make_tuple(arg, first_quote_char, command);
-}
-
-Args::ArgEntry::ArgEntry(llvm::StringRef str, char quote) : quote(quote) {
- size_t size = str.size();
- ptr.reset(new char[size + 1]);
-
- ::memcpy(data(), str.data() ? str.data() : "", size);
- ptr[size] = 0;
- ref = llvm::StringRef(c_str(), size);
-}
-
-//----------------------------------------------------------------------
-// Args constructor
-//----------------------------------------------------------------------
-Args::Args(llvm::StringRef command) { SetCommandString(command); }
-
-Args::Args(const Args &rhs) { *this = rhs; }
-
-Args::Args(const StringList &list) : Args() {
- for(size_t i = 0; i < list.GetSize(); ++i)
- AppendArgument(list[i]);
-}
-
-Args &Args::operator=(const Args &rhs) {
- Clear();
-
- m_argv.clear();
- m_entries.clear();
- for (auto &entry : rhs.m_entries) {
- m_entries.emplace_back(entry.ref, entry.quote);
- m_argv.push_back(m_entries.back().data());
- }
- m_argv.push_back(nullptr);
- return *this;
-}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-Args::~Args() {}
-
-void Args::Dump(Stream &s, const char *label_name) const {
- if (!label_name)
- return;
-
- int i = 0;
- for (auto &entry : m_entries) {
- s.Indent();
- s.Format("{0}[{1}]=\"{2}\"\n", label_name, i++, entry.ref);
- }
- s.Format("{0}[{1}]=NULL\n", label_name, i);
- s.EOL();
-}
-
-bool Args::GetCommandString(std::string &command) const {
- command.clear();
-
- for (size_t i = 0; i < m_entries.size(); ++i) {
- if (i > 0)
- command += ' ';
- command += m_entries[i].ref;
- }
-
- return !m_entries.empty();
-}
-
-bool Args::GetQuotedCommandString(std::string &command) const {
- command.clear();
-
- for (size_t i = 0; i < m_entries.size(); ++i) {
- if (i > 0)
- command += ' ';
-
- if (m_entries[i].quote) {
- command += m_entries[i].quote;
- command += m_entries[i].ref;
- command += m_entries[i].quote;
- } else {
- command += m_entries[i].ref;
- }
- }
-
- return !m_entries.empty();
-}
-
-void Args::SetCommandString(llvm::StringRef command) {
- Clear();
- m_argv.clear();
-
- static const char *k_space_separators = " \t";
- command = command.ltrim(k_space_separators);
- std::string arg;
- char quote;
- while (!command.empty()) {
- std::tie(arg, quote, command) = ParseSingleArgument(command);
- m_entries.emplace_back(arg, quote);
- m_argv.push_back(m_entries.back().data());
- command = command.ltrim(k_space_separators);
- }
- m_argv.push_back(nullptr);
-}
-
-void Args::UpdateArgsAfterOptionParsing() {
- assert(!m_argv.empty());
- assert(m_argv.back() == nullptr);
-
- // Now m_argv might be out of date with m_entries, so we need to fix that.
- // This happens because getopt_long_only may permute the order of the
- // arguments in argv, so we need to re-order the quotes and the refs array
- // to match.
- for (size_t i = 0; i < m_argv.size() - 1; ++i) {
- const char *argv = m_argv[i];
- auto pos =
- std::find_if(m_entries.begin() + i, m_entries.end(),
- [argv](const ArgEntry &D) { return D.c_str() == argv; });
- assert(pos != m_entries.end());
- size_t distance = std::distance(m_entries.begin(), pos);
- if (i == distance)
- continue;
-
- assert(distance > i);
-
- std::swap(m_entries[i], m_entries[distance]);
- assert(m_entries[i].ref.data() == m_argv[i]);
- }
- m_entries.resize(m_argv.size() - 1);
-}
-
-size_t Args::GetArgumentCount() const { return m_entries.size(); }
-
-const char *Args::GetArgumentAtIndex(size_t idx) const {
- if (idx < m_argv.size())
- return m_argv[idx];
- return nullptr;
-}
-
-char Args::GetArgumentQuoteCharAtIndex(size_t idx) const {
- if (idx < m_entries.size())
- return m_entries[idx].quote;
- return '\0';
-}
-
-char **Args::GetArgumentVector() {
- assert(!m_argv.empty());
- // TODO: functions like execve and posix_spawnp exhibit undefined behavior
- // when argv or envp is null. So the code below is actually wrong. However,
- // other code in LLDB depends on it being null. The code has been acting this
- // way for some time, so it makes sense to leave it this way until someone
- // has the time to come along and fix it.
- return (m_argv.size() > 1) ? m_argv.data() : nullptr;
-}
-
-const char **Args::GetConstArgumentVector() const {
- assert(!m_argv.empty());
- return (m_argv.size() > 1) ? const_cast<const char **>(m_argv.data())
- : nullptr;
-}
-
-void Args::Shift() {
- // Don't pop the last NULL terminator from the argv array
- if (m_entries.empty())
- return;
- m_argv.erase(m_argv.begin());
- m_entries.erase(m_entries.begin());
-}
-
-void Args::Unshift(llvm::StringRef arg_str, char quote_char) {
- InsertArgumentAtIndex(0, arg_str, quote_char);
-}
-
-void Args::AppendArguments(const Args &rhs) {
- assert(m_argv.size() == m_entries.size() + 1);
- assert(m_argv.back() == nullptr);
- m_argv.pop_back();
- for (auto &entry : rhs.m_entries) {
- m_entries.emplace_back(entry.ref, entry.quote);
- m_argv.push_back(m_entries.back().data());
- }
- m_argv.push_back(nullptr);
-}
-
-void Args::AppendArguments(const char **argv) {
- size_t argc = ArgvToArgc(argv);
-
- assert(m_argv.size() == m_entries.size() + 1);
- assert(m_argv.back() == nullptr);
- m_argv.pop_back();
- for (auto arg : llvm::makeArrayRef(argv, argc)) {
- m_entries.emplace_back(arg, '\0');
- m_argv.push_back(m_entries.back().data());
- }
-
- m_argv.push_back(nullptr);
-}
-
-void Args::AppendArgument(llvm::StringRef arg_str, char quote_char) {
- InsertArgumentAtIndex(GetArgumentCount(), arg_str, quote_char);
-}
-
-void Args::InsertArgumentAtIndex(size_t idx, llvm::StringRef arg_str,
- char quote_char) {
- assert(m_argv.size() == m_entries.size() + 1);
- assert(m_argv.back() == nullptr);
-
- if (idx > m_entries.size())
- return;
- m_entries.emplace(m_entries.begin() + idx, arg_str, quote_char);
- m_argv.insert(m_argv.begin() + idx, m_entries[idx].data());
-}
-
-void Args::ReplaceArgumentAtIndex(size_t idx, llvm::StringRef arg_str,
- char quote_char) {
- assert(m_argv.size() == m_entries.size() + 1);
- assert(m_argv.back() == nullptr);
-
- if (idx >= m_entries.size())
- return;
-
- if (arg_str.size() > m_entries[idx].ref.size()) {
- m_entries[idx] = ArgEntry(arg_str, quote_char);
- m_argv[idx] = m_entries[idx].data();
- } else {
- const char *src_data = arg_str.data() ? arg_str.data() : "";
- ::memcpy(m_entries[idx].data(), src_data, arg_str.size());
- m_entries[idx].ptr[arg_str.size()] = 0;
- m_entries[idx].ref = m_entries[idx].ref.take_front(arg_str.size());
- }
-}
-
-void Args::DeleteArgumentAtIndex(size_t idx) {
- if (idx >= m_entries.size())
- return;
-
- m_argv.erase(m_argv.begin() + idx);
- m_entries.erase(m_entries.begin() + idx);
-}
-
-void Args::SetArguments(size_t argc, const char **argv) {
- Clear();
-
- auto args = llvm::makeArrayRef(argv, argc);
- m_entries.resize(argc);
- m_argv.resize(argc + 1);
- for (size_t i = 0; i < args.size(); ++i) {
- char quote =
- ((args[i][0] == '\'') || (args[i][0] == '"') || (args[i][0] == '`'))
- ? args[i][0]
- : '\0';
-
- m_entries[i] = ArgEntry(args[i], quote);
- m_argv[i] = m_entries[i].data();
- }
-}
-
-void Args::SetArguments(const char **argv) {
- SetArguments(ArgvToArgc(argv), argv);
-}
-
-Status Args::ParseOptions(Options &options, ExecutionContext *execution_context,
- PlatformSP platform_sp, bool require_validation) {
- StreamString sstr;
- Status error;
- Option *long_options = options.GetLongOptions();
- if (long_options == nullptr) {
- error.SetErrorStringWithFormat("invalid long options");
- return error;
- }
-
- for (int i = 0; long_options[i].definition != nullptr; ++i) {
- if (long_options[i].flag == nullptr) {
- if (isprint8(long_options[i].val)) {
- sstr << (char)long_options[i].val;
- switch (long_options[i].definition->option_has_arg) {
- default:
- case OptionParser::eNoArgument:
- break;
- case OptionParser::eRequiredArgument:
- sstr << ':';
- break;
- case OptionParser::eOptionalArgument:
- sstr << "::";
- break;
- }
- }
- }
- }
- std::unique_lock<std::mutex> lock;
- OptionParser::Prepare(lock);
- int val;
- while (1) {
- int long_options_index = -1;
- val = OptionParser::Parse(GetArgumentCount(), GetArgumentVector(),
- sstr.GetString(), long_options,
- &long_options_index);
- if (val == -1)
- break;
-
- // Did we get an error?
- if (val == '?') {
- error.SetErrorStringWithFormat("unknown or ambiguous option");
- break;
- }
- // The option auto-set itself
- if (val == 0)
- continue;
-
- ((Options *)&options)->OptionSeen(val);
-
- // Lookup the long option index
- if (long_options_index == -1) {
- for (int i = 0; long_options[i].definition || long_options[i].flag ||
- long_options[i].val;
- ++i) {
- if (long_options[i].val == val) {
- long_options_index = i;
- break;
- }
- }
- }
- // Call the callback with the option
- if (long_options_index >= 0 &&
- long_options[long_options_index].definition) {
- const OptionDefinition *def = long_options[long_options_index].definition;
-
- if (!platform_sp) {
- // User did not pass in an explicit platform. Try to grab
- // from the execution context.
- TargetSP target_sp =
- execution_context ? execution_context->GetTargetSP() : TargetSP();
- platform_sp = target_sp ? target_sp->GetPlatform() : PlatformSP();
- }
- OptionValidator *validator = def->validator;
-
- if (!platform_sp && require_validation) {
- // Caller requires validation but we cannot validate as we
- // don't have the mandatory platform against which to
- // validate.
- error.SetErrorString("cannot validate options: "
- "no platform available");
- return error;
- }
-
- bool validation_failed = false;
- if (platform_sp) {
- // Ensure we have an execution context, empty or not.
- ExecutionContext dummy_context;
- ExecutionContext *exe_ctx_p =
- execution_context ? execution_context : &dummy_context;
- if (validator && !validator->IsValid(*platform_sp, *exe_ctx_p)) {
- validation_failed = true;
- error.SetErrorStringWithFormat("Option \"%s\" invalid. %s",
- def->long_option,
- def->validator->LongConditionString());
- }
- }
-
- // As long as validation didn't fail, we set the option value.
- if (!validation_failed)
- error = options.SetOptionValue(
- long_options_index,
- (def->option_has_arg == OptionParser::eNoArgument)
- ? nullptr
- : OptionParser::GetOptionArgument(),
- execution_context);
- } else {
- error.SetErrorStringWithFormat("invalid option with value '%i'", val);
- }
- if (error.Fail())
- break;
- }
-
- // Update our ARGV now that get options has consumed all the options
- m_argv.erase(m_argv.begin(), m_argv.begin() + OptionParser::GetOptionIndex());
- UpdateArgsAfterOptionParsing();
- return error;
-}
-
-void Args::Clear() {
- m_entries.clear();
- m_argv.clear();
- m_argv.push_back(nullptr);
-}
-
-lldb::addr_t Args::StringToAddress(const ExecutionContext *exe_ctx,
- llvm::StringRef s, lldb::addr_t fail_value,
- Status *error_ptr) {
- bool error_set = false;
- if (s.empty()) {
- if (error_ptr)
- error_ptr->SetErrorStringWithFormat("invalid address expression \"%s\"",
- s.str().c_str());
- return fail_value;
- }
-
- llvm::StringRef sref = s;
-
- lldb::addr_t addr = LLDB_INVALID_ADDRESS;
- if (!s.getAsInteger(0, addr)) {
- if (error_ptr)
- error_ptr->Clear();
- return addr;
- }
-
- // Try base 16 with no prefix...
- if (!s.getAsInteger(16, addr)) {
- if (error_ptr)
- error_ptr->Clear();
- return addr;
- }
-
- Target *target = nullptr;
- if (!exe_ctx || !(target = exe_ctx->GetTargetPtr())) {
- if (error_ptr)
- error_ptr->SetErrorStringWithFormat("invalid address expression \"%s\"",
- s.str().c_str());
- return fail_value;
- }
-
- lldb::ValueObjectSP valobj_sp;
- EvaluateExpressionOptions options;
- options.SetCoerceToId(false);
- options.SetUnwindOnError(true);
- options.SetKeepInMemory(false);
- options.SetTryAllThreads(true);
-
- ExpressionResults expr_result =
- target->EvaluateExpression(s, exe_ctx->GetFramePtr(), valobj_sp, options);
-
- bool success = false;
- if (expr_result == eExpressionCompleted) {
- if (valobj_sp)
- valobj_sp = valobj_sp->GetQualifiedRepresentationIfAvailable(
- valobj_sp->GetDynamicValueType(), true);
- // Get the address to watch.
- if (valobj_sp)
- addr = valobj_sp->GetValueAsUnsigned(fail_value, &success);
- if (success) {
- if (error_ptr)
- error_ptr->Clear();
- return addr;
- } else {
- if (error_ptr) {
- error_set = true;
- error_ptr->SetErrorStringWithFormat(
- "address expression \"%s\" resulted in a value whose type "
- "can't be converted to an address: %s",
- s.str().c_str(), valobj_sp->GetTypeName().GetCString());
- }
- }
-
- } else {
- // Since the compiler can't handle things like "main + 12" we should
- // try to do this for now. The compiler doesn't like adding offsets
- // to function pointer types.
- static RegularExpression g_symbol_plus_offset_regex(
- "^(.*)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*$");
- RegularExpression::Match regex_match(3);
- if (g_symbol_plus_offset_regex.Execute(sref, &regex_match)) {
- uint64_t offset = 0;
- bool add = true;
- std::string name;
- std::string str;
- if (regex_match.GetMatchAtIndex(s, 1, name)) {
- if (regex_match.GetMatchAtIndex(s, 2, str)) {
- add = str[0] == '+';
-
- if (regex_match.GetMatchAtIndex(s, 3, str)) {
- if (!llvm::StringRef(str).getAsInteger(0, offset)) {
- Status error;
- addr = StringToAddress(exe_ctx, name.c_str(),
- LLDB_INVALID_ADDRESS, &error);
- if (addr != LLDB_INVALID_ADDRESS) {
- if (add)
- return addr + offset;
- else
- return addr - offset;
- }
- }
- }
- }
- }
- }
-
- if (error_ptr) {
- error_set = true;
- error_ptr->SetErrorStringWithFormat(
- "address expression \"%s\" evaluation failed", s.str().c_str());
- }
- }
-
- if (error_ptr) {
- if (!error_set)
- error_ptr->SetErrorStringWithFormat("invalid address expression \"%s\"",
- s.str().c_str());
- }
- return fail_value;
-}
-
-const char *Args::StripSpaces(std::string &s, bool leading, bool trailing,
- bool return_null_if_empty) {
- static const char *k_white_space = " \t\v";
- if (!s.empty()) {
- if (leading) {
- size_t pos = s.find_first_not_of(k_white_space);
- if (pos == std::string::npos)
- s.clear();
- else if (pos > 0)
- s.erase(0, pos);
- }
-
- if (trailing) {
- size_t rpos = s.find_last_not_of(k_white_space);
- if (rpos != std::string::npos && rpos + 1 < s.size())
- s.erase(rpos + 1);
- }
- }
- if (return_null_if_empty && s.empty())
- return nullptr;
- return s.c_str();
-}
-
-bool Args::StringToBoolean(llvm::StringRef ref, bool fail_value,
- bool *success_ptr) {
- if (success_ptr)
- *success_ptr = true;
- ref = ref.trim();
- if (ref.equals_lower("false") || ref.equals_lower("off") ||
- ref.equals_lower("no") || ref.equals_lower("0")) {
- return false;
- } else if (ref.equals_lower("true") || ref.equals_lower("on") ||
- ref.equals_lower("yes") || ref.equals_lower("1")) {
- return true;
- }
- if (success_ptr)
- *success_ptr = false;
- return fail_value;
-}
-
-char Args::StringToChar(llvm::StringRef s, char fail_value, bool *success_ptr) {
- if (success_ptr)
- *success_ptr = false;
- if (s.size() != 1)
- return fail_value;
-
- if (success_ptr)
- *success_ptr = true;
- return s[0];
-}
-
-bool Args::StringToVersion(llvm::StringRef string, uint32_t &major,
- uint32_t &minor, uint32_t &update) {
- major = UINT32_MAX;
- minor = UINT32_MAX;
- update = UINT32_MAX;
-
- if (string.empty())
- return false;
-
- llvm::StringRef major_str, minor_str, update_str;
-
- std::tie(major_str, minor_str) = string.split('.');
- std::tie(minor_str, update_str) = minor_str.split('.');
- if (major_str.getAsInteger(10, major))
- return false;
- if (!minor_str.empty() && minor_str.getAsInteger(10, minor))
- return false;
- if (!update_str.empty() && update_str.getAsInteger(10, update))
- return false;
-
- return true;
-}
-
-const char *Args::GetShellSafeArgument(const FileSpec &shell,
- const char *unsafe_arg,
- std::string &safe_arg) {
- struct ShellDescriptor {
- ConstString m_basename;
- const char *m_escapables;
- };
-
- static ShellDescriptor g_Shells[] = {{ConstString("bash"), " '\"<>()&"},
- {ConstString("tcsh"), " '\"<>()&$"},
- {ConstString("sh"), " '\"<>()&"}};
-
- // safe minimal set
- const char *escapables = " '\"";
-
- if (auto basename = shell.GetFilename()) {
- for (const auto &Shell : g_Shells) {
- if (Shell.m_basename == basename) {
- escapables = Shell.m_escapables;
- break;
- }
- }
- }
-
- safe_arg.assign(unsafe_arg);
- size_t prev_pos = 0;
- while (prev_pos < safe_arg.size()) {
- // Escape spaces and quotes
- size_t pos = safe_arg.find_first_of(escapables, prev_pos);
- if (pos != std::string::npos) {
- safe_arg.insert(pos, 1, '\\');
- prev_pos = pos + 2;
- } else
- break;
- }
- return safe_arg.c_str();
-}
-
-int64_t Args::StringToOptionEnum(llvm::StringRef s,
- OptionEnumValueElement *enum_values,
- int32_t fail_value, Status &error) {
- error.Clear();
- if (!enum_values) {
- error.SetErrorString("invalid enumeration argument");
- return fail_value;
- }
-
- if (s.empty()) {
- error.SetErrorString("empty enumeration string");
- return fail_value;
- }
-
- for (int i = 0; enum_values[i].string_value != nullptr; i++) {
- llvm::StringRef this_enum(enum_values[i].string_value);
- if (this_enum.startswith(s))
- return enum_values[i].value;
- }
-
- StreamString strm;
- strm.PutCString("invalid enumeration value, valid values are: ");
- for (int i = 0; enum_values[i].string_value != nullptr; i++) {
- strm.Printf("%s\"%s\"", i > 0 ? ", " : "", enum_values[i].string_value);
- }
- error.SetErrorString(strm.GetString());
- return fail_value;
-}
-
-lldb::ScriptLanguage
-Args::StringToScriptLanguage(llvm::StringRef s, lldb::ScriptLanguage fail_value,
- bool *success_ptr) {
- if (success_ptr)
- *success_ptr = true;
-
- if (s.equals_lower("python"))
- return eScriptLanguagePython;
- if (s.equals_lower("default"))
- return eScriptLanguageDefault;
- if (s.equals_lower("none"))
- return eScriptLanguageNone;
-
- if (success_ptr)
- *success_ptr = false;
- return fail_value;
-}
-
-Status Args::StringToFormat(const char *s, lldb::Format &format,
- size_t *byte_size_ptr) {
- format = eFormatInvalid;
- Status error;
-
- if (s && s[0]) {
- if (byte_size_ptr) {
- if (isdigit(s[0])) {
- char *format_char = nullptr;
- unsigned long byte_size = ::strtoul(s, &format_char, 0);
- if (byte_size != ULONG_MAX)
- *byte_size_ptr = byte_size;
- s = format_char;
- } else
- *byte_size_ptr = 0;
- }
-
- const bool partial_match_ok = true;
- if (!FormatManager::GetFormatFromCString(s, partial_match_ok, format)) {
- StreamString error_strm;
- error_strm.Printf(
- "Invalid format character or name '%s'. Valid values are:\n", s);
- for (Format f = eFormatDefault; f < kNumFormats; f = Format(f + 1)) {
- char format_char = FormatManager::GetFormatAsFormatChar(f);
- if (format_char)
- error_strm.Printf("'%c' or ", format_char);
-
- error_strm.Printf("\"%s\"", FormatManager::GetFormatAsCString(f));
- error_strm.EOL();
- }
-
- if (byte_size_ptr)
- error_strm.PutCString(
- "An optional byte size can precede the format character.\n");
- error.SetErrorString(error_strm.GetString());
- }
-
- if (error.Fail())
- return error;
- } else {
- error.SetErrorStringWithFormat("%s option string", s ? "empty" : "invalid");
- }
- return error;
-}
-
-lldb::Encoding Args::StringToEncoding(llvm::StringRef s,
- lldb::Encoding fail_value) {
- return llvm::StringSwitch<lldb::Encoding>(s)
- .Case("uint", eEncodingUint)
- .Case("sint", eEncodingSint)
- .Case("ieee754", eEncodingIEEE754)
- .Case("vector", eEncodingVector)
- .Default(fail_value);
-}
-
-uint32_t Args::StringToGenericRegister(llvm::StringRef s) {
- if (s.empty())
- return LLDB_INVALID_REGNUM;
- uint32_t result = llvm::StringSwitch<uint32_t>(s)
- .Case("pc", LLDB_REGNUM_GENERIC_PC)
- .Case("sp", LLDB_REGNUM_GENERIC_SP)
- .Case("fp", LLDB_REGNUM_GENERIC_FP)
- .Cases("ra", "lr", LLDB_REGNUM_GENERIC_RA)
- .Case("flags", LLDB_REGNUM_GENERIC_FLAGS)
- .Case("arg1", LLDB_REGNUM_GENERIC_ARG1)
- .Case("arg2", LLDB_REGNUM_GENERIC_ARG2)
- .Case("arg3", LLDB_REGNUM_GENERIC_ARG3)
- .Case("arg4", LLDB_REGNUM_GENERIC_ARG4)
- .Case("arg5", LLDB_REGNUM_GENERIC_ARG5)
- .Case("arg6", LLDB_REGNUM_GENERIC_ARG6)
- .Case("arg7", LLDB_REGNUM_GENERIC_ARG7)
- .Case("arg8", LLDB_REGNUM_GENERIC_ARG8)
- .Default(LLDB_INVALID_REGNUM);
- return result;
-}
-
-void Args::AddOrReplaceEnvironmentVariable(llvm::StringRef env_var_name,
- llvm::StringRef new_value) {
- if (env_var_name.empty())
- return;
-
- // Build the new entry.
- std::string var_string(env_var_name);
- if (!new_value.empty()) {
- var_string += "=";
- var_string += new_value;
- }
-
- size_t index = 0;
- if (ContainsEnvironmentVariable(env_var_name, &index)) {
- ReplaceArgumentAtIndex(index, var_string);
- return;
- }
-
- // We didn't find it. Append it instead.
- AppendArgument(var_string);
-}
-
-bool Args::ContainsEnvironmentVariable(llvm::StringRef env_var_name,
- size_t *argument_index) const {
- // Validate args.
- if (env_var_name.empty())
- return false;
-
- // Check each arg to see if it matches the env var name.
- for (auto arg : llvm::enumerate(m_entries)) {
- llvm::StringRef name, value;
- std::tie(name, value) = arg.value().ref.split('=');
- if (name != env_var_name)
- continue;
-
- if (argument_index)
- *argument_index = arg.index();
- return true;
- }
-
- // We didn't find a match.
- return false;
-}
-
-size_t Args::FindArgumentIndexForOption(Option *long_options,
- int long_options_index) const {
- char short_buffer[3];
- char long_buffer[255];
- ::snprintf(short_buffer, sizeof(short_buffer), "-%c",
- long_options[long_options_index].val);
- ::snprintf(long_buffer, sizeof(long_buffer), "--%s",
- long_options[long_options_index].definition->long_option);
-
- for (auto entry : llvm::enumerate(m_entries)) {
- if (entry.value().ref.startswith(short_buffer) ||
- entry.value().ref.startswith(long_buffer))
- return entry.index();
- }
-
- return size_t(-1);
-}
-
-bool Args::IsPositionalArgument(const char *arg) {
- if (arg == nullptr)
- return false;
-
- bool is_positional = true;
- const char *cptr = arg;
-
- if (cptr[0] == '%') {
- ++cptr;
- while (isdigit(cptr[0]))
- ++cptr;
- if (cptr[0] != '\0')
- is_positional = false;
- } else
- is_positional = false;
-
- return is_positional;
-}
-
-std::string Args::ParseAliasOptions(Options &options,
- CommandReturnObject &result,
- OptionArgVector *option_arg_vector,
- llvm::StringRef raw_input_string) {
- std::string result_string(raw_input_string);
- StreamString sstr;
- int i;
- Option *long_options = options.GetLongOptions();
-
- if (long_options == nullptr) {
- result.AppendError("invalid long options");
- result.SetStatus(eReturnStatusFailed);
- return result_string;
- }
-
- for (i = 0; long_options[i].definition != nullptr; ++i) {
- if (long_options[i].flag == nullptr) {
- sstr << (char)long_options[i].val;
- switch (long_options[i].definition->option_has_arg) {
- default:
- case OptionParser::eNoArgument:
- break;
- case OptionParser::eRequiredArgument:
- sstr << ":";
- break;
- case OptionParser::eOptionalArgument:
- sstr << "::";
- break;
- }
- }
- }
-
- std::unique_lock<std::mutex> lock;
- OptionParser::Prepare(lock);
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- int val;
- while (1) {
- int long_options_index = -1;
- val = OptionParser::Parse(GetArgumentCount(), GetArgumentVector(),
- sstr.GetString(), long_options,
- &long_options_index);
-
- if (val == -1)
- break;
-
- if (val == '?') {
- result.AppendError("unknown or ambiguous option");
- result.SetStatus(eReturnStatusFailed);
- break;
- }
-
- if (val == 0)
- continue;
-
- options.OptionSeen(val);
-
- // Look up the long option index
- if (long_options_index == -1) {
- for (int j = 0; long_options[j].definition || long_options[j].flag ||
- long_options[j].val;
- ++j) {
- if (long_options[j].val == val) {
- long_options_index = j;
- break;
- }
- }
- }
-
- // See if the option takes an argument, and see if one was supplied.
- if (long_options_index == -1) {
- result.AppendErrorWithFormat("Invalid option with value '%c'.\n", val);
- result.SetStatus(eReturnStatusFailed);
- return result_string;
- }
-
- StreamString option_str;
- option_str.Printf("-%c", val);
- const OptionDefinition *def = long_options[long_options_index].definition;
- int has_arg =
- (def == nullptr) ? OptionParser::eNoArgument : def->option_has_arg;
-
- const char *option_arg = nullptr;
- switch (has_arg) {
- case OptionParser::eRequiredArgument:
- if (OptionParser::GetOptionArgument() == nullptr) {
- result.AppendErrorWithFormat(
- "Option '%s' is missing argument specifier.\n",
- option_str.GetData());
- result.SetStatus(eReturnStatusFailed);
- return result_string;
- }
- LLVM_FALLTHROUGH;
- case OptionParser::eOptionalArgument:
- option_arg = OptionParser::GetOptionArgument();
- LLVM_FALLTHROUGH;
- case OptionParser::eNoArgument:
- break;
- default:
- result.AppendErrorWithFormat("error with options table; invalid value "
- "in has_arg field for option '%c'.\n",
- val);
- result.SetStatus(eReturnStatusFailed);
- return result_string;
- }
- if (!option_arg)
- option_arg = "<no-argument>";
- option_arg_vector->emplace_back(option_str.GetString(), has_arg,
- option_arg);
-
- // Find option in the argument list; also see if it was supposed to take
- // an argument and if one was supplied. Remove option (and argument, if
- // given) from the argument list. Also remove them from the
- // raw_input_string, if one was passed in.
- size_t idx = FindArgumentIndexForOption(long_options, long_options_index);
- if (idx == size_t(-1))
- continue;
-
- if (!result_string.empty()) {
- auto tmp_arg = m_entries[idx].ref;
- size_t pos = result_string.find(tmp_arg);
- if (pos != std::string::npos)
- result_string.erase(pos, tmp_arg.size());
- }
- ReplaceArgumentAtIndex(idx, llvm::StringRef());
- if ((long_options[long_options_index].definition->option_has_arg !=
- OptionParser::eNoArgument) &&
- (OptionParser::GetOptionArgument() != nullptr) &&
- (idx + 1 < GetArgumentCount()) &&
- (m_entries[idx + 1].ref == OptionParser::GetOptionArgument())) {
- if (result_string.size() > 0) {
- auto tmp_arg = m_entries[idx + 1].ref;
- size_t pos = result_string.find(tmp_arg);
- if (pos != std::string::npos)
- result_string.erase(pos, tmp_arg.size());
- }
- ReplaceArgumentAtIndex(idx + 1, llvm::StringRef());
- }
- }
- return result_string;
-}
-
-void Args::ParseArgsForCompletion(Options &options,
- OptionElementVector &option_element_vector,
- uint32_t cursor_index) {
- StreamString sstr;
- Option *long_options = options.GetLongOptions();
- option_element_vector.clear();
-
- if (long_options == nullptr) {
- return;
- }
-
- // Leading : tells getopt to return a : for a missing option argument AND
- // to suppress error messages.
-
- sstr << ":";
- for (int i = 0; long_options[i].definition != nullptr; ++i) {
- if (long_options[i].flag == nullptr) {
- sstr << (char)long_options[i].val;
- switch (long_options[i].definition->option_has_arg) {
- default:
- case OptionParser::eNoArgument:
- break;
- case OptionParser::eRequiredArgument:
- sstr << ":";
- break;
- case OptionParser::eOptionalArgument:
- sstr << "::";
- break;
- }
- }
- }
-
- std::unique_lock<std::mutex> lock;
- OptionParser::Prepare(lock);
- OptionParser::EnableError(false);
-
- int val;
- auto opt_defs = options.GetDefinitions();
-
- // Fooey... OptionParser::Parse permutes the GetArgumentVector to move the
- // options to the front. So we have to build another Arg and pass that to
- // OptionParser::Parse so it doesn't change the one we have.
-
- std::vector<char *> dummy_vec = m_argv;
-
- bool failed_once = false;
- uint32_t dash_dash_pos = -1;
-
- while (1) {
- bool missing_argument = false;
- int long_options_index = -1;
-
- val = OptionParser::Parse(dummy_vec.size() - 1, &dummy_vec[0],
- sstr.GetString(), long_options,
- &long_options_index);
-
- if (val == -1) {
- // When we're completing a "--" which is the last option on line,
- if (failed_once)
- break;
-
- failed_once = true;
-
- // If this is a bare "--" we mark it as such so we can complete it
- // successfully later.
- // Handling the "--" is a little tricky, since that may mean end of
- // options or arguments, or the
- // user might want to complete options by long name. I make this work by
- // checking whether the
- // cursor is in the "--" argument, and if so I assume we're completing the
- // long option, otherwise
- // I let it pass to OptionParser::Parse which will terminate the option
- // parsing.
- // Note, in either case we continue parsing the line so we can figure out
- // what other options
- // were passed. This will be useful when we come to restricting
- // completions based on what other
- // options we've seen on the line.
-
- if (static_cast<size_t>(OptionParser::GetOptionIndex()) <
- dummy_vec.size() - 1 &&
- (strcmp(dummy_vec[OptionParser::GetOptionIndex() - 1], "--") == 0)) {
- dash_dash_pos = OptionParser::GetOptionIndex() - 1;
- if (static_cast<size_t>(OptionParser::GetOptionIndex() - 1) ==
- cursor_index) {
- option_element_vector.push_back(
- OptionArgElement(OptionArgElement::eBareDoubleDash,
- OptionParser::GetOptionIndex() - 1,
- OptionArgElement::eBareDoubleDash));
- continue;
- } else
- break;
- } else
- break;
- } else if (val == '?') {
- option_element_vector.push_back(
- OptionArgElement(OptionArgElement::eUnrecognizedArg,
- OptionParser::GetOptionIndex() - 1,
- OptionArgElement::eUnrecognizedArg));
- continue;
- } else if (val == 0) {
- continue;
- } else if (val == ':') {
- // This is a missing argument.
- val = OptionParser::GetOptionErrorCause();
- missing_argument = true;
- }
-
- ((Options *)&options)->OptionSeen(val);
-
- // Look up the long option index
- if (long_options_index == -1) {
- for (int j = 0; long_options[j].definition || long_options[j].flag ||
- long_options[j].val;
- ++j) {
- if (long_options[j].val == val) {
- long_options_index = j;
- break;
- }
- }
- }
-
- // See if the option takes an argument, and see if one was supplied.
- if (long_options_index >= 0) {
- int opt_defs_index = -1;
- for (size_t i = 0; i < opt_defs.size(); i++) {
- if (opt_defs[i].short_option != val)
- continue;
- opt_defs_index = i;
- break;
- }
-
- const OptionDefinition *def = long_options[long_options_index].definition;
- int has_arg =
- (def == nullptr) ? OptionParser::eNoArgument : def->option_has_arg;
- switch (has_arg) {
- case OptionParser::eNoArgument:
- option_element_vector.push_back(OptionArgElement(
- opt_defs_index, OptionParser::GetOptionIndex() - 1, 0));
- break;
- case OptionParser::eRequiredArgument:
- if (OptionParser::GetOptionArgument() != nullptr) {
- int arg_index;
- if (missing_argument)
- arg_index = -1;
- else
- arg_index = OptionParser::GetOptionIndex() - 1;
-
- option_element_vector.push_back(OptionArgElement(
- opt_defs_index, OptionParser::GetOptionIndex() - 2, arg_index));
- } else {
- option_element_vector.push_back(OptionArgElement(
- opt_defs_index, OptionParser::GetOptionIndex() - 1, -1));
- }
- break;
- case OptionParser::eOptionalArgument:
- if (OptionParser::GetOptionArgument() != nullptr) {
- option_element_vector.push_back(OptionArgElement(
- opt_defs_index, OptionParser::GetOptionIndex() - 2,
- OptionParser::GetOptionIndex() - 1));
- } else {
- option_element_vector.push_back(OptionArgElement(
- opt_defs_index, OptionParser::GetOptionIndex() - 2,
- OptionParser::GetOptionIndex() - 1));
- }
- break;
- default:
- // The options table is messed up. Here we'll just continue
- option_element_vector.push_back(
- OptionArgElement(OptionArgElement::eUnrecognizedArg,
- OptionParser::GetOptionIndex() - 1,
- OptionArgElement::eUnrecognizedArg));
- break;
- }
- } else {
- option_element_vector.push_back(
- OptionArgElement(OptionArgElement::eUnrecognizedArg,
- OptionParser::GetOptionIndex() - 1,
- OptionArgElement::eUnrecognizedArg));
- }
- }
-
- // Finally we have to handle the case where the cursor index points at a
- // single "-". We want to mark that in
- // the option_element_vector, but only if it is not after the "--". But it
- // turns out that OptionParser::Parse just ignores
- // an isolated "-". So we have to look it up by hand here. We only care if
- // it is AT the cursor position.
- // Note, a single quoted dash is not the same as a single dash...
-
- const ArgEntry &cursor = m_entries[cursor_index];
- if ((static_cast<int32_t>(dash_dash_pos) == -1 ||
- cursor_index < dash_dash_pos) &&
- cursor.quote == '\0' && cursor.ref == "-") {
- option_element_vector.push_back(
- OptionArgElement(OptionArgElement::eBareDash, cursor_index,
- OptionArgElement::eBareDash));
- }
-}
-
-void Args::EncodeEscapeSequences(const char *src, std::string &dst) {
- dst.clear();
- if (src) {
- for (const char *p = src; *p != '\0'; ++p) {
- size_t non_special_chars = ::strcspn(p, "\\");
- if (non_special_chars > 0) {
- dst.append(p, non_special_chars);
- p += non_special_chars;
- if (*p == '\0')
- break;
- }
-
- if (*p == '\\') {
- ++p; // skip the slash
- switch (*p) {
- case 'a':
- dst.append(1, '\a');
- break;
- case 'b':
- dst.append(1, '\b');
- break;
- case 'f':
- dst.append(1, '\f');
- break;
- case 'n':
- dst.append(1, '\n');
- break;
- case 'r':
- dst.append(1, '\r');
- break;
- case 't':
- dst.append(1, '\t');
- break;
- case 'v':
- dst.append(1, '\v');
- break;
- case '\\':
- dst.append(1, '\\');
- break;
- case '\'':
- dst.append(1, '\'');
- break;
- case '"':
- dst.append(1, '"');
- break;
- case '0':
- // 1 to 3 octal chars
- {
- // Make a string that can hold onto the initial zero char,
- // up to 3 octal digits, and a terminating NULL.
- char oct_str[5] = {'\0', '\0', '\0', '\0', '\0'};
-
- int i;
- for (i = 0; (p[i] >= '0' && p[i] <= '7') && i < 4; ++i)
- oct_str[i] = p[i];
-
- // We don't want to consume the last octal character since
- // the main for loop will do this for us, so we advance p by
- // one less than i (even if i is zero)
- p += i - 1;
- unsigned long octal_value = ::strtoul(oct_str, nullptr, 8);
- if (octal_value <= UINT8_MAX) {
- dst.append(1, (char)octal_value);
- }
- }
- break;
-
- case 'x':
- // hex number in the format
- if (isxdigit(p[1])) {
- ++p; // Skip the 'x'
-
- // Make a string that can hold onto two hex chars plus a
- // NULL terminator
- char hex_str[3] = {*p, '\0', '\0'};
- if (isxdigit(p[1])) {
- ++p; // Skip the first of the two hex chars
- hex_str[1] = *p;
- }
-
- unsigned long hex_value = strtoul(hex_str, nullptr, 16);
- if (hex_value <= UINT8_MAX)
- dst.append(1, (char)hex_value);
- } else {
- dst.append(1, 'x');
- }
- break;
-
- default:
- // Just desensitize any other character by just printing what
- // came after the '\'
- dst.append(1, *p);
- break;
- }
- }
- }
- }
-}
-
-void Args::ExpandEscapedCharacters(const char *src, std::string &dst) {
- dst.clear();
- if (src) {
- for (const char *p = src; *p != '\0'; ++p) {
- if (isprint8(*p))
- dst.append(1, *p);
- else {
- switch (*p) {
- case '\a':
- dst.append("\\a");
- break;
- case '\b':
- dst.append("\\b");
- break;
- case '\f':
- dst.append("\\f");
- break;
- case '\n':
- dst.append("\\n");
- break;
- case '\r':
- dst.append("\\r");
- break;
- case '\t':
- dst.append("\\t");
- break;
- case '\v':
- dst.append("\\v");
- break;
- case '\'':
- dst.append("\\'");
- break;
- case '"':
- dst.append("\\\"");
- break;
- case '\\':
- dst.append("\\\\");
- break;
- default: {
- // Just encode as octal
- dst.append("\\0");
- char octal_str[32];
- snprintf(octal_str, sizeof(octal_str), "%o", *p);
- dst.append(octal_str);
- } break;
- }
- }
- }
- }
-}
-
-std::string Args::EscapeLLDBCommandArgument(const std::string &arg,
- char quote_char) {
- const char *chars_to_escape = nullptr;
- switch (quote_char) {
- case '\0':
- chars_to_escape = " \t\\'\"`";
- break;
- case '\'':
- chars_to_escape = "";
- break;
- case '"':
- chars_to_escape = "$\"`\\";
- break;
- default:
- assert(false && "Unhandled quote character");
- }
-
- std::string res;
- res.reserve(arg.size());
- for (char c : arg) {
- if (::strchr(chars_to_escape, c))
- res.push_back('\\');
- res.push_back(c);
- }
- return res;
-}
diff --git a/source/Interpreter/CMakeLists.txt b/source/Interpreter/CMakeLists.txt
index 0ab25f17144b..aaa335af39f9 100644
--- a/source/Interpreter/CMakeLists.txt
+++ b/source/Interpreter/CMakeLists.txt
@@ -1,5 +1,4 @@
add_lldb_library(lldbInterpreter
- Args.cpp
CommandAlias.cpp
CommandHistory.cpp
CommandInterpreter.cpp
@@ -8,6 +7,7 @@ add_lldb_library(lldbInterpreter
CommandObjectScript.cpp
CommandOptionValidators.cpp
CommandReturnObject.cpp
+ OptionArgParser.cpp
OptionGroupArchitecture.cpp
OptionGroupBoolean.cpp
OptionGroupFile.cpp
diff --git a/source/Interpreter/CommandAlias.cpp b/source/Interpreter/CommandAlias.cpp
index 2db7460611ca..a4b0a0c55c0e 100644
--- a/source/Interpreter/CommandAlias.cpp
+++ b/source/Interpreter/CommandAlias.cpp
@@ -40,12 +40,17 @@ static bool ProcessAliasOptionsArgs(lldb::CommandObjectSP &cmd_obj_sp,
ExecutionContext exe_ctx =
cmd_obj_sp->GetCommandInterpreter().GetExecutionContext();
options->NotifyOptionParsingStarting(&exe_ctx);
- args.Unshift(llvm::StringRef("dummy_arg"));
- options_string = args.ParseAliasOptions(*options, result, option_arg_vector,
- options_args);
- args.Shift();
- if (result.Succeeded())
- options->VerifyPartialOptions(result);
+
+ llvm::Expected<Args> args_or =
+ options->ParseAlias(args, option_arg_vector, options_string);
+ if (!args_or) {
+ result.AppendError(toString(args_or.takeError()));
+ result.AppendError("Unable to create requested alias.\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ args = std::move(*args_or);
+ options->VerifyPartialOptions(result);
if (!result.Succeeded() &&
result.GetStatus() != lldb::eReturnStatusStarted) {
result.AppendError("Unable to create requested alias.\n");
@@ -109,26 +114,17 @@ bool CommandAlias::WantsCompletion() {
return false;
}
-int CommandAlias::HandleCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- int match_start_point,
- int max_return_elements, bool &word_complete,
- StringList &matches) {
+int CommandAlias::HandleCompletion(CompletionRequest &request) {
if (IsValid())
- return m_underlying_command_sp->HandleCompletion(
- input, cursor_index, cursor_char_position, match_start_point,
- max_return_elements, word_complete, matches);
+ return m_underlying_command_sp->HandleCompletion(request);
return -1;
}
int CommandAlias::HandleArgumentCompletion(
- Args &input, int &cursor_index, int &cursor_char_position,
- OptionElementVector &opt_element_vector, int match_start_point,
- int max_return_elements, bool &word_complete, StringList &matches) {
+ CompletionRequest &request, OptionElementVector &opt_element_vector) {
if (IsValid())
return m_underlying_command_sp->HandleArgumentCompletion(
- input, cursor_index, cursor_char_position, opt_element_vector,
- match_start_point, max_return_elements, word_complete, matches);
+ request, opt_element_vector);
return -1;
}
@@ -191,8 +187,8 @@ bool CommandAlias::IsDashDashCommand() {
}
}
- // if this is a nested alias, it may be adding arguments on top of an
- // already dash-dash alias
+ // if this is a nested alias, it may be adding arguments on top of an already
+ // dash-dash alias
if ((m_is_dashdash_alias == eLazyBoolNo) && IsNestedAlias())
m_is_dashdash_alias =
(GetUnderlyingCommand()->IsDashDashCommand() ? eLazyBoolYes
@@ -223,8 +219,7 @@ std::pair<lldb::CommandObjectSP, OptionArgVectorSP> CommandAlias::Desugar() {
}
// allow CommandAlias objects to provide their own help, but fallback to the
-// info
-// for the underlying command if no customization has been provided
+// info for the underlying command if no customization has been provided
void CommandAlias::SetHelp(llvm::StringRef str) {
this->CommandObject::SetHelp(str);
m_did_set_help = true;
diff --git a/source/Interpreter/CommandInterpreter.cpp b/source/Interpreter/CommandInterpreter.cpp
index 8dc5637b6e4e..4c8b65441366 100644
--- a/source/Interpreter/CommandInterpreter.cpp
+++ b/source/Interpreter/CommandInterpreter.cpp
@@ -14,32 +14,31 @@
#include "CommandObjectScript.h"
#include "lldb/Interpreter/CommandObjectRegexCommand.h"
-#include "../Commands/CommandObjectApropos.h"
-#include "../Commands/CommandObjectArgs.h"
-#include "../Commands/CommandObjectBreakpoint.h"
-#include "../Commands/CommandObjectBugreport.h"
-#include "../Commands/CommandObjectCommands.h"
-#include "../Commands/CommandObjectDisassemble.h"
-#include "../Commands/CommandObjectExpression.h"
-#include "../Commands/CommandObjectFrame.h"
-#include "../Commands/CommandObjectGUI.h"
-#include "../Commands/CommandObjectHelp.h"
-#include "../Commands/CommandObjectLanguage.h"
-#include "../Commands/CommandObjectLog.h"
-#include "../Commands/CommandObjectMemory.h"
-#include "../Commands/CommandObjectPlatform.h"
-#include "../Commands/CommandObjectPlugin.h"
-#include "../Commands/CommandObjectProcess.h"
-#include "../Commands/CommandObjectQuit.h"
-#include "../Commands/CommandObjectRegister.h"
-#include "../Commands/CommandObjectSettings.h"
-#include "../Commands/CommandObjectSource.h"
-#include "../Commands/CommandObjectSyntax.h"
-#include "../Commands/CommandObjectTarget.h"
-#include "../Commands/CommandObjectThread.h"
-#include "../Commands/CommandObjectType.h"
-#include "../Commands/CommandObjectVersion.h"
-#include "../Commands/CommandObjectWatchpoint.h"
+#include "Commands/CommandObjectApropos.h"
+#include "Commands/CommandObjectBreakpoint.h"
+#include "Commands/CommandObjectBugreport.h"
+#include "Commands/CommandObjectCommands.h"
+#include "Commands/CommandObjectDisassemble.h"
+#include "Commands/CommandObjectExpression.h"
+#include "Commands/CommandObjectFrame.h"
+#include "Commands/CommandObjectGUI.h"
+#include "Commands/CommandObjectHelp.h"
+#include "Commands/CommandObjectLanguage.h"
+#include "Commands/CommandObjectLog.h"
+#include "Commands/CommandObjectMemory.h"
+#include "Commands/CommandObjectPlatform.h"
+#include "Commands/CommandObjectPlugin.h"
+#include "Commands/CommandObjectProcess.h"
+#include "Commands/CommandObjectQuit.h"
+#include "Commands/CommandObjectRegister.h"
+#include "Commands/CommandObjectSettings.h"
+#include "Commands/CommandObjectSource.h"
+#include "Commands/CommandObjectStats.h"
+#include "Commands/CommandObjectTarget.h"
+#include "Commands/CommandObjectThread.h"
+#include "Commands/CommandObjectType.h"
+#include "Commands/CommandObjectVersion.h"
+#include "Commands/CommandObjectWatchpoint.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/PluginManager.h"
@@ -55,20 +54,18 @@
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/Property.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/TargetList.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Utility/CleanUp.h"
-
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Path.h"
@@ -147,6 +144,26 @@ void CommandInterpreter::SetPromptOnQuit(bool b) {
m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
}
+void CommandInterpreter::AllowExitCodeOnQuit(bool allow) {
+ m_allow_exit_code = allow;
+ if (!allow)
+ m_quit_exit_code.reset();
+}
+
+bool CommandInterpreter::SetQuitExitCode(int exit_code) {
+ if (!m_allow_exit_code)
+ return false;
+ m_quit_exit_code = exit_code;
+ return true;
+}
+
+int CommandInterpreter::GetQuitExitCode(bool &exited) const {
+ exited = m_quit_exit_code.hasValue();
+ if (exited)
+ return *m_quit_exit_code;
+ return 0;
+}
+
void CommandInterpreter::ResolveCommand(const char *command_line,
CommandReturnObject &result) {
std::string command = command_line;
@@ -428,6 +445,7 @@ void CommandInterpreter::LoadCommandDictionary() {
CommandObjectSP(new CommandObjectMultiwordSettings(*this));
m_command_dict["source"] =
CommandObjectSP(new CommandObjectMultiwordSource(*this));
+ m_command_dict["statistics"] = CommandObjectSP(new CommandObjectStats(*this));
m_command_dict["target"] =
CommandObjectSP(new CommandObjectMultiwordTarget(*this));
m_command_dict["thread"] =
@@ -545,7 +563,7 @@ void CommandInterpreter::LoadCommandDictionary() {
// sure to increase the size of this buffer.
char buffer[1024];
int num_printed =
- snprintf(buffer, 1024, "%s %s", break_regexes[i][1], "-o");
+ snprintf(buffer, 1024, "%s %s", break_regexes[i][1], "-o 1");
lldbassert(num_printed < 1024);
UNUSED_IF_ASSERT_DISABLED(num_printed);
success =
@@ -683,10 +701,9 @@ void CommandInterpreter::LoadCommandDictionary() {
"bt [<digit> | all]", 2, 0, false));
if (bt_regex_cmd_ap.get()) {
// accept but don't document "bt -c <number>" -- before bt was a regex
- // command if you wanted to backtrace
- // three frames you would do "bt -c 3" but the intention is to have this
- // emulate the gdb "bt" command and
- // so now "bt 3" is the preferred form, in line with gdb.
+ // command if you wanted to backtrace three frames you would do "bt -c 3"
+ // but the intention is to have this emulate the gdb "bt" command and so
+ // now "bt 3" is the preferred form, in line with gdb.
if (bt_regex_cmd_ap->AddRegexCommand("^([[:digit:]]+)$",
"thread backtrace -c %1") &&
bt_regex_cmd_ap->AddRegexCommand("^-c ([[:digit:]]+)$",
@@ -827,9 +844,8 @@ CommandObjectSP CommandInterpreter::GetCommandSP(llvm::StringRef cmd_str,
unsigned int num_user_matches = 0;
// Look through the command dictionaries one by one, and if we get only one
- // match from any of
- // them in toto, then return that, otherwise return an empty CommandObjectSP
- // and the list of matches.
+ // match from any of them in toto, then return that, otherwise return an
+ // empty CommandObjectSP and the list of matches.
if (HasCommands()) {
num_cmd_matches =
@@ -955,10 +971,9 @@ CommandObjectSP CommandInterpreter::GetCommandSPExact(llvm::StringRef cmd_str,
CommandObjectSP cmd_obj_sp = GetCommandSP(llvm::StringRef(cmd_words.GetArgumentAtIndex(0)),
include_aliases, true, nullptr);
if (cmd_obj_sp.get() != nullptr) {
- // Loop through the rest of the words in the command (everything passed in
- // was supposed to be part of a
- // command name), and find the appropriate sub-command SP for each command
- // word....
+ // Loop through the rest of the words in the command (everything passed
+ // in was supposed to be part of a command name), and find the
+ // appropriate sub-command SP for each command word....
size_t end = cmd_words.GetArgumentCount();
for (size_t j = 1; j < end; ++j) {
if (cmd_obj_sp->IsMultiwordObject()) {
@@ -988,8 +1003,7 @@ CommandObject *CommandInterpreter::GetCommandObject(llvm::StringRef cmd_str,
GetCommandSP(cmd_str, false, true, matches).get();
// If we didn't find an exact match to the command string in the commands,
- // look in
- // the aliases.
+ // look in the aliases.
if (command_obj)
return command_obj;
@@ -1004,8 +1018,7 @@ CommandObject *CommandInterpreter::GetCommandObject(llvm::StringRef cmd_str,
command_obj = GetCommandSP(cmd_str, false, false, nullptr).get();
// Finally, if there wasn't an inexact match among the commands, look for an
- // inexact
- // match in both the commands and aliases.
+ // inexact match in both the commands and aliases.
if (command_obj) {
if (matches)
@@ -1168,8 +1181,8 @@ void CommandInterpreter::GetHelp(CommandReturnObject &result,
CommandObject *CommandInterpreter::GetCommandObjectForCommand(
llvm::StringRef &command_string) {
// This function finds the final, lowest-level, alias-resolved command object
- // whose 'Execute' function will
- // eventually be invoked by the given command line.
+ // whose 'Execute' function will eventually be invoked by the given command
+ // line.
CommandObject *cmd_obj = nullptr;
size_t start = command_string.find_first_not_of(k_white_space);
@@ -1240,8 +1253,8 @@ static size_t FindArgumentTerminator(const std::string &s) {
break;
if (pos > 0) {
if (isspace(s[pos - 1])) {
- // Check if the string ends "\s--" (where \s is a space character)
- // or if we have "\s--\s".
+ // Check if the string ends "\s--" (where \s is a space character) or
+ // if we have "\s--\s".
if ((pos + 2 >= s_len) || isspace(s[pos + 2])) {
return pos;
}
@@ -1376,20 +1389,19 @@ CommandObject *CommandInterpreter::BuildAliasResult(
}
Status CommandInterpreter::PreprocessCommand(std::string &command) {
- // The command preprocessor needs to do things to the command
- // line before any parsing of arguments or anything else is done.
- // The only current stuff that gets preprocessed is anything enclosed
- // in backtick ('`') characters is evaluated as an expression and
- // the result of the expression must be a scalar that can be substituted
- // into the command. An example would be:
+ // The command preprocessor needs to do things to the command line before any
+ // parsing of arguments or anything else is done. The only current stuff that
+ // gets preprocessed is anything enclosed in backtick ('`') characters is
+ // evaluated as an expression and the result of the expression must be a
+ // scalar that can be substituted into the command. An example would be:
// (lldb) memory read `$rsp + 20`
Status error; // Status for any expressions that might not evaluate
size_t start_backtick;
size_t pos = 0;
while ((start_backtick = command.find('`', pos)) != std::string::npos) {
if (start_backtick > 0 && command[start_backtick - 1] == '\\') {
- // The backtick was preceded by a '\' character, remove the slash
- // and don't treat the backtick as the start of an expression
+ // The backtick was preceded by a '\' character, remove the slash and
+ // don't treat the backtick as the start of an expression
command.erase(start_backtick - 1, 1);
// No need to add one to start_backtick since we just deleted a char
pos = start_backtick;
@@ -1408,8 +1420,8 @@ Status CommandInterpreter::PreprocessCommand(std::string &command) {
ExecutionContext exe_ctx(GetExecutionContext());
Target *target = exe_ctx.GetTargetPtr();
// Get a dummy target to allow for calculator mode while processing
- // backticks.
- // This also helps break the infinite loop caused when target is null.
+ // backticks. This also helps break the infinite loop caused when
+ // target is null.
if (!target)
target = m_debugger.GetDummyTarget();
if (target) {
@@ -1561,8 +1573,8 @@ bool CommandInterpreter::HandleCommand(const char *command_line,
const char *k_space_characters = "\t\n\v\f\r ";
size_t non_space = command_string.find_first_not_of(k_space_characters);
- // Check for empty line or comment line (lines whose first
- // non-space character is the comment character for this interpreter)
+ // Check for empty line or comment line (lines whose first non-space
+ // character is the comment character for this interpreter)
if (non_space == std::string::npos)
empty_command = true;
else if (command_string[non_space] == m_comment_char)
@@ -1635,8 +1647,8 @@ bool CommandInterpreter::HandleCommand(const char *command_line,
CommandObject *cmd_obj = ResolveCommandImpl(command_string, result);
// Although the user may have abbreviated the command, the command_string now
- // has the command expanded to the full name. For example, if the input
- // was "br s -n main", command_string is now "breakpoint set -n main".
+ // has the command expanded to the full name. For example, if the input was
+ // "br s -n main", command_string is now "breakpoint set -n main".
if (log) {
llvm::StringRef command_name = cmd_obj ? cmd_obj->GetCommandName() : "<not found>";
log->Printf("HandleCommand, cmd_obj : '%s'", command_name.str().c_str());
@@ -1650,8 +1662,8 @@ bool CommandInterpreter::HandleCommand(const char *command_line,
// Phase 2.
// Take care of things like setting up the history command & calling the
- // appropriate Execute method on the
- // CommandObject, with the appropriate arguments.
+ // appropriate Execute method on the CommandObject, with the appropriate
+ // arguments.
if (cmd_obj != nullptr) {
if (add_to_history) {
@@ -1681,36 +1693,6 @@ bool CommandInterpreter::HandleCommand(const char *command_line,
remainder.c_str());
cmd_obj->Execute(remainder.c_str(), result);
- } else {
- // We didn't find the first command object, so complete the first argument.
- Args command_args(command_string);
- StringList matches;
- int num_matches;
- int cursor_index = 0;
- int cursor_char_position = strlen(command_args.GetArgumentAtIndex(0));
- bool word_complete;
- num_matches = HandleCompletionMatches(command_args, cursor_index,
- cursor_char_position, 0, -1,
- word_complete, matches);
-
- if (num_matches > 0) {
- std::string error_msg;
- error_msg.assign("ambiguous command '");
- error_msg.append(command_args.GetArgumentAtIndex(0));
- error_msg.append("'.");
-
- error_msg.append(" Possible completions:");
- for (int i = 0; i < num_matches; i++) {
- error_msg.append("\n\t");
- error_msg.append(matches.GetStringAtIndex(i));
- }
- error_msg.append("\n");
- result.AppendRawError(error_msg.c_str());
- } else
- result.AppendErrorWithFormat("Unrecognized command '%s'.\n",
- command_args.GetArgumentAtIndex(0));
-
- result.SetStatus(eReturnStatusFailed);
}
if (log)
@@ -1720,60 +1702,55 @@ bool CommandInterpreter::HandleCommand(const char *command_line,
return result.Succeeded();
}
-int CommandInterpreter::HandleCompletionMatches(
- Args &parsed_line, int &cursor_index, int &cursor_char_position,
- int match_start_point, int max_return_elements, bool &word_complete,
- StringList &matches) {
+int CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) {
+ auto &matches = request.GetMatches();
int num_command_matches = 0;
bool look_for_subcommand = false;
// For any of the command completions a unique match will be a complete word.
- word_complete = true;
+ request.SetWordComplete(true);
- if (cursor_index == -1) {
+ if (request.GetCursorIndex() == -1) {
// We got nothing on the command line, so return the list of commands
bool include_aliases = true;
num_command_matches =
GetCommandNamesMatchingPartialString("", include_aliases, matches);
- } else if (cursor_index == 0) {
+ } else if (request.GetCursorIndex() == 0) {
// The cursor is in the first argument, so just do a lookup in the
// dictionary.
- CommandObject *cmd_obj =
- GetCommandObject(parsed_line.GetArgumentAtIndex(0), &matches);
+ CommandObject *cmd_obj = GetCommandObject(
+ request.GetParsedLine().GetArgumentAtIndex(0), &matches);
num_command_matches = matches.GetSize();
if (num_command_matches == 1 && cmd_obj && cmd_obj->IsMultiwordObject() &&
matches.GetStringAtIndex(0) != nullptr &&
- strcmp(parsed_line.GetArgumentAtIndex(0),
+ strcmp(request.GetParsedLine().GetArgumentAtIndex(0),
matches.GetStringAtIndex(0)) == 0) {
- if (parsed_line.GetArgumentCount() == 1) {
- word_complete = true;
+ if (request.GetParsedLine().GetArgumentCount() == 1) {
+ request.SetWordComplete(true);
} else {
look_for_subcommand = true;
num_command_matches = 0;
matches.DeleteStringAtIndex(0);
- parsed_line.AppendArgument(llvm::StringRef());
- cursor_index++;
- cursor_char_position = 0;
+ request.GetParsedLine().AppendArgument(llvm::StringRef());
+ request.SetCursorIndex(request.GetCursorIndex() + 1);
+ request.SetCursorCharPosition(0);
}
}
}
- if (cursor_index > 0 || look_for_subcommand) {
+ if (request.GetCursorIndex() > 0 || look_for_subcommand) {
// We are completing further on into a commands arguments, so find the
- // command and tell it
- // to complete the command.
- // First see if there is a matching initial command:
+ // command and tell it to complete the command. First see if there is a
+ // matching initial command:
CommandObject *command_object =
- GetCommandObject(parsed_line.GetArgumentAtIndex(0));
+ GetCommandObject(request.GetParsedLine().GetArgumentAtIndex(0));
if (command_object == nullptr) {
return 0;
} else {
- parsed_line.Shift();
- cursor_index--;
- num_command_matches = command_object->HandleCompletion(
- parsed_line, cursor_index, cursor_char_position, match_start_point,
- max_return_elements, word_complete, matches);
+ request.GetParsedLine().Shift();
+ request.SetCursorIndex(request.GetCursorIndex() - 1);
+ num_command_matches = command_object->HandleCompletion(request);
}
}
@@ -1783,106 +1760,59 @@ int CommandInterpreter::HandleCompletionMatches(
int CommandInterpreter::HandleCompletion(
const char *current_line, const char *cursor, const char *last_char,
int match_start_point, int max_return_elements, StringList &matches) {
- // We parse the argument up to the cursor, so the last argument in parsed_line
- // is
- // the one containing the cursor, and the cursor is after the last character.
- Args parsed_line(llvm::StringRef(current_line, last_char - current_line));
- Args partial_parsed_line(
- llvm::StringRef(current_line, cursor - current_line));
+ llvm::StringRef command_line(current_line, last_char - current_line);
+ CompletionRequest request(command_line, cursor - current_line,
+ match_start_point, max_return_elements, matches);
// Don't complete comments, and if the line we are completing is just the
- // history repeat character,
- // substitute the appropriate history line.
- const char *first_arg = parsed_line.GetArgumentAtIndex(0);
+ // history repeat character, substitute the appropriate history line.
+ const char *first_arg = request.GetParsedLine().GetArgumentAtIndex(0);
if (first_arg) {
if (first_arg[0] == m_comment_char)
return 0;
else if (first_arg[0] == CommandHistory::g_repeat_char) {
if (auto hist_str = m_command_history.FindString(first_arg)) {
- matches.Clear();
- matches.InsertStringAtIndex(0, *hist_str);
+ request.GetMatches().Clear();
+ request.GetMatches().InsertStringAtIndex(0, *hist_str);
return -2;
} else
return 0;
}
}
- int num_args = partial_parsed_line.GetArgumentCount();
- int cursor_index = partial_parsed_line.GetArgumentCount() - 1;
- int cursor_char_position;
-
- if (cursor_index == -1)
- cursor_char_position = 0;
- else
- cursor_char_position =
- strlen(partial_parsed_line.GetArgumentAtIndex(cursor_index));
-
- if (cursor > current_line && cursor[-1] == ' ') {
- // We are just after a space. If we are in an argument, then we will
- // continue
- // parsing, but if we are between arguments, then we have to complete
- // whatever the next
- // element would be.
- // We can distinguish the two cases because if we are in an argument (e.g.
- // because the space is
- // protected by a quote) then the space will also be in the parsed
- // argument...
-
- const char *current_elem =
- partial_parsed_line.GetArgumentAtIndex(cursor_index);
- if (cursor_char_position == 0 ||
- current_elem[cursor_char_position - 1] != ' ') {
- parsed_line.InsertArgumentAtIndex(cursor_index + 1, llvm::StringRef(),
- '\0');
- cursor_index++;
- cursor_char_position = 0;
- }
- }
-
- int num_command_matches;
-
- matches.Clear();
-
// Only max_return_elements == -1 is supported at present:
lldbassert(max_return_elements == -1);
- bool word_complete;
- num_command_matches = HandleCompletionMatches(
- parsed_line, cursor_index, cursor_char_position, match_start_point,
- max_return_elements, word_complete, matches);
+
+ int num_command_matches = HandleCompletionMatches(request);
if (num_command_matches <= 0)
return num_command_matches;
- if (num_args == 0) {
+ if (request.GetParsedLine().GetArgumentCount() == 0) {
// If we got an empty string, insert nothing.
matches.InsertStringAtIndex(0, "");
} else {
// Now figure out if there is a common substring, and if so put that in
- // element 0, otherwise
- // put an empty string in element 0.
- std::string command_partial_str;
- if (cursor_index >= 0)
- command_partial_str =
- parsed_line[cursor_index].ref.take_front(cursor_char_position);
+ // element 0, otherwise put an empty string in element 0.
+ std::string command_partial_str = request.GetCursorArgumentPrefix().str();
std::string common_prefix;
matches.LongestCommonPrefix(common_prefix);
const size_t partial_name_len = command_partial_str.size();
common_prefix.erase(0, partial_name_len);
- // If we matched a unique single command, add a space...
- // Only do this if the completer told us this was a complete word,
- // however...
- if (num_command_matches == 1 && word_complete) {
- char quote_char = parsed_line[cursor_index].quote;
+ // If we matched a unique single command, add a space... Only do this if
+ // the completer told us this was a complete word, however...
+ if (num_command_matches == 1 && request.GetWordComplete()) {
+ char quote_char = request.GetParsedLine()[request.GetCursorIndex()].quote;
common_prefix =
Args::EscapeLLDBCommandArgument(common_prefix, quote_char);
if (quote_char != '\0')
common_prefix.push_back(quote_char);
common_prefix.push_back(' ');
}
- matches.InsertStringAtIndex(0, common_prefix.c_str());
+ request.GetMatches().InsertStringAtIndex(0, common_prefix.c_str());
}
return num_command_matches;
}
@@ -1951,8 +1881,8 @@ void CommandInterpreter::BuildAliasCommandArgs(CommandObject *alias_cmd_obj,
if (option_arg_vector_sp.get()) {
if (wants_raw_input) {
// We have a command that both has command options and takes raw input.
- // Make *sure* it has a
- // " -- " in the right place in the raw_input_string.
+ // Make *sure* it has a " -- " in the right place in the
+ // raw_input_string.
size_t pos = raw_input_string.find(" -- ");
if (pos == std::string::npos) {
// None found; assume it goes at the beginning of the raw input string
@@ -2036,10 +1966,9 @@ void CommandInterpreter::BuildAliasCommandArgs(CommandObject *alias_cmd_obj,
} else {
result.SetStatus(eReturnStatusSuccessFinishNoResult);
// This alias was not created with any options; nothing further needs to be
- // done, unless it is a command that
- // wants raw input, in which case we need to clear the rest of the data from
- // cmd_args, since its in the raw
- // input string.
+ // done, unless it is a command that wants raw input, in which case we need
+ // to clear the rest of the data from cmd_args, since its in the raw input
+ // string.
if (wants_raw_input) {
cmd_args.Clear();
cmd_args.SetArguments(new_args.GetArgumentCount(),
@@ -2069,7 +1998,8 @@ int CommandInterpreter::GetOptionArgumentPosition(const char *in_string) {
while (isdigit(cptr[0]))
++cptr;
- // We've gotten to the end of the digits; are we at the end of the string?
+ // We've gotten to the end of the digits; are we at the end of the
+ // string?
if (cptr[0] == '\0')
position = atoi(start);
}
@@ -2117,16 +2047,16 @@ void CommandInterpreter::SourceInitFile(bool in_cwd,
return;
}
} else if (should_load == eLoadCWDlldbinitTrue) {
- init_file.SetFile("./.lldbinit", true);
+ init_file.SetFile("./.lldbinit", true, FileSpec::Style::native);
}
}
} else {
- // If we aren't looking in the current working directory we are looking
- // in the home directory. We will first see if there is an application
- // specific ".lldbinit" file whose name is "~/.lldbinit" followed by a
- // "-" and the name of the program. If this file doesn't exist, we fall
- // back to just the "~/.lldbinit" file. We also obey any requests to not
- // load the init files.
+ // If we aren't looking in the current working directory we are looking in
+ // the home directory. We will first see if there is an application
+ // specific ".lldbinit" file whose name is "~/.lldbinit" followed by a "-"
+ // and the name of the program. If this file doesn't exist, we fall back to
+ // just the "~/.lldbinit" file. We also obey any requests to not load the
+ // init files.
llvm::SmallString<64> home_dir_path;
llvm::sys::path::home_directory(home_dir_path);
FileSpec profilePath(home_dir_path.c_str(), false);
@@ -2141,19 +2071,19 @@ void CommandInterpreter::SourceInitFile(bool in_cwd,
char program_init_file_name[PATH_MAX];
::snprintf(program_init_file_name, sizeof(program_init_file_name),
"%s-%s", init_file_path.c_str(), program_name);
- init_file.SetFile(program_init_file_name, true);
+ init_file.SetFile(program_init_file_name, true,
+ FileSpec::Style::native);
if (!init_file.Exists())
init_file.Clear();
}
}
if (!init_file && !m_skip_lldbinit_files)
- init_file.SetFile(init_file_path, false);
+ init_file.SetFile(init_file_path, false, FileSpec::Style::native);
}
// If the file exists, tell HandleCommand to 'source' it; this will do the
- // actual broadcasting
- // of the commands back to any appropriate listener (see
+ // actual broadcasting of the commands back to any appropriate listener (see
// CommandObjectSource::Execute for more details).
if (init_file.Exists()) {
@@ -2199,15 +2129,14 @@ void CommandInterpreter::HandleCommands(const StringList &commands,
size_t num_lines = commands.GetSize();
// If we are going to continue past a "continue" then we need to run the
- // commands synchronously.
- // Make sure you reset this value anywhere you return from the function.
+ // commands synchronously. Make sure you reset this value anywhere you return
+ // from the function.
bool old_async_execution = m_debugger.GetAsyncExecution();
// If we've been given an execution context, set it at the start, but don't
- // keep resetting it or we will
- // cause series of commands that change the context, then do an operation that
- // relies on that context to fail.
+ // keep resetting it or we will cause series of commands that change the
+ // context, then do an operation that relies on that context to fail.
if (override_context != nullptr)
UpdateExecutionContext(override_context);
@@ -2232,9 +2161,8 @@ void CommandInterpreter::HandleCommands(const StringList &commands,
// HandleCommand() since we updated our context already.
// We might call into a regex or alias command, in which case the
- // add_to_history will get lost. This
- // m_command_source_depth dingus is the way we turn off adding to the
- // history in that case, so set it up here.
+ // add_to_history will get lost. This m_command_source_depth dingus is the
+ // way we turn off adding to the history in that case, so set it up here.
if (!options.GetAddToHistory())
m_command_source_depth++;
bool success =
@@ -2275,18 +2203,17 @@ void CommandInterpreter::HandleCommands(const StringList &commands,
if (result.GetImmediateErrorStream())
result.GetImmediateErrorStream()->Flush();
- // N.B. Can't depend on DidChangeProcessState, because the state coming into
- // the command execution
- // could be running (for instance in Breakpoint Commands.
- // So we check the return value to see if it is has running in it.
+ // N.B. Can't depend on DidChangeProcessState, because the state coming
+ // into the command execution could be running (for instance in Breakpoint
+ // Commands. So we check the return value to see if it is has running in
+ // it.
if ((tmp_result.GetStatus() == eReturnStatusSuccessContinuingNoResult) ||
(tmp_result.GetStatus() == eReturnStatusSuccessContinuingResult)) {
if (options.GetStopOnContinue()) {
// If we caused the target to proceed, and we're going to stop in that
- // case, set the
- // status in our real result before returning. This is an error if the
- // continue was not the
- // last command in the set of commands to be run.
+ // case, set the status in our real result before returning. This is
+ // an error if the continue was not the last command in the set of
+ // commands to be run.
if (idx != num_lines - 1)
result.AppendErrorWithFormat(
"Aborting reading of commands after command #%" PRIu64
@@ -2434,8 +2361,8 @@ void CommandInterpreter::HandleCommandsFromFile(
cmd_file_path.c_str());
}
- // Used for inheriting the right settings when "command source" might have
- // nested "command source" commands
+ // Used for inheriting the right settings when "command source" might
+ // have nested "command source" commands
lldb::StreamFileSP empty_stream_sp;
m_command_source_flags.push_back(flags);
IOHandlerSP io_handler_sp(new IOHandlerEditline(
@@ -2748,18 +2675,14 @@ void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler,
if (is_interactive == false) {
// When we are not interactive, don't execute blank lines. This will happen
// sourcing a commands file. We don't want blank lines to repeat the
- // previous
- // command and cause any errors to occur (like redefining an alias, get an
- // error
- // and stop parsing the commands file).
+ // previous command and cause any errors to occur (like redefining an
+ // alias, get an error and stop parsing the commands file).
if (line.empty())
return;
// When using a non-interactive file handle (like when sourcing commands
- // from a file)
- // we need to echo the command out so we don't just see the command output
- // and no
- // command...
+ // from a file) we need to echo the command out so we don't just see the
+ // command output and no command...
if (io_handler.GetFlags().Test(eHandleCommandFlagEchoCommand))
io_handler.GetOutputStreamFile()->Printf("%s%s\n", io_handler.GetPrompt(),
line.c_str());
@@ -2916,13 +2839,13 @@ bool CommandInterpreter::IsActive() {
lldb::IOHandlerSP
CommandInterpreter::GetIOHandler(bool force_create,
CommandInterpreterRunOptions *options) {
- // Always re-create the IOHandlerEditline in case the input
- // changed. The old instance might have had a non-interactive
- // input and now it does or vice versa.
+ // Always re-create the IOHandlerEditline in case the input changed. The old
+ // instance might have had a non-interactive input and now it does or vice
+ // versa.
if (force_create || !m_command_io_handler_sp) {
- // Always re-create the IOHandlerEditline in case the input
- // changed. The old instance might have had a non-interactive
- // input and now it does or vice versa.
+ // Always re-create the IOHandlerEditline in case the input changed. The
+ // old instance might have had a non-interactive input and now it does or
+ // vice versa.
uint32_t flags = 0;
if (options) {
@@ -2956,8 +2879,8 @@ CommandInterpreter::GetIOHandler(bool force_create,
void CommandInterpreter::RunCommandInterpreter(
bool auto_handle_events, bool spawn_thread,
CommandInterpreterRunOptions &options) {
- // Always re-create the command interpreter when we run it in case
- // any file handles have changed.
+ // Always re-create the command interpreter when we run it in case any file
+ // handles have changed.
bool force_create = true;
m_debugger.PushIOHandler(GetIOHandler(force_create, &options));
m_stopped_for_crash = false;
@@ -3009,8 +2932,6 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line,
actual_cmd_name_len = cmd_obj->GetCommandName().size();
}
} else {
- if (!cmd_obj)
- cmd_obj = GetCommandObject(next_word, &matches);
if (cmd_obj) {
llvm::StringRef cmd_name = cmd_obj->GetCommandName();
actual_cmd_name_len += cmd_name.size();
@@ -3025,8 +2946,8 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line,
CommandObject *sub_cmd_obj =
cmd_obj->GetSubcommandObject(next_word.c_str());
if (sub_cmd_obj) {
- // The subcommand's name includes the parent command's name,
- // so restart rather than append to the revised_command_line.
+ // The subcommand's name includes the parent command's name, so
+ // restart rather than append to the revised_command_line.
llvm::StringRef sub_cmd_name = sub_cmd_obj->GetCommandName();
actual_cmd_name_len = sub_cmd_name.size() + 1;
revised_command_line.Clear();
diff --git a/source/Interpreter/CommandObject.cpp b/source/Interpreter/CommandObject.cpp
index 98a6a941864e..07be9139f219 100644
--- a/source/Interpreter/CommandObject.cpp
+++ b/source/Interpreter/CommandObject.cpp
@@ -90,8 +90,8 @@ void CommandObject::SetHelpLong(llvm::StringRef str) { m_cmd_help_long = str; }
void CommandObject::SetSyntax(llvm::StringRef str) { m_cmd_syntax = str; }
Options *CommandObject::GetOptions() {
- // By default commands don't have options unless this virtual function
- // is overridden by base classes.
+ // By default commands don't have options unless this virtual function is
+ // overridden by base classes.
return nullptr;
}
@@ -104,20 +104,16 @@ bool CommandObject::ParseOptions(Args &args, CommandReturnObject &result) {
auto exe_ctx = GetCommandInterpreter().GetExecutionContext();
options->NotifyOptionParsingStarting(&exe_ctx);
- // ParseOptions calls getopt_long_only, which always skips the zero'th item
- // in the array and starts at position 1,
- // so we need to push a dummy value into position zero.
- args.Unshift(llvm::StringRef("dummy_string"));
const bool require_validation = true;
- error = args.ParseOptions(*options, &exe_ctx,
- GetCommandInterpreter().GetPlatform(true),
- require_validation);
+ llvm::Expected<Args> args_or = options->Parse(
+ args, &exe_ctx, GetCommandInterpreter().GetPlatform(true),
+ require_validation);
- // The "dummy_string" will have already been removed by ParseOptions,
- // so no need to remove it.
-
- if (error.Success())
+ if (args_or) {
+ args = std::move(*args_or);
error = options->NotifyOptionParsingFinished(&exe_ctx);
+ } else
+ error = args_or.takeError();
if (error.Success()) {
if (options->VerifyOptions(result))
@@ -142,10 +138,10 @@ bool CommandObject::ParseOptions(Args &args, CommandReturnObject &result) {
bool CommandObject::CheckRequirements(CommandReturnObject &result) {
#ifdef LLDB_CONFIGURATION_DEBUG
- // Nothing should be stored in m_exe_ctx between running commands as m_exe_ctx
- // has shared pointers to the target, process, thread and frame and we don't
- // want any CommandObject instances to keep any of these objects around
- // longer than for a single command. Every command should call
+ // Nothing should be stored in m_exe_ctx between running commands as
+ // m_exe_ctx has shared pointers to the target, process, thread and frame and
+ // we don't want any CommandObject instances to keep any of these objects
+ // around longer than for a single command. Every command should call
// CommandObject::Cleanup() after it has completed
assert(m_exe_ctx.GetTargetPtr() == NULL);
assert(m_exe_ctx.GetProcessPtr() == NULL);
@@ -153,9 +149,9 @@ bool CommandObject::CheckRequirements(CommandReturnObject &result) {
assert(m_exe_ctx.GetFramePtr() == NULL);
#endif
- // Lock down the interpreter's execution context prior to running the
- // command so we guarantee the selected target, process, thread and frame
- // can't go away during the execution
+ // Lock down the interpreter's execution context prior to running the command
+ // so we guarantee the selected target, process, thread and frame can't go
+ // away during the execution
m_exe_ctx = m_interpreter.GetExecutionContext();
const uint32_t flags = GetFlags().Get();
@@ -264,19 +260,14 @@ void CommandObject::Cleanup() {
m_api_locker.unlock();
}
-int CommandObject::HandleCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- int match_start_point,
- int max_return_elements,
- bool &word_complete, StringList &matches) {
+int CommandObject::HandleCompletion(CompletionRequest &request) {
// Default implementation of WantsCompletion() is !WantsRawCommandString().
- // Subclasses who want raw command string but desire, for example,
- // argument completion should override WantsCompletion() to return true,
- // instead.
+ // Subclasses who want raw command string but desire, for example, argument
+ // completion should override WantsCompletion() to return true, instead.
if (WantsRawCommandString() && !WantsCompletion()) {
// FIXME: Abstract telling the completion to insert the completion
// character.
- matches.Clear();
+ request.GetMatches().Clear();
return -1;
} else {
// Can we do anything generic with the options?
@@ -285,34 +276,17 @@ int CommandObject::HandleCompletion(Args &input, int &cursor_index,
OptionElementVector opt_element_vector;
if (cur_options != nullptr) {
- // Re-insert the dummy command name string which will have been
- // stripped off:
- input.Unshift(llvm::StringRef("dummy-string"));
- cursor_index++;
-
- // I stick an element on the end of the input, because if the last element
- // is option that requires an argument, getopt_long_only will freak out.
-
- input.AppendArgument(llvm::StringRef("<FAKE-VALUE>"));
-
- input.ParseArgsForCompletion(*cur_options, opt_element_vector,
- cursor_index);
+ opt_element_vector = cur_options->ParseForCompletion(
+ request.GetParsedLine(), request.GetCursorIndex());
- input.DeleteArgumentAtIndex(input.GetArgumentCount() - 1);
-
- bool handled_by_options;
- handled_by_options = cur_options->HandleOptionCompletion(
- input, opt_element_vector, cursor_index, cursor_char_position,
- match_start_point, max_return_elements, GetCommandInterpreter(),
- word_complete, matches);
+ bool handled_by_options = cur_options->HandleOptionCompletion(
+ request, opt_element_vector, GetCommandInterpreter());
if (handled_by_options)
- return matches.GetSize();
+ return request.GetMatches().GetSize();
}
// If we got here, the last word is not an option or an option argument.
- return HandleArgumentCompletion(
- input, cursor_index, cursor_char_position, opt_element_vector,
- match_start_point, max_return_elements, word_complete, matches);
+ return HandleArgumentCompletion(request, opt_element_vector);
}
}
@@ -351,6 +325,22 @@ bool CommandObject::HelpTextContainsWord(llvm::StringRef search_word,
return found_word;
}
+bool CommandObject::ParseOptionsAndNotify(Args &args,
+ CommandReturnObject &result,
+ OptionGroupOptions &group_options,
+ ExecutionContext &exe_ctx) {
+ if (!ParseOptions(args, result))
+ return false;
+
+ Status error(group_options.NotifyOptionParsingFinished(&exe_ctx));
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ return true;
+}
+
int CommandObject::GetNumArgumentEntries() { return m_arguments.size(); }
CommandObject::CommandArgumentEntry *
@@ -441,9 +431,10 @@ OptSetFiltered(uint32_t opt_set_mask,
return ret_val;
}
-// Default parameter value of opt_set_mask is LLDB_OPT_SET_ALL, which means take
-// all the argument data into account. On rare cases where some argument sticks
-// with certain option sets, this function returns the option set filtered args.
+// Default parameter value of opt_set_mask is LLDB_OPT_SET_ALL, which means
+// take all the argument data into account. On rare cases where some argument
+// sticks with certain option sets, this function returns the option set
+// filtered args.
void CommandObject::GetFormattedCommandArguments(Stream &str,
uint32_t opt_set_mask) {
int num_args = m_arguments.size();
@@ -483,8 +474,7 @@ void CommandObject::GetFormattedCommandArguments(Stream &str,
first_name, second_name);
break;
// Explicitly test for all the rest of the cases, so if new types get
- // added we will notice the
- // missing case statement(s).
+ // added we will notice the missing case statement(s).
case eArgRepeatPlain:
case eArgRepeatOptional:
case eArgRepeatPlus:
@@ -520,8 +510,7 @@ void CommandObject::GetFormattedCommandArguments(Stream &str,
str.Printf("<%s_1> .. <%s_n>", name_str.c_str(), name_str.c_str());
break;
// Explicitly test for all the rest of the cases, so if new types get
- // added we will notice the
- // missing case statement(s).
+ // added we will notice the missing case statement(s).
case eArgRepeatPairPlain:
case eArgRepeatPairOptional:
case eArgRepeatPairPlus:
@@ -529,8 +518,8 @@ void CommandObject::GetFormattedCommandArguments(Stream &str,
case eArgRepeatPairRange:
case eArgRepeatPairRangeOptional:
// These should not be hit, as they should pass the IsPairType test
- // above, and control should
- // have gone into the other branch of the if statement.
+ // above, and control should have gone into the other branch of the if
+ // statement.
break;
}
}
@@ -874,9 +863,8 @@ void CommandObject::GenerateHelpText(Stream &output_strm) {
if (!IsDashDashCommand() && options && options->NumCommandOptions() > 0) {
if (WantsRawCommandString() && !WantsCompletion()) {
// Emit the message about using ' -- ' between the end of the command
- // options and the raw input
- // conditionally, i.e., only if the command object does not want
- // completion.
+ // options and the raw input conditionally, i.e., only if the command
+ // object does not want completion.
interpreter.OutputFormattedHelpText(
output_strm, "", "",
"\nImportant Note: Because this command takes 'raw' input, if you "
@@ -916,8 +904,8 @@ void CommandObject::AddIDsArgumentData(CommandArgumentEntry &arg,
id_range_arg.arg_repetition = eArgRepeatOptional;
// The first (and only) argument for this command could be either an id or an
- // id_range.
- // Push both variants into the entry for the first argument for this command.
+ // id_range. Push both variants into the entry for the first argument for
+ // this command.
arg.push_back(id_arg);
arg.push_back(id_range_arg);
}
@@ -1021,7 +1009,8 @@ static llvm::StringRef arch_helper() {
static StreamString g_archs_help;
if (g_archs_help.Empty()) {
StringList archs;
- ArchSpec::AutoComplete(llvm::StringRef(), archs);
+
+ ArchSpec::ListSupportedArchNames(archs);
g_archs_help.Printf("These are the supported architecture names:\n");
archs.Join("\n", g_archs_help);
}
diff --git a/source/Interpreter/CommandObjectRegexCommand.cpp b/source/Interpreter/CommandObjectRegexCommand.cpp
index 79d3bb1b5bee..f975c0eea2ee 100644
--- a/source/Interpreter/CommandObjectRegexCommand.cpp
+++ b/source/Interpreter/CommandObjectRegexCommand.cpp
@@ -35,53 +35,47 @@ CommandObjectRegexCommand::CommandObjectRegexCommand(
//----------------------------------------------------------------------
CommandObjectRegexCommand::~CommandObjectRegexCommand() {}
-bool CommandObjectRegexCommand::DoExecute(const char *command,
+bool CommandObjectRegexCommand::DoExecute(llvm::StringRef command,
CommandReturnObject &result) {
- if (command) {
- EntryCollection::const_iterator pos, end = m_entries.end();
- for (pos = m_entries.begin(); pos != end; ++pos) {
- RegularExpression::Match regex_match(m_max_matches);
+ EntryCollection::const_iterator pos, end = m_entries.end();
+ for (pos = m_entries.begin(); pos != end; ++pos) {
+ RegularExpression::Match regex_match(m_max_matches);
- if (pos->regex.Execute(command, &regex_match)) {
- std::string new_command(pos->command);
- std::string match_str;
- char percent_var[8];
- size_t idx, percent_var_idx;
- for (uint32_t match_idx = 1; match_idx <= m_max_matches; ++match_idx) {
- if (regex_match.GetMatchAtIndex(command, match_idx, match_str)) {
- const int percent_var_len =
- ::snprintf(percent_var, sizeof(percent_var), "%%%u", match_idx);
- for (idx = 0; (percent_var_idx = new_command.find(
- percent_var, idx)) != std::string::npos;) {
- new_command.erase(percent_var_idx, percent_var_len);
- new_command.insert(percent_var_idx, match_str);
- idx += percent_var_idx + match_str.size();
- }
+ if (pos->regex.Execute(command, &regex_match)) {
+ std::string new_command(pos->command);
+ std::string match_str;
+ char percent_var[8];
+ size_t idx, percent_var_idx;
+ for (uint32_t match_idx = 1; match_idx <= m_max_matches; ++match_idx) {
+ if (regex_match.GetMatchAtIndex(command, match_idx, match_str)) {
+ const int percent_var_len =
+ ::snprintf(percent_var, sizeof(percent_var), "%%%u", match_idx);
+ for (idx = 0; (percent_var_idx = new_command.find(
+ percent_var, idx)) != std::string::npos;) {
+ new_command.erase(percent_var_idx, percent_var_len);
+ new_command.insert(percent_var_idx, match_str);
+ idx += percent_var_idx + match_str.size();
}
}
- // Interpret the new command and return this as the result!
- if (m_interpreter.GetExpandRegexAliases())
- result.GetOutputStream().Printf("%s\n", new_command.c_str());
- // Pass in true for "no context switching". The command that called us
- // should have set up the context
- // appropriately, we shouldn't have to redo that.
- return m_interpreter.HandleCommand(new_command.c_str(),
- eLazyBoolCalculate, result, nullptr,
- true, true);
}
+ // Interpret the new command and return this as the result!
+ if (m_interpreter.GetExpandRegexAliases())
+ result.GetOutputStream().Printf("%s\n", new_command.c_str());
+ // Pass in true for "no context switching". The command that called us
+ // should have set up the context appropriately, we shouldn't have to
+ // redo that.
+ return m_interpreter.HandleCommand(
+ new_command.c_str(), eLazyBoolCalculate, result, nullptr, true, true);
}
- result.SetStatus(eReturnStatusFailed);
- if (!GetSyntax().empty())
- result.AppendError(GetSyntax());
- else
- result.AppendErrorWithFormat("Command contents '%s' failed to match any "
- "regular expression in the '%s' regex "
- "command.\n",
- command, m_cmd_name.c_str());
- return false;
}
- result.AppendError("empty command passed to regular expression command");
result.SetStatus(eReturnStatusFailed);
+ if (!GetSyntax().empty())
+ result.AppendError(GetSyntax());
+ else
+ result.GetOutputStream() << "Command contents '" << command
+ << "' failed to match any "
+ "regular expression in the '"
+ << m_cmd_name << "' regex ";
return false;
}
@@ -99,23 +93,14 @@ bool CommandObjectRegexCommand::AddRegexCommand(const char *re_cstr,
return false;
}
-int CommandObjectRegexCommand::HandleCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) {
+int CommandObjectRegexCommand::HandleCompletion(CompletionRequest &request) {
if (m_completion_type_mask) {
- std::string completion_str(input.GetArgumentAtIndex(cursor_index),
- cursor_char_position);
CommandCompletions::InvokeCommonCompletionCallbacks(
- GetCommandInterpreter(), m_completion_type_mask, completion_str.c_str(),
- match_start_point, max_return_elements, nullptr, word_complete,
- matches);
- return matches.GetSize();
+ GetCommandInterpreter(), m_completion_type_mask, request, nullptr);
+ return request.GetMatches().GetSize();
} else {
- matches.Clear();
- word_complete = false;
+ request.GetMatches().Clear();
+ request.SetWordComplete(false);
}
return 0;
}
diff --git a/source/Interpreter/CommandObjectScript.cpp b/source/Interpreter/CommandObjectScript.cpp
index 0891298c5ac0..fa1516df60c9 100644
--- a/source/Interpreter/CommandObjectScript.cpp
+++ b/source/Interpreter/CommandObjectScript.cpp
@@ -18,10 +18,10 @@
#include "lldb/DataFormatters/DataVisualization.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "lldb/Utility/Args.h"
using namespace lldb;
using namespace lldb_private;
@@ -40,7 +40,7 @@ CommandObjectScript::CommandObjectScript(CommandInterpreter &interpreter,
CommandObjectScript::~CommandObjectScript() {}
-bool CommandObjectScript::DoExecute(const char *command,
+bool CommandObjectScript::DoExecute(llvm::StringRef command,
CommandReturnObject &result) {
#ifdef LLDB_DISABLE_PYTHON
// if we ever support languages other than Python this simple #ifdef won't
@@ -69,7 +69,7 @@ bool CommandObjectScript::DoExecute(const char *command,
// for formatting.. make sure we keep up to
// date with it
- if (command == nullptr || command[0] == '\0') {
+ if (command.empty()) {
script_interpreter->ExecuteInterpreterLoop();
result.SetStatus(eReturnStatusSuccessFinishNoResult);
return result.Succeeded();
diff --git a/source/Interpreter/CommandObjectScript.h b/source/Interpreter/CommandObjectScript.h
index 2c05ca9468d8..7a61b06e5b04 100644
--- a/source/Interpreter/CommandObjectScript.h
+++ b/source/Interpreter/CommandObjectScript.h
@@ -30,7 +30,7 @@ public:
~CommandObjectScript() override;
protected:
- bool DoExecute(const char *command, CommandReturnObject &result) override;
+ bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override;
};
} // namespace lldb_private
diff --git a/source/Interpreter/CommandReturnObject.cpp b/source/Interpreter/CommandReturnObject.cpp
index 75c02588066c..7c06e22c3909 100644
--- a/source/Interpreter/CommandReturnObject.cpp
+++ b/source/Interpreter/CommandReturnObject.cpp
@@ -25,8 +25,8 @@ static void DumpStringToStreamWithNewline(Stream &strm, const std::string &s,
if (s.empty()) {
add_newline = add_newline_if_empty;
} else {
- // We already checked for empty above, now make sure there is a newline
- // in the error, and if there isn't one, add one.
+ // We already checked for empty above, now make sure there is a newline in
+ // the error, and if there isn't one, add one.
strm.Write(s.c_str(), s.size());
const char last_char = *s.rbegin();
@@ -127,8 +127,8 @@ void CommandReturnObject::SetError(llvm::StringRef error_str) {
SetStatus(eReturnStatusFailed);
}
-// Similar to AppendError, but do not prepend 'Status: ' to message, and
-// don't append "\n" to the end of it.
+// Similar to AppendError, but do not prepend 'Status: ' to message, and don't
+// append "\n" to the end of it.
void CommandReturnObject::AppendRawError(llvm::StringRef in_string) {
if (in_string.empty())
diff --git a/source/Interpreter/OptionArgParser.cpp b/source/Interpreter/OptionArgParser.cpp
new file mode 100644
index 000000000000..3bd3af8fc50e
--- /dev/null
+++ b/source/Interpreter/OptionArgParser.cpp
@@ -0,0 +1,253 @@
+//===-- OptionArgParser.cpp -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Interpreter/OptionArgParser.h"
+#include "lldb/DataFormatters/FormatManager.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/Utility/StreamString.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+bool OptionArgParser::ToBoolean(llvm::StringRef ref, bool fail_value,
+ bool *success_ptr) {
+ if (success_ptr)
+ *success_ptr = true;
+ ref = ref.trim();
+ if (ref.equals_lower("false") || ref.equals_lower("off") ||
+ ref.equals_lower("no") || ref.equals_lower("0")) {
+ return false;
+ } else if (ref.equals_lower("true") || ref.equals_lower("on") ||
+ ref.equals_lower("yes") || ref.equals_lower("1")) {
+ return true;
+ }
+ if (success_ptr)
+ *success_ptr = false;
+ return fail_value;
+}
+
+char OptionArgParser::ToChar(llvm::StringRef s, char fail_value,
+ bool *success_ptr) {
+ if (success_ptr)
+ *success_ptr = false;
+ if (s.size() != 1)
+ return fail_value;
+
+ if (success_ptr)
+ *success_ptr = true;
+ return s[0];
+}
+
+int64_t OptionArgParser::ToOptionEnum(llvm::StringRef s,
+ OptionEnumValueElement *enum_values,
+ int32_t fail_value, Status &error) {
+ error.Clear();
+ if (!enum_values) {
+ error.SetErrorString("invalid enumeration argument");
+ return fail_value;
+ }
+
+ if (s.empty()) {
+ error.SetErrorString("empty enumeration string");
+ return fail_value;
+ }
+
+ for (int i = 0; enum_values[i].string_value != nullptr; i++) {
+ llvm::StringRef this_enum(enum_values[i].string_value);
+ if (this_enum.startswith(s))
+ return enum_values[i].value;
+ }
+
+ StreamString strm;
+ strm.PutCString("invalid enumeration value, valid values are: ");
+ for (int i = 0; enum_values[i].string_value != nullptr; i++) {
+ strm.Printf("%s\"%s\"", i > 0 ? ", " : "", enum_values[i].string_value);
+ }
+ error.SetErrorString(strm.GetString());
+ return fail_value;
+}
+
+Status OptionArgParser::ToFormat(const char *s, lldb::Format &format,
+ size_t *byte_size_ptr) {
+ format = eFormatInvalid;
+ Status error;
+
+ if (s && s[0]) {
+ if (byte_size_ptr) {
+ if (isdigit(s[0])) {
+ char *format_char = nullptr;
+ unsigned long byte_size = ::strtoul(s, &format_char, 0);
+ if (byte_size != ULONG_MAX)
+ *byte_size_ptr = byte_size;
+ s = format_char;
+ } else
+ *byte_size_ptr = 0;
+ }
+
+ const bool partial_match_ok = true;
+ if (!FormatManager::GetFormatFromCString(s, partial_match_ok, format)) {
+ StreamString error_strm;
+ error_strm.Printf(
+ "Invalid format character or name '%s'. Valid values are:\n", s);
+ for (Format f = eFormatDefault; f < kNumFormats; f = Format(f + 1)) {
+ char format_char = FormatManager::GetFormatAsFormatChar(f);
+ if (format_char)
+ error_strm.Printf("'%c' or ", format_char);
+
+ error_strm.Printf("\"%s\"", FormatManager::GetFormatAsCString(f));
+ error_strm.EOL();
+ }
+
+ if (byte_size_ptr)
+ error_strm.PutCString(
+ "An optional byte size can precede the format character.\n");
+ error.SetErrorString(error_strm.GetString());
+ }
+
+ if (error.Fail())
+ return error;
+ } else {
+ error.SetErrorStringWithFormat("%s option string", s ? "empty" : "invalid");
+ }
+ return error;
+}
+
+lldb::ScriptLanguage OptionArgParser::ToScriptLanguage(
+ llvm::StringRef s, lldb::ScriptLanguage fail_value, bool *success_ptr) {
+ if (success_ptr)
+ *success_ptr = true;
+
+ if (s.equals_lower("python"))
+ return eScriptLanguagePython;
+ if (s.equals_lower("default"))
+ return eScriptLanguageDefault;
+ if (s.equals_lower("none"))
+ return eScriptLanguageNone;
+
+ if (success_ptr)
+ *success_ptr = false;
+ return fail_value;
+}
+
+lldb::addr_t OptionArgParser::ToAddress(const ExecutionContext *exe_ctx,
+ llvm::StringRef s,
+ lldb::addr_t fail_value,
+ Status *error_ptr) {
+ bool error_set = false;
+ if (s.empty()) {
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormat("invalid address expression \"%s\"",
+ s.str().c_str());
+ return fail_value;
+ }
+
+ llvm::StringRef sref = s;
+
+ lldb::addr_t addr = LLDB_INVALID_ADDRESS;
+ if (!s.getAsInteger(0, addr)) {
+ if (error_ptr)
+ error_ptr->Clear();
+ return addr;
+ }
+
+ // Try base 16 with no prefix...
+ if (!s.getAsInteger(16, addr)) {
+ if (error_ptr)
+ error_ptr->Clear();
+ return addr;
+ }
+
+ Target *target = nullptr;
+ if (!exe_ctx || !(target = exe_ctx->GetTargetPtr())) {
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormat("invalid address expression \"%s\"",
+ s.str().c_str());
+ return fail_value;
+ }
+
+ lldb::ValueObjectSP valobj_sp;
+ EvaluateExpressionOptions options;
+ options.SetCoerceToId(false);
+ options.SetUnwindOnError(true);
+ options.SetKeepInMemory(false);
+ options.SetTryAllThreads(true);
+
+ ExpressionResults expr_result =
+ target->EvaluateExpression(s, exe_ctx->GetFramePtr(), valobj_sp, options);
+
+ bool success = false;
+ if (expr_result == eExpressionCompleted) {
+ if (valobj_sp)
+ valobj_sp = valobj_sp->GetQualifiedRepresentationIfAvailable(
+ valobj_sp->GetDynamicValueType(), true);
+ // Get the address to watch.
+ if (valobj_sp)
+ addr = valobj_sp->GetValueAsUnsigned(fail_value, &success);
+ if (success) {
+ if (error_ptr)
+ error_ptr->Clear();
+ return addr;
+ } else {
+ if (error_ptr) {
+ error_set = true;
+ error_ptr->SetErrorStringWithFormat(
+ "address expression \"%s\" resulted in a value whose type "
+ "can't be converted to an address: %s",
+ s.str().c_str(), valobj_sp->GetTypeName().GetCString());
+ }
+ }
+
+ } else {
+ // Since the compiler can't handle things like "main + 12" we should try to
+ // do this for now. The compiler doesn't like adding offsets to function
+ // pointer types.
+ static RegularExpression g_symbol_plus_offset_regex(
+ "^(.*)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*$");
+ RegularExpression::Match regex_match(3);
+ if (g_symbol_plus_offset_regex.Execute(sref, &regex_match)) {
+ uint64_t offset = 0;
+ bool add = true;
+ std::string name;
+ std::string str;
+ if (regex_match.GetMatchAtIndex(s, 1, name)) {
+ if (regex_match.GetMatchAtIndex(s, 2, str)) {
+ add = str[0] == '+';
+
+ if (regex_match.GetMatchAtIndex(s, 3, str)) {
+ if (!llvm::StringRef(str).getAsInteger(0, offset)) {
+ Status error;
+ addr = ToAddress(exe_ctx, name.c_str(), LLDB_INVALID_ADDRESS,
+ &error);
+ if (addr != LLDB_INVALID_ADDRESS) {
+ if (add)
+ return addr + offset;
+ else
+ return addr - offset;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (error_ptr) {
+ error_set = true;
+ error_ptr->SetErrorStringWithFormat(
+ "address expression \"%s\" evaluation failed", s.str().c_str());
+ }
+ }
+
+ if (error_ptr) {
+ if (!error_set)
+ error_ptr->SetErrorStringWithFormat("invalid address expression \"%s\"",
+ s.str().c_str());
+ }
+ return fail_value;
+}
diff --git a/source/Interpreter/OptionGroupBoolean.cpp b/source/Interpreter/OptionGroupBoolean.cpp
index 5fd4ce7aecfa..e3759f2e60a1 100644
--- a/source/Interpreter/OptionGroupBoolean.cpp
+++ b/source/Interpreter/OptionGroupBoolean.cpp
@@ -45,8 +45,8 @@ Status OptionGroupBoolean::SetOptionValue(uint32_t option_idx,
ExecutionContext *execution_context) {
Status error;
if (m_option_definition.option_has_arg == OptionParser::eNoArgument) {
- // Not argument, toggle the default value and mark the option as having been
- // set
+ // Not argument, toggle the default value and mark the option as having
+ // been set
m_value.SetCurrentValue(!m_value.GetDefaultValue());
m_value.SetOptionWasSet();
} else {
diff --git a/source/Interpreter/OptionGroupFormat.cpp b/source/Interpreter/OptionGroupFormat.cpp
index 75d8df950f18..b64c19324810 100644
--- a/source/Interpreter/OptionGroupFormat.cpp
+++ b/source/Interpreter/OptionGroupFormat.cpp
@@ -102,8 +102,8 @@ Status OptionGroupFormat::SetOptionValue(uint32_t option_idx,
// We the first character of the "gdb_format_str" is not the
// NULL terminator, we didn't consume the entire string and
- // something is wrong. Also, if none of the format, size or count
- // was specified correctly, then abort.
+ // something is wrong. Also, if none of the format, size or count was
+ // specified correctly, then abort.
if (!gdb_format_str.empty() ||
(format == eFormatInvalid && byte_size == 0 && count == 0)) {
// Nothing got set correctly
@@ -112,9 +112,8 @@ Status OptionGroupFormat::SetOptionValue(uint32_t option_idx,
return error;
}
- // At least one of the format, size or count was set correctly.
- // Anything that wasn't set correctly should be set to the
- // previous default
+ // At least one of the format, size or count was set correctly. Anything
+ // that wasn't set correctly should be set to the previous default
if (format == eFormatInvalid)
ParserGDBFormatLetter(execution_context, m_prev_gdb_format, format,
byte_size);
@@ -127,9 +126,8 @@ Status OptionGroupFormat::SetOptionValue(uint32_t option_idx,
ParserGDBFormatLetter(execution_context, m_prev_gdb_size, format,
byte_size);
} else {
- // Byte size is disabled, make sure it wasn't specified
- // but if this is an address, it's actually necessary to
- // specify one so don't error out
+ // Byte size is disabled, make sure it wasn't specified but if this is an
+ // address, it's actually necessary to specify one so don't error out
if (byte_size > 0 && format != lldb::eFormatAddressInfo) {
error.SetErrorString(
"this command doesn't support specifying a byte size");
@@ -235,10 +233,9 @@ bool OptionGroupFormat::ParserGDBFormatLetter(
case 'w':
case 'g':
{
- // Size isn't used for printing instructions, so if a size is specified, and
- // the previous format was
- // 'i', then we should reset it to the default ('x'). Otherwise we'll
- // continue to print as instructions,
+ // Size isn't used for printing instructions, so if a size is specified,
+ // and the previous format was 'i', then we should reset it to the
+ // default ('x'). Otherwise we'll continue to print as instructions,
// which isn't expected.
if (format_letter == 'b')
byte_size = 1;
diff --git a/source/Interpreter/OptionGroupPlatform.cpp b/source/Interpreter/OptionGroupPlatform.cpp
index 5747c6a8815d..47974276c8c0 100644
--- a/source/Interpreter/OptionGroupPlatform.cpp
+++ b/source/Interpreter/OptionGroupPlatform.cpp
@@ -44,10 +44,8 @@ PlatformSP OptionGroupPlatform::CreatePlatformWithOptions(
if (platform_sp) {
interpreter.GetDebugger().GetPlatformList().Append(platform_sp,
make_selected);
- if (m_os_version_major != UINT32_MAX) {
- platform_sp->SetOSVersion(m_os_version_major, m_os_version_minor,
- m_os_version_update);
- }
+ if (!m_os_version.empty())
+ platform_sp->SetOSVersion(m_os_version);
if (m_sdk_sysroot)
platform_sp->SetSDKRootDirectory(m_sdk_sysroot);
@@ -64,9 +62,7 @@ void OptionGroupPlatform::OptionParsingStarting(
m_platform_name.clear();
m_sdk_sysroot.Clear();
m_sdk_build.Clear();
- m_os_version_major = UINT32_MAX;
- m_os_version_minor = UINT32_MAX;
- m_os_version_update = UINT32_MAX;
+ m_os_version = llvm::VersionTuple();
}
static OptionDefinition g_option_table[] = {
@@ -108,10 +104,9 @@ OptionGroupPlatform::SetOptionValue(uint32_t option_idx,
break;
case 'v':
- if (!Args::StringToVersion(option_arg, m_os_version_major,
- m_os_version_minor, m_os_version_update))
- error.SetErrorStringWithFormat("invalid version string '%s'",
- option_arg.str().c_str());
+ if (m_os_version.tryParse(option_arg))
+ error.SetErrorStringWithFormatv("invalid version string '{0}'",
+ option_arg);
break;
case 'b':
@@ -143,17 +138,8 @@ bool OptionGroupPlatform::PlatformMatches(
if (m_sdk_sysroot && m_sdk_sysroot != platform_sp->GetSDKRootDirectory())
return false;
- if (m_os_version_major != UINT32_MAX) {
- uint32_t major, minor, update;
- if (platform_sp->GetOSVersion(major, minor, update)) {
- if (m_os_version_major != major)
- return false;
- if (m_os_version_minor != minor)
- return false;
- if (m_os_version_update != update)
- return false;
- }
- }
+ if (!m_os_version.empty() && m_os_version != platform_sp->GetOSVersion())
+ return false;
return true;
}
return false;
diff --git a/source/Interpreter/OptionGroupValueObjectDisplay.cpp b/source/Interpreter/OptionGroupValueObjectDisplay.cpp
index ce27d948c93c..54b45c29c70d 100644
--- a/source/Interpreter/OptionGroupValueObjectDisplay.cpp
+++ b/source/Interpreter/OptionGroupValueObjectDisplay.cpp
@@ -16,6 +16,7 @@
#include "lldb/DataFormatters/ValueObjectPrinter.h"
#include "lldb/Host/OptionParser.h"
#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Target/Target.h"
#include "llvm/ADT/ArrayRef.h"
@@ -85,8 +86,8 @@ Status OptionGroupValueObjectDisplay::SetOptionValue(
switch (short_option) {
case 'd': {
int32_t result;
- result =
- Args::StringToOptionEnum(option_arg, g_dynamic_value_types, 2, error);
+ result = OptionArgParser::ToOptionEnum(option_arg, g_dynamic_value_types, 2,
+ error);
if (error.Success())
use_dynamic = (lldb::DynamicValueType)result;
} break;
@@ -144,14 +145,14 @@ Status OptionGroupValueObjectDisplay::SetOptionValue(
break;
case 'S':
- use_synth = Args::StringToBoolean(option_arg, true, &success);
+ use_synth = OptionArgParser::ToBoolean(option_arg, true, &success);
if (!success)
error.SetErrorStringWithFormat("invalid synthetic-type '%s'",
option_arg.str().c_str());
break;
case 'V':
- run_validator = Args::StringToBoolean(option_arg, true, &success);
+ run_validator = OptionArgParser::ToBoolean(option_arg, true, &success);
if (!success)
error.SetErrorStringWithFormat("invalid validate '%s'",
option_arg.str().c_str());
diff --git a/source/Interpreter/OptionGroupVariable.cpp b/source/Interpreter/OptionGroupVariable.cpp
index 0793d3731446..7b7a62be8743 100644
--- a/source/Interpreter/OptionGroupVariable.cpp
+++ b/source/Interpreter/OptionGroupVariable.cpp
@@ -132,12 +132,12 @@ void OptionGroupVariable::OptionParsingStarting(
llvm::ArrayRef<OptionDefinition> OptionGroupVariable::GetDefinitions() {
auto result = llvm::makeArrayRef(g_variable_options);
- // Show the "--no-args", "--no-locals" and "--show-globals"
- // options if we are showing frame specific options
+ // Show the "--no-args", "--no-locals" and "--show-globals" options if we are
+ // showing frame specific options
if (include_frame_options)
return result;
- // Skip the "--no-args", "--no-locals" and "--show-globals"
- // options if we are not showing frame specific options (globals only)
+ // Skip the "--no-args", "--no-locals" and "--show-globals" options if we are
+ // not showing frame specific options (globals only)
return result.drop_front(NUM_FRAME_OPTS);
}
diff --git a/source/Interpreter/OptionGroupWatchpoint.cpp b/source/Interpreter/OptionGroupWatchpoint.cpp
index dd4b8c86c910..0431fefaa7f9 100644
--- a/source/Interpreter/OptionGroupWatchpoint.cpp
+++ b/source/Interpreter/OptionGroupWatchpoint.cpp
@@ -14,7 +14,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Host/OptionParser.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/lldb-enumerations.h"
using namespace lldb;
@@ -65,7 +65,7 @@ OptionGroupWatchpoint::SetOptionValue(uint32_t option_idx,
switch (short_option) {
case 'w': {
WatchType tmp_watch_type;
- tmp_watch_type = (WatchType)Args::StringToOptionEnum(
+ tmp_watch_type = (WatchType)OptionArgParser::ToOptionEnum(
option_arg, g_option_table[option_idx].enum_values, 0, error);
if (error.Success()) {
watch_type = tmp_watch_type;
@@ -74,7 +74,7 @@ OptionGroupWatchpoint::SetOptionValue(uint32_t option_idx,
break;
}
case 's':
- watch_size = (uint32_t)Args::StringToOptionEnum(
+ watch_size = (uint32_t)OptionArgParser::ToOptionEnum(
option_arg, g_option_table[option_idx].enum_values, 0, error);
break;
diff --git a/source/Interpreter/OptionValue.cpp b/source/Interpreter/OptionValue.cpp
index afcace2567ce..2d7c69eaa432 100644
--- a/source/Interpreter/OptionValue.cpp
+++ b/source/Interpreter/OptionValue.cpp
@@ -20,9 +20,8 @@ using namespace lldb;
using namespace lldb_private;
//-------------------------------------------------------------------------
-// Get this value as a uint64_t value if it is encoded as a boolean,
-// uint64_t or int64_t. Other types will cause "fail_value" to be
-// returned
+// Get this value as a uint64_t value if it is encoded as a boolean, uint64_t
+// or int64_t. Other types will cause "fail_value" to be returned
//-------------------------------------------------------------------------
uint64_t OptionValue::GetUInt64Value(uint64_t fail_value, bool *success_ptr) {
if (success_ptr)
@@ -508,8 +507,8 @@ const char *OptionValue::GetBuiltinTypeAsCString(Type t) {
lldb::OptionValueSP OptionValue::CreateValueFromCStringForTypeMask(
const char *value_cstr, uint32_t type_mask, Status &error) {
- // If only 1 bit is set in the type mask for a dictionary or array
- // then we know how to decode a value from a cstring
+ // If only 1 bit is set in the type mask for a dictionary or array then we
+ // know how to decode a value from a cstring
lldb::OptionValueSP value_sp;
switch (type_mask) {
case 1u << eTypeArch:
@@ -574,12 +573,10 @@ bool OptionValue::DumpQualifiedName(Stream &strm) const {
}
size_t OptionValue::AutoComplete(CommandInterpreter &interpreter,
- llvm::StringRef s, int match_start_point,
- int max_return_elements, bool &word_complete,
- StringList &matches) {
- word_complete = false;
- matches.Clear();
- return matches.GetSize();
+ CompletionRequest &request) {
+ request.SetWordComplete(false);
+ request.GetMatches().Clear();
+ return request.GetMatches().GetSize();
}
Status OptionValue::SetValueFromString(llvm::StringRef value,
diff --git a/source/Interpreter/OptionValueArch.cpp b/source/Interpreter/OptionValueArch.cpp
index 1d920a114723..3d08780ae6f6 100644
--- a/source/Interpreter/OptionValueArch.cpp
+++ b/source/Interpreter/OptionValueArch.cpp
@@ -15,9 +15,9 @@
// Project includes
#include "lldb/Core/State.h"
#include "lldb/DataFormatters/FormatManager.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Utility/Args.h"
using namespace lldb;
using namespace lldb_private;
@@ -74,13 +74,11 @@ lldb::OptionValueSP OptionValueArch::DeepCopy() const {
}
size_t OptionValueArch::AutoComplete(CommandInterpreter &interpreter,
- llvm::StringRef s, int match_start_point,
- int max_return_elements,
- bool &word_complete, StringList &matches) {
- word_complete = false;
- matches.Clear();
+ CompletionRequest &request) {
+ request.SetWordComplete(false);
+ request.GetMatches().Clear();
CommandCompletions::InvokeCommonCompletionCallbacks(
- interpreter, CommandCompletions::eArchitectureCompletion, s,
- match_start_point, max_return_elements, nullptr, word_complete, matches);
- return matches.GetSize();
+ interpreter, CommandCompletions::eArchitectureCompletion, request,
+ nullptr);
+ return request.GetMatches().GetSize();
}
diff --git a/source/Interpreter/OptionValueArgs.cpp b/source/Interpreter/OptionValueArgs.cpp
index 8edec77f9d2d..26e438548ea3 100644
--- a/source/Interpreter/OptionValueArgs.cpp
+++ b/source/Interpreter/OptionValueArgs.cpp
@@ -13,7 +13,7 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Utility/Args.h"
using namespace lldb;
using namespace lldb_private;
diff --git a/source/Interpreter/OptionValueArray.cpp b/source/Interpreter/OptionValueArray.cpp
index 8b62070352a6..d3fd1cb5db48 100644
--- a/source/Interpreter/OptionValueArray.cpp
+++ b/source/Interpreter/OptionValueArray.cpp
@@ -14,7 +14,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Host/StringConvert.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/Stream.h"
using namespace lldb;
diff --git a/source/Interpreter/OptionValueBoolean.cpp b/source/Interpreter/OptionValueBoolean.cpp
index 2cb84cd6abb3..8a340792d78f 100644
--- a/source/Interpreter/OptionValueBoolean.cpp
+++ b/source/Interpreter/OptionValueBoolean.cpp
@@ -14,7 +14,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Host/PosixApi.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StringList.h"
#include "llvm/ADT/STLExtras.h"
@@ -47,7 +47,7 @@ Status OptionValueBoolean::SetValueFromString(llvm::StringRef value_str,
case eVarSetOperationReplace:
case eVarSetOperationAssign: {
bool success = false;
- bool value = Args::StringToBoolean(value_str, false, &success);
+ bool value = OptionArgParser::ToBoolean(value_str, false, &success);
if (success) {
m_value_was_set = true;
m_current_value = value;
@@ -76,23 +76,22 @@ lldb::OptionValueSP OptionValueBoolean::DeepCopy() const {
return OptionValueSP(new OptionValueBoolean(*this));
}
-size_t OptionValueBoolean::AutoComplete(
- CommandInterpreter &interpreter, llvm::StringRef s, int match_start_point,
- int max_return_elements, bool &word_complete, StringList &matches) {
- word_complete = false;
- matches.Clear();
+size_t OptionValueBoolean::AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) {
+ request.SetWordComplete(false);
+ request.GetMatches().Clear();
static const llvm::StringRef g_autocomplete_entries[] = {
"true", "false", "on", "off", "yes", "no", "1", "0"};
auto entries = llvm::makeArrayRef(g_autocomplete_entries);
// only suggest "true" or "false" by default
- if (s.empty())
+ if (request.GetCursorArgumentPrefix().empty())
entries = entries.take_front(2);
for (auto entry : entries) {
- if (entry.startswith_lower(s))
- matches.AppendString(entry);
+ if (entry.startswith_lower(request.GetCursorArgumentPrefix()))
+ request.GetMatches().AppendString(entry);
}
- return matches.GetSize();
+ return request.GetMatches().GetSize();
}
diff --git a/source/Interpreter/OptionValueChar.cpp b/source/Interpreter/OptionValueChar.cpp
index 27684a27264d..21fe88014724 100644
--- a/source/Interpreter/OptionValueChar.cpp
+++ b/source/Interpreter/OptionValueChar.cpp
@@ -13,7 +13,7 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StringList.h"
#include "llvm/ADT/STLExtras.h"
@@ -47,7 +47,7 @@ Status OptionValueChar::SetValueFromString(llvm::StringRef value,
case eVarSetOperationReplace:
case eVarSetOperationAssign: {
bool success = false;
- char char_value = Args::StringToChar(value, '\0', &success);
+ char char_value = OptionArgParser::ToChar(value, '\0', &success);
if (success) {
m_current_value = char_value;
m_value_was_set = true;
diff --git a/source/Interpreter/OptionValueDictionary.cpp b/source/Interpreter/OptionValueDictionary.cpp
index a57ede486319..2e8a8427237b 100644
--- a/source/Interpreter/OptionValueDictionary.cpp
+++ b/source/Interpreter/OptionValueDictionary.cpp
@@ -16,8 +16,8 @@
// Project includes
#include "lldb/Core/State.h"
#include "lldb/DataFormatters/FormatManager.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/OptionValueString.h"
+#include "lldb/Utility/Args.h"
using namespace lldb;
using namespace lldb_private;
@@ -128,9 +128,7 @@ Status OptionValueDictionary::SetArgs(const Args &args,
if (key.front() == '[') {
// Key name starts with '[', so the key value must be in single or
- // double quotes like:
- // ['<key>']
- // ["<key>"]
+ // double quotes like: ['<key>'] ["<key>"]
if ((key.size() > 2) && (key.back() == ']')) {
// Strip leading '[' and trailing ']'
key = key.substr(1, key.size() - 2);
@@ -286,8 +284,8 @@ OptionValueDictionary::GetValueForKey(const ConstString &key) const {
bool OptionValueDictionary::SetValueForKey(const ConstString &key,
const lldb::OptionValueSP &value_sp,
bool can_replace) {
- // Make sure the value_sp object is allowed to contain
- // values of the type passed in...
+ // Make sure the value_sp object is allowed to contain values of the type
+ // passed in...
if (value_sp && (m_type_mask & value_sp->GetTypeAsMask())) {
if (!can_replace) {
collection::const_iterator pos = m_values.find(key);
diff --git a/source/Interpreter/OptionValueEnumeration.cpp b/source/Interpreter/OptionValueEnumeration.cpp
index 9510f4a671d1..e78618ee3c6b 100644
--- a/source/Interpreter/OptionValueEnumeration.cpp
+++ b/source/Interpreter/OptionValueEnumeration.cpp
@@ -109,23 +109,23 @@ lldb::OptionValueSP OptionValueEnumeration::DeepCopy() const {
return OptionValueSP(new OptionValueEnumeration(*this));
}
-size_t OptionValueEnumeration::AutoComplete(
- CommandInterpreter &interpreter, llvm::StringRef s, int match_start_point,
- int max_return_elements, bool &word_complete, StringList &matches) {
- word_complete = false;
- matches.Clear();
+size_t OptionValueEnumeration::AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) {
+ request.SetWordComplete(false);
+ request.GetMatches().Clear();
const uint32_t num_enumerators = m_enumerations.GetSize();
- if (!s.empty()) {
+ if (!request.GetCursorArgumentPrefix().empty()) {
for (size_t i = 0; i < num_enumerators; ++i) {
llvm::StringRef name = m_enumerations.GetCStringAtIndex(i).GetStringRef();
- if (name.startswith(s))
- matches.AppendString(name);
+ if (name.startswith(request.GetCursorArgumentPrefix()))
+ request.GetMatches().AppendString(name);
}
} else {
// only suggest "true" or "false" by default
for (size_t i = 0; i < num_enumerators; ++i)
- matches.AppendString(m_enumerations.GetCStringAtIndex(i).GetStringRef());
+ request.GetMatches().AppendString(
+ m_enumerations.GetCStringAtIndex(i).GetStringRef());
}
- return matches.GetSize();
+ return request.GetMatches().GetSize();
}
diff --git a/source/Interpreter/OptionValueFileSpec.cpp b/source/Interpreter/OptionValueFileSpec.cpp
index 7d17ddec4f9c..18bfcd693949 100644
--- a/source/Interpreter/OptionValueFileSpec.cpp
+++ b/source/Interpreter/OptionValueFileSpec.cpp
@@ -12,9 +12,9 @@
#include "lldb/Core/State.h"
#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Host/FileSystem.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/DataBufferLLVM.h"
using namespace lldb;
@@ -67,18 +67,15 @@ Status OptionValueFileSpec::SetValueFromString(llvm::StringRef value,
case eVarSetOperationAssign:
if (value.size() > 0) {
// The setting value may have whitespace, double-quotes, or single-quotes
- // around the file
- // path to indicate that internal spaces are not word breaks. Strip off
- // any ws & quotes
- // from the start and end of the file path - we aren't doing any word //
- // breaking here so
- // the quoting is unnecessary. NB this will cause a problem if someone
- // tries to specify
+ // around the file path to indicate that internal spaces are not word
+ // breaks. Strip off any ws & quotes from the start and end of the file
+ // path - we aren't doing any word // breaking here so the quoting is
+ // unnecessary. NB this will cause a problem if someone tries to specify
// a file path that legitimately begins or ends with a " or ' character,
// or whitespace.
value = value.trim("\"' \t");
m_value_was_set = true;
- m_current_value.SetFile(value.str(), m_resolve);
+ m_current_value.SetFile(value.str(), m_resolve, FileSpec::Style::native);
m_data_sp.reset();
m_data_mod_time = llvm::sys::TimePoint<>();
NotifyValueChanged();
@@ -102,15 +99,13 @@ lldb::OptionValueSP OptionValueFileSpec::DeepCopy() const {
return OptionValueSP(new OptionValueFileSpec(*this));
}
-size_t OptionValueFileSpec::AutoComplete(
- CommandInterpreter &interpreter, llvm::StringRef s, int match_start_point,
- int max_return_elements, bool &word_complete, StringList &matches) {
- word_complete = false;
- matches.Clear();
+size_t OptionValueFileSpec::AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) {
+ request.SetWordComplete(false);
+ request.GetMatches().Clear();
CommandCompletions::InvokeCommonCompletionCallbacks(
- interpreter, m_completion_mask, s, match_start_point, max_return_elements,
- nullptr, word_complete, matches);
- return matches.GetSize();
+ interpreter, m_completion_mask, request, nullptr);
+ return request.GetMatches().GetSize();
}
const lldb::DataBufferSP &OptionValueFileSpec::GetFileContents() {
diff --git a/source/Interpreter/OptionValueFileSpecLIst.cpp b/source/Interpreter/OptionValueFileSpecLIst.cpp
index 7773bdc5ea9c..7fdc3c780239 100644
--- a/source/Interpreter/OptionValueFileSpecLIst.cpp
+++ b/source/Interpreter/OptionValueFileSpecLIst.cpp
@@ -14,7 +14,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Host/StringConvert.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/Stream.h"
using namespace lldb;
diff --git a/source/Interpreter/OptionValueFormat.cpp b/source/Interpreter/OptionValueFormat.cpp
index 24dd8fd5f71c..1837804a4622 100644
--- a/source/Interpreter/OptionValueFormat.cpp
+++ b/source/Interpreter/OptionValueFormat.cpp
@@ -14,7 +14,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/DataFormatters/FormatManager.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Utility/Stream.h"
using namespace lldb;
@@ -43,7 +43,7 @@ Status OptionValueFormat::SetValueFromString(llvm::StringRef value,
case eVarSetOperationReplace:
case eVarSetOperationAssign: {
Format new_format;
- error = Args::StringToFormat(value.str().c_str(), new_format, nullptr);
+ error = OptionArgParser::ToFormat(value.str().c_str(), new_format, nullptr);
if (error.Success()) {
m_value_was_set = true;
m_current_value = new_format;
diff --git a/source/Interpreter/OptionValueFormatEntity.cpp b/source/Interpreter/OptionValueFormatEntity.cpp
index e9431d4562ec..ce1a84e8dece 100644
--- a/source/Interpreter/OptionValueFormatEntity.cpp
+++ b/source/Interpreter/OptionValueFormatEntity.cpp
@@ -64,12 +64,10 @@ Status OptionValueFormatEntity::SetValueFromString(llvm::StringRef value_str,
case eVarSetOperationReplace:
case eVarSetOperationAssign: {
// Check if the string starts with a quote character after removing leading
- // and trailing spaces.
- // If it does start with a quote character, make sure it ends with the same
- // quote character
- // and remove the quotes before we parse the format string. If the string
- // doesn't start with
- // a quote, leave the string alone and parse as is.
+ // and trailing spaces. If it does start with a quote character, make sure
+ // it ends with the same quote character and remove the quotes before we
+ // parse the format string. If the string doesn't start with a quote, leave
+ // the string alone and parse as is.
llvm::StringRef trimmed_value_str = value_str.trim();
if (!trimmed_value_str.empty()) {
const char first_char = trimmed_value_str[0];
@@ -107,9 +105,7 @@ lldb::OptionValueSP OptionValueFormatEntity::DeepCopy() const {
return OptionValueSP(new OptionValueFormatEntity(*this));
}
-size_t OptionValueFormatEntity::AutoComplete(
- CommandInterpreter &interpreter, llvm::StringRef s, int match_start_point,
- int max_return_elements, bool &word_complete, StringList &matches) {
- return FormatEntity::AutoComplete(s, match_start_point, max_return_elements,
- word_complete, matches);
+size_t OptionValueFormatEntity::AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) {
+ return FormatEntity::AutoComplete(request);
}
diff --git a/source/Interpreter/OptionValueLanguage.cpp b/source/Interpreter/OptionValueLanguage.cpp
index 3290e88c1815..1a82329bf0f3 100644
--- a/source/Interpreter/OptionValueLanguage.cpp
+++ b/source/Interpreter/OptionValueLanguage.cpp
@@ -14,8 +14,8 @@
// Other libraries and framework includes
// Project includes
#include "lldb/DataFormatters/FormatManager.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Target/Language.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/Stream.h"
using namespace lldb;
diff --git a/source/Interpreter/OptionValuePathMappings.cpp b/source/Interpreter/OptionValuePathMappings.cpp
index 5f805720bd3f..8390a8cf5aba 100644
--- a/source/Interpreter/OptionValuePathMappings.cpp
+++ b/source/Interpreter/OptionValuePathMappings.cpp
@@ -14,7 +14,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Host/StringConvert.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Stream.h"
diff --git a/source/Interpreter/OptionValueProperties.cpp b/source/Interpreter/OptionValueProperties.cpp
index ae7669605592..c1887f34b712 100644
--- a/source/Interpreter/OptionValueProperties.cpp
+++ b/source/Interpreter/OptionValueProperties.cpp
@@ -16,9 +16,9 @@
#include "lldb/Utility/Flags.h"
#include "lldb/Core/UserSettingsController.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/OptionValues.h"
#include "lldb/Interpreter/Property.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StringList.h"
@@ -35,15 +35,13 @@ OptionValueProperties::OptionValueProperties(
m_name(global_properties.m_name),
m_properties(global_properties.m_properties),
m_name_to_index(global_properties.m_name_to_index) {
- // We now have an exact copy of "global_properties". We need to now
- // find all non-global settings and copy the property values so that
- // all non-global settings get new OptionValue instances created for
- // them.
+ // We now have an exact copy of "global_properties". We need to now find all
+ // non-global settings and copy the property values so that all non-global
+ // settings get new OptionValue instances created for them.
const size_t num_properties = m_properties.size();
for (size_t i = 0; i < num_properties; ++i) {
// Duplicate any values that are not global when constructing properties
- // from
- // a global copy
+ // from a global copy
if (m_properties[i].IsGlobal() == false) {
lldb::OptionValueSP new_value_sp(m_properties[i].GetValue()->DeepCopy());
m_properties[i].SetOptionValue(new_value_sp);
@@ -157,15 +155,13 @@ OptionValueProperties::GetSubValue(const ExecutionContext *exe_ctx,
case '{':
// Predicate matching for predicates like
// "<setting-name>{<predicate>}"
- // strings are parsed by the current OptionValueProperties subclass
- // to mean whatever they want to. For instance a subclass of
- // OptionValueProperties for a lldb_private::Target might implement:
- // "target.run-args{arch==i386}" -- only set run args if the arch is
- // i386
- // "target.run-args{path=/tmp/a/b/c/a.out}" -- only set run args if the
- // path matches
- // "target.run-args{basename==test&&arch==x86_64}" -- only set run args
- // if executable basename is "test" and arch is "x86_64"
+ // strings are parsed by the current OptionValueProperties subclass to mean
+ // whatever they want to. For instance a subclass of OptionValueProperties
+ // for a lldb_private::Target might implement: "target.run-
+ // args{arch==i386}" -- only set run args if the arch is i386 "target
+ // .run-args{path=/tmp/a/b/c/a.out}" -- only set run args if the path
+ // matches "target.run-args{basename==test&&arch==x86_64}" -- only set run
+ // args if executable basename is "test" and arch is "x86_64"
if (sub_name[1]) {
llvm::StringRef predicate_start = sub_name.drop_front();
size_t pos = predicate_start.find_first_of('}');
@@ -189,9 +185,8 @@ OptionValueProperties::GetSubValue(const ExecutionContext *exe_ctx,
break;
case '[':
- // Array or dictionary access for subvalues like:
- // "[12]" -- access 12th array element
- // "['hello']" -- dictionary access of key named hello
+ // Array or dictionary access for subvalues like: "[12]" -- access
+ // 12th array element "['hello']" -- dictionary access of key named hello
return value_sp->GetSubValue(exe_ctx, sub_name, will_modify, error);
default:
@@ -207,12 +202,23 @@ Status OptionValueProperties::SetSubValue(const ExecutionContext *exe_ctx,
llvm::StringRef value) {
Status error;
const bool will_modify = true;
+ llvm::SmallVector<llvm::StringRef, 8> components;
+ name.split(components, '.');
+ bool name_contains_experimental = false;
+ for (const auto &part : components)
+ if (Properties::IsSettingExperimental(part))
+ name_contains_experimental = true;
+
+
lldb::OptionValueSP value_sp(GetSubValue(exe_ctx, name, will_modify, error));
if (value_sp)
error = value_sp->SetValueFromString(value, op);
else {
- if (error.AsCString() == nullptr)
+ // Don't set an error if the path contained .experimental. - those are
+ // allowed to be missing and should silently fail.
+ if (name_contains_experimental == false && error.AsCString() == nullptr) {
error.SetErrorStringWithFormat("invalid value path '%s'", name.str().c_str());
+ }
}
return error;
}
diff --git a/source/Interpreter/OptionValueSInt64.cpp b/source/Interpreter/OptionValueSInt64.cpp
index 9dbcd58dc3e9..ddd1b9662ca3 100644
--- a/source/Interpreter/OptionValueSInt64.cpp
+++ b/source/Interpreter/OptionValueSInt64.cpp
@@ -21,7 +21,8 @@ using namespace lldb_private;
void OptionValueSInt64::DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
uint32_t dump_mask) {
- // printf ("%p: DumpValue (exe_ctx=%p, strm, mask) m_current_value = %" PRIi64
+ // printf ("%p: DumpValue (exe_ctx=%p, strm, mask) m_current_value = %"
+ // PRIi64
// "\n", this, exe_ctx, m_current_value);
if (dump_mask & eDumpOptionType)
strm.Printf("(%s)", GetTypeAsCString());
diff --git a/source/Interpreter/OptionValueString.cpp b/source/Interpreter/OptionValueString.cpp
index 1d7332dd41a6..8383b531270b 100644
--- a/source/Interpreter/OptionValueString.cpp
+++ b/source/Interpreter/OptionValueString.cpp
@@ -15,7 +15,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Host/OptionParser.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/Stream.h"
using namespace lldb;
diff --git a/source/Interpreter/OptionValueUUID.cpp b/source/Interpreter/OptionValueUUID.cpp
index bec04cba8c37..7fa155277cec 100644
--- a/source/Interpreter/OptionValueUUID.cpp
+++ b/source/Interpreter/OptionValueUUID.cpp
@@ -43,7 +43,7 @@ Status OptionValueUUID::SetValueFromString(llvm::StringRef value,
case eVarSetOperationReplace:
case eVarSetOperationAssign: {
- if (m_uuid.SetFromCString(value.str().c_str()) == 0)
+ if (m_uuid.SetFromStringRef(value) == 0)
error.SetErrorStringWithFormat("invalid uuid string value '%s'",
value.str().c_str());
else {
@@ -68,40 +68,30 @@ lldb::OptionValueSP OptionValueUUID::DeepCopy() const {
}
size_t OptionValueUUID::AutoComplete(CommandInterpreter &interpreter,
- llvm::StringRef s, int match_start_point,
- int max_return_elements,
- bool &word_complete, StringList &matches) {
- word_complete = false;
- matches.Clear();
+ CompletionRequest &request) {
+ request.SetWordComplete(false);
+ request.GetMatches().Clear();
ExecutionContext exe_ctx(interpreter.GetExecutionContext());
Target *target = exe_ctx.GetTargetPtr();
if (target) {
- const size_t num_modules = target->GetImages().GetSize();
- if (num_modules > 0) {
- UUID::ValueType uuid_bytes;
- uint32_t num_bytes_decoded = 0;
- UUID::DecodeUUIDBytesFromString(s, uuid_bytes, num_bytes_decoded);
+ auto prefix = request.GetCursorArgumentPrefix();
+ llvm::SmallVector<uint8_t, 20> uuid_bytes;
+ if (UUID::DecodeUUIDBytesFromString(prefix, uuid_bytes).empty()) {
+ const size_t num_modules = target->GetImages().GetSize();
for (size_t i = 0; i < num_modules; ++i) {
ModuleSP module_sp(target->GetImages().GetModuleAtIndex(i));
if (module_sp) {
const UUID &module_uuid = module_sp->GetUUID();
if (module_uuid.IsValid()) {
- bool add_uuid = false;
- if (num_bytes_decoded == 0)
- add_uuid = true;
- else
- add_uuid = ::memcmp(module_uuid.GetBytes(), uuid_bytes,
- num_bytes_decoded) == 0;
- if (add_uuid) {
- std::string uuid_str;
- uuid_str = module_uuid.GetAsString();
- if (!uuid_str.empty())
- matches.AppendString(uuid_str.c_str());
+ llvm::ArrayRef<uint8_t> module_bytes = module_uuid.GetBytes();
+ if (module_bytes.size() >= uuid_bytes.size() &&
+ module_bytes.take_front(uuid_bytes.size()).equals(uuid_bytes)) {
+ request.GetMatches().AppendString(module_uuid.GetAsString());
}
}
}
}
}
}
- return matches.GetSize();
+ return request.GetMatches().GetSize();
}
diff --git a/source/Interpreter/Options.cpp b/source/Interpreter/Options.cpp
index f8b1a8d6beba..f4758978e2a6 100644
--- a/source/Interpreter/Options.cpp
+++ b/source/Interpreter/Options.cpp
@@ -115,13 +115,12 @@ bool Options::VerifyOptions(CommandReturnObject &result) {
int num_levels = GetRequiredOptions().size();
if (num_levels) {
for (int i = 0; i < num_levels && !options_are_valid; ++i) {
- // This is the correct set of options if: 1). m_seen_options contains all
- // of m_required_options[i]
- // (i.e. all the required options at this level are a subset of
- // m_seen_options); AND
- // 2). { m_seen_options - m_required_options[i] is a subset of
- // m_options_options[i] (i.e. all the rest of
- // m_seen_options are in the set of optional options at this level.
+ // This is the correct set of options if: 1). m_seen_options contains
+ // all of m_required_options[i] (i.e. all the required options at this
+ // level are a subset of m_seen_options); AND 2). { m_seen_options -
+ // m_required_options[i] is a subset of m_options_options[i] (i.e. all
+ // the rest of m_seen_options are in the set of optional options at this
+ // level.
// Check to see if all of m_required_options[i] are a subset of
// m_seen_options
@@ -152,8 +151,7 @@ bool Options::VerifyOptions(CommandReturnObject &result) {
}
// This is called in the Options constructor, though we could call it lazily if
-// that ends up being
-// a performance problem.
+// that ends up being a performance problem.
void Options::BuildValidOptionSets() {
// Check to see if we already did this.
@@ -265,13 +263,11 @@ Option *Options::GetLongOptions() {
}
// This function takes INDENT, which tells how many spaces to output at the
-// front of each line; SPACES, which is
-// a string containing 80 spaces; and TEXT, which is the text that is to be
-// output. It outputs the text, on
+// front of each line; SPACES, which is a string containing 80 spaces; and
+// TEXT, which is the text that is to be output. It outputs the text, on
// multiple lines if necessary, to RESULT, with INDENT spaces at the front of
-// each line. It breaks lines on spaces,
-// tabs or newlines, shortening the line if necessary to not break in the middle
-// of a word. It assumes that each
+// each line. It breaks lines on spaces, tabs or newlines, shortening the line
+// if necessary to not break in the middle of a word. It assumes that each
// output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.
void Options::OutputFormattedUsageText(Stream &strm,
@@ -421,8 +417,8 @@ void Options::GenerateOptionUsage(Stream &strm, CommandObject *cmd,
strm.IndentMore(2);
- // First, show each usage level set of options, e.g. <cmd>
- // [options-for-level-0]
+ // First, show each usage level set of options, e.g. <cmd> [options-for-
+ // level-0]
// <cmd>
// [options-for-level-1]
// etc.
@@ -449,9 +445,9 @@ void Options::GenerateOptionUsage(Stream &strm, CommandObject *cmd,
if (cmd)
cmd->GetFormattedCommandArguments(args_str, opt_set_mask);
- // First go through and print all options that take no arguments as
- // a single string. If a command has "-a" "-b" and "-c", this will show
- // up as [-abc]
+ // First go through and print all options that take no arguments as a
+ // single string. If a command has "-a" "-b" and "-c", this will show up
+ // as [-abc]
std::set<int> options;
std::set<int>::const_iterator options_pos, options_end;
@@ -554,24 +550,23 @@ void Options::GenerateOptionUsage(Stream &strm, CommandObject *cmd,
// help text
// This variable is used to keep track of which options' info we've printed
- // out, because some options can be in
- // more than one usage level, but we only want to print the long form of its
- // information once.
+ // out, because some options can be in more than one usage level, but we
+ // only want to print the long form of its information once.
std::multimap<int, uint32_t> options_seen;
strm.IndentMore(5);
// Put the unique command options in a vector & sort it, so we can output
- // them alphabetically (by short_option)
- // when writing out detailed help for each option.
+ // them alphabetically (by short_option) when writing out detailed help for
+ // each option.
i = 0;
for (auto &def : opt_defs)
options_seen.insert(std::make_pair(def.short_option, i++));
- // Go through the unique'd and alphabetically sorted vector of options, find
- // the table entry for each option
- // and write out the detailed help information for that option.
+ // Go through the unique'd and alphabetically sorted vector of options,
+ // find the table entry for each option and write out the detailed help
+ // information for that option.
bool first_option_printed = false;
@@ -627,14 +622,10 @@ void Options::GenerateOptionUsage(Stream &strm, CommandObject *cmd,
}
// This function is called when we have been given a potentially incomplete set
-// of
-// options, such as when an alias has been defined (more options might be added
-// at
-// at the time the alias is invoked). We need to verify that the options in the
-// set
-// m_seen_options are all part of a set that may be used together, but
-// m_seen_options
-// may be missing some of the "required" options.
+// of options, such as when an alias has been defined (more options might be
+// added at at the time the alias is invoked). We need to verify that the
+// options in the set m_seen_options are all part of a set that may be used
+// together, but m_seen_options may be missing some of the "required" options.
bool Options::VerifyPartialOptions(CommandReturnObject &result) {
bool options_are_valid = false;
@@ -643,10 +634,8 @@ bool Options::VerifyPartialOptions(CommandReturnObject &result) {
if (num_levels) {
for (int i = 0; i < num_levels && !options_are_valid; ++i) {
// In this case we are treating all options as optional rather than
- // required.
- // Therefore a set of options is correct if m_seen_options is a subset of
- // the
- // union of m_required_options and m_optional_options.
+ // required. Therefore a set of options is correct if m_seen_options is a
+ // subset of the union of m_required_options and m_optional_options.
OptionSet union_set;
OptionsSetUnion(GetRequiredOptions()[i], GetOptionalOptions()[i],
union_set);
@@ -658,28 +647,26 @@ bool Options::VerifyPartialOptions(CommandReturnObject &result) {
return options_are_valid;
}
-bool Options::HandleOptionCompletion(
- Args &input, OptionElementVector &opt_element_vector, int cursor_index,
- int char_pos, int match_start_point, int max_return_elements,
- CommandInterpreter &interpreter, bool &word_complete,
- lldb_private::StringList &matches) {
- word_complete = true;
+bool Options::HandleOptionCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector,
+ CommandInterpreter &interpreter) {
+ request.SetWordComplete(true);
// For now we just scan the completions to see if the cursor position is in
// an option or its argument. Otherwise we'll call HandleArgumentCompletion.
- // In the future we can use completion to validate options as well if we want.
+ // In the future we can use completion to validate options as well if we
+ // want.
auto opt_defs = GetDefinitions();
- std::string cur_opt_std_str(input.GetArgumentAtIndex(cursor_index));
- cur_opt_std_str.erase(char_pos);
+ std::string cur_opt_std_str = request.GetCursorArgumentPrefix().str();
const char *cur_opt_str = cur_opt_std_str.c_str();
for (size_t i = 0; i < opt_element_vector.size(); i++) {
int opt_pos = opt_element_vector[i].opt_pos;
int opt_arg_pos = opt_element_vector[i].opt_arg_pos;
int opt_defs_index = opt_element_vector[i].opt_defs_index;
- if (opt_pos == cursor_index) {
+ if (opt_pos == request.GetCursorIndex()) {
// We're completing the option itself.
if (opt_defs_index == OptionArgElement::eBareDash) {
@@ -693,7 +680,7 @@ bool Options::HandleOptionCompletion(
if (!def.short_option)
continue;
opt_str[1] = def.short_option;
- matches.AppendString(opt_str);
+ request.GetMatches().AppendString(opt_str);
}
return true;
@@ -705,25 +692,23 @@ bool Options::HandleOptionCompletion(
full_name.erase(full_name.begin() + 2, full_name.end());
full_name.append(def.long_option);
- matches.AppendString(full_name.c_str());
+ request.GetMatches().AppendString(full_name.c_str());
}
return true;
} else if (opt_defs_index != OptionArgElement::eUnrecognizedArg) {
- // We recognized it, if it an incomplete long option, complete it anyway
- // (getopt_long_only is
- // happy with shortest unique string, but it's still a nice thing to
- // do.) Otherwise return
- // The string so the upper level code will know this is a full match and
- // add the " ".
+ // We recognized it, if it an incomplete long option, complete it
+ // anyway (getopt_long_only is happy with shortest unique string, but
+ // it's still a nice thing to do.) Otherwise return The string so the
+ // upper level code will know this is a full match and add the " ".
if (cur_opt_str && strlen(cur_opt_str) > 2 && cur_opt_str[0] == '-' &&
cur_opt_str[1] == '-' &&
strcmp(opt_defs[opt_defs_index].long_option, cur_opt_str) != 0) {
std::string full_name("--");
full_name.append(opt_defs[opt_defs_index].long_option);
- matches.AppendString(full_name.c_str());
+ request.GetMatches().AppendString(full_name.c_str());
return true;
} else {
- matches.AppendString(input.GetArgumentAtIndex(cursor_index));
+ request.GetMatches().AppendString(request.GetCursorArgument());
return true;
}
} else {
@@ -731,9 +716,8 @@ bool Options::HandleOptionCompletion(
// Check to see if they are writing a long option & complete it.
// I think we will only get in here if the long option table has two
// elements
- // that are not unique up to this point. getopt_long_only does shortest
- // unique match
- // for long options already.
+ // that are not unique up to this point. getopt_long_only does
+ // shortest unique match for long options already.
if (cur_opt_str && strlen(cur_opt_str) > 2 && cur_opt_str[0] == '-' &&
cur_opt_str[1] == '-') {
@@ -747,29 +731,30 @@ bool Options::HandleOptionCompletion(
// The options definitions table has duplicates because of the
// way the grouping information is stored, so only add once.
bool duplicate = false;
- for (size_t k = 0; k < matches.GetSize(); k++) {
- if (matches.GetStringAtIndex(k) == full_name) {
+ for (size_t k = 0; k < request.GetMatches().GetSize(); k++) {
+ if (request.GetMatches().GetStringAtIndex(k) == full_name) {
duplicate = true;
break;
}
}
if (!duplicate)
- matches.AppendString(full_name.c_str());
+ request.GetMatches().AppendString(full_name.c_str());
}
}
}
return true;
}
- } else if (opt_arg_pos == cursor_index) {
- // Okay the cursor is on the completion of an argument.
- // See if it has a completion, otherwise return no matches.
+ } else if (opt_arg_pos == request.GetCursorIndex()) {
+ // Okay the cursor is on the completion of an argument. See if it has a
+ // completion, otherwise return no matches.
+ CompletionRequest subrequest = request;
+ subrequest.SetCursorCharPosition(subrequest.GetCursorArgument().size());
if (opt_defs_index != -1) {
- HandleOptionArgumentCompletion(
- input, cursor_index, strlen(input.GetArgumentAtIndex(cursor_index)),
- opt_element_vector, i, match_start_point, max_return_elements,
- interpreter, word_complete, matches);
+ HandleOptionArgumentCompletion(subrequest, opt_element_vector, i,
+ interpreter);
+ request.SetWordComplete(subrequest.GetWordComplete());
return true;
} else {
// No completion callback means no completions...
@@ -785,11 +770,8 @@ bool Options::HandleOptionCompletion(
}
bool Options::HandleOptionArgumentCompletion(
- Args &input, int cursor_index, int char_pos,
- OptionElementVector &opt_element_vector, int opt_element_index,
- int match_start_point, int max_return_elements,
- CommandInterpreter &interpreter, bool &word_complete,
- lldb_private::StringList &matches) {
+ CompletionRequest &request, OptionElementVector &opt_element_vector,
+ int opt_element_index, CommandInterpreter &interpreter) {
auto opt_defs = GetDefinitions();
std::unique_ptr<SearchFilter> filter_ap;
@@ -801,22 +783,23 @@ bool Options::HandleOptionArgumentCompletion(
OptionEnumValueElement *enum_values = opt_defs[opt_defs_index].enum_values;
if (enum_values != nullptr) {
bool return_value = false;
- std::string match_string(input.GetArgumentAtIndex(opt_arg_pos),
- input.GetArgumentAtIndex(opt_arg_pos) + char_pos);
+ std::string match_string(
+ request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos),
+ request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos) +
+ request.GetCursorCharPosition());
for (int i = 0; enum_values[i].string_value != nullptr; i++) {
if (strstr(enum_values[i].string_value, match_string.c_str()) ==
enum_values[i].string_value) {
- matches.AppendString(enum_values[i].string_value);
+ request.GetMatches().AppendString(enum_values[i].string_value);
return_value = true;
}
}
return return_value;
}
- // If this is a source file or symbol type completion, and there is a
- // -shlib option somewhere in the supplied arguments, then make a search
- // filter
- // for that shared library.
+ // If this is a source file or symbol type completion, and there is a -shlib
+ // option somewhere in the supplied arguments, then make a search filter for
+ // that shared library.
// FIXME: Do we want to also have an "OptionType" so we don't have to match
// string names?
@@ -852,7 +835,8 @@ bool Options::HandleOptionArgumentCompletion(
// restrict it to that shared library.
if (cur_opt_name && strcmp(cur_opt_name, "shlib") == 0 &&
cur_arg_pos != -1) {
- const char *module_name = input.GetArgumentAtIndex(cur_arg_pos);
+ const char *module_name =
+ request.GetParsedLine().GetArgumentAtIndex(cur_arg_pos);
if (module_name) {
FileSpec module_spec(module_name, false);
lldb::TargetSP target_sp =
@@ -867,9 +851,7 @@ bool Options::HandleOptionArgumentCompletion(
}
return CommandCompletions::InvokeCommonCompletionCallbacks(
- interpreter, completion_mask, input.GetArgumentAtIndex(opt_arg_pos),
- match_start_point, max_return_elements, filter_ap.get(), word_complete,
- matches);
+ interpreter, completion_mask, request, filter_ap.get());
}
void OptionGroupOptions::Append(OptionGroup *group) {
@@ -908,8 +890,8 @@ void OptionGroupOptions::Finalize() {
Status OptionGroupOptions::SetOptionValue(uint32_t option_idx,
llvm::StringRef option_value,
ExecutionContext *execution_context) {
- // After calling OptionGroupOptions::Append(...), you must finalize the groups
- // by calling OptionGroupOptions::Finlize()
+ // After calling OptionGroupOptions::Append(...), you must finalize the
+ // groups by calling OptionGroupOptions::Finlize()
assert(m_did_finalize);
Status error;
if (option_idx < m_option_infos.size()) {
@@ -951,3 +933,525 @@ OptionGroupOptions::OptionParsingFinished(ExecutionContext *execution_context) {
}
return error;
}
+
+// OptionParser permutes the arguments while processing them, so we create a
+// temporary array holding to avoid modification of the input arguments. The
+// options themselves are never modified, but the API expects a char * anyway,
+// hence the const_cast.
+static std::vector<char *> GetArgvForParsing(const Args &args) {
+ std::vector<char *> result;
+ // OptionParser always skips the first argument as it is based on getopt().
+ result.push_back(const_cast<char *>("<FAKE-ARG0>"));
+ for (const Args::ArgEntry &entry : args)
+ result.push_back(const_cast<char *>(entry.c_str()));
+ return result;
+}
+
+// Given a permuted argument, find it's position in the original Args vector.
+static Args::const_iterator FindOriginalIter(const char *arg,
+ const Args &original) {
+ return llvm::find_if(
+ original, [arg](const Args::ArgEntry &D) { return D.c_str() == arg; });
+}
+
+// Given a permuted argument, find it's index in the original Args vector.
+static size_t FindOriginalIndex(const char *arg, const Args &original) {
+ return std::distance(original.begin(), FindOriginalIter(arg, original));
+}
+
+// Construct a new Args object, consisting of the entries from the original
+// arguments, but in the permuted order.
+static Args ReconstituteArgsAfterParsing(llvm::ArrayRef<char *> parsed,
+ const Args &original) {
+ Args result;
+ for (const char *arg : parsed) {
+ auto pos = FindOriginalIter(arg, original);
+ assert(pos != original.end());
+ result.AppendArgument(pos->ref, pos->quote);
+ }
+ return result;
+}
+
+static size_t FindArgumentIndexForOption(const Args &args,
+ const Option &long_option) {
+ std::string short_opt = llvm::formatv("-{0}", char(long_option.val)).str();
+ std::string long_opt =
+ llvm::formatv("--{0}", long_option.definition->long_option);
+ for (const auto &entry : llvm::enumerate(args)) {
+ if (entry.value().ref.startswith(short_opt) ||
+ entry.value().ref.startswith(long_opt))
+ return entry.index();
+ }
+
+ return size_t(-1);
+}
+
+llvm::Expected<Args> Options::ParseAlias(const Args &args,
+ OptionArgVector *option_arg_vector,
+ std::string &input_line) {
+ StreamString sstr;
+ int i;
+ Option *long_options = GetLongOptions();
+
+ if (long_options == nullptr) {
+ return llvm::make_error<llvm::StringError>("Invalid long options",
+ llvm::inconvertibleErrorCode());
+ }
+
+ for (i = 0; long_options[i].definition != nullptr; ++i) {
+ if (long_options[i].flag == nullptr) {
+ sstr << (char)long_options[i].val;
+ switch (long_options[i].definition->option_has_arg) {
+ default:
+ case OptionParser::eNoArgument:
+ break;
+ case OptionParser::eRequiredArgument:
+ sstr << ":";
+ break;
+ case OptionParser::eOptionalArgument:
+ sstr << "::";
+ break;
+ }
+ }
+ }
+
+ Args args_copy = args;
+ std::vector<char *> argv = GetArgvForParsing(args);
+
+ std::unique_lock<std::mutex> lock;
+ OptionParser::Prepare(lock);
+ int val;
+ while (1) {
+ int long_options_index = -1;
+ val = OptionParser::Parse(argv.size(), &*argv.begin(), sstr.GetString(),
+ long_options, &long_options_index);
+
+ if (val == -1)
+ break;
+
+ if (val == '?') {
+ return llvm::make_error<llvm::StringError>(
+ "Unknown or ambiguous option", llvm::inconvertibleErrorCode());
+ }
+
+ if (val == 0)
+ continue;
+
+ OptionSeen(val);
+
+ // Look up the long option index
+ if (long_options_index == -1) {
+ for (int j = 0; long_options[j].definition || long_options[j].flag ||
+ long_options[j].val;
+ ++j) {
+ if (long_options[j].val == val) {
+ long_options_index = j;
+ break;
+ }
+ }
+ }
+
+ // See if the option takes an argument, and see if one was supplied.
+ if (long_options_index == -1) {
+ return llvm::make_error<llvm::StringError>(
+ llvm::formatv("Invalid option with value '{0}'.", char(val)).str(),
+ llvm::inconvertibleErrorCode());
+ }
+
+ StreamString option_str;
+ option_str.Printf("-%c", val);
+ const OptionDefinition *def = long_options[long_options_index].definition;
+ int has_arg =
+ (def == nullptr) ? OptionParser::eNoArgument : def->option_has_arg;
+
+ const char *option_arg = nullptr;
+ switch (has_arg) {
+ case OptionParser::eRequiredArgument:
+ if (OptionParser::GetOptionArgument() == nullptr) {
+ return llvm::make_error<llvm::StringError>(
+ llvm::formatv("Option '{0}' is missing argument specifier.",
+ option_str.GetString())
+ .str(),
+ llvm::inconvertibleErrorCode());
+ }
+ LLVM_FALLTHROUGH;
+ case OptionParser::eOptionalArgument:
+ option_arg = OptionParser::GetOptionArgument();
+ LLVM_FALLTHROUGH;
+ case OptionParser::eNoArgument:
+ break;
+ default:
+ return llvm::make_error<llvm::StringError>(
+ llvm::formatv("error with options table; invalid value in has_arg "
+ "field for option '{0}'.",
+ char(val))
+ .str(),
+ llvm::inconvertibleErrorCode());
+ }
+ if (!option_arg)
+ option_arg = "<no-argument>";
+ option_arg_vector->emplace_back(option_str.GetString(), has_arg,
+ option_arg);
+
+ // Find option in the argument list; also see if it was supposed to take an
+ // argument and if one was supplied. Remove option (and argument, if
+ // given) from the argument list. Also remove them from the
+ // raw_input_string, if one was passed in.
+ size_t idx =
+ FindArgumentIndexForOption(args_copy, long_options[long_options_index]);
+ if (idx == size_t(-1))
+ continue;
+
+ if (!input_line.empty()) {
+ auto tmp_arg = args_copy[idx].ref;
+ size_t pos = input_line.find(tmp_arg);
+ if (pos != std::string::npos)
+ input_line.erase(pos, tmp_arg.size());
+ }
+ args_copy.DeleteArgumentAtIndex(idx);
+ if ((long_options[long_options_index].definition->option_has_arg !=
+ OptionParser::eNoArgument) &&
+ (OptionParser::GetOptionArgument() != nullptr) &&
+ (idx < args_copy.GetArgumentCount()) &&
+ (args_copy[idx].ref == OptionParser::GetOptionArgument())) {
+ if (input_line.size() > 0) {
+ auto tmp_arg = args_copy[idx].ref;
+ size_t pos = input_line.find(tmp_arg);
+ if (pos != std::string::npos)
+ input_line.erase(pos, tmp_arg.size());
+ }
+ args_copy.DeleteArgumentAtIndex(idx);
+ }
+ }
+
+ return std::move(args_copy);
+}
+
+OptionElementVector Options::ParseForCompletion(const Args &args,
+ uint32_t cursor_index) {
+ OptionElementVector option_element_vector;
+ StreamString sstr;
+ Option *long_options = GetLongOptions();
+ option_element_vector.clear();
+
+ if (long_options == nullptr)
+ return option_element_vector;
+
+ // Leading : tells getopt to return a : for a missing option argument AND to
+ // suppress error messages.
+
+ sstr << ":";
+ for (int i = 0; long_options[i].definition != nullptr; ++i) {
+ if (long_options[i].flag == nullptr) {
+ sstr << (char)long_options[i].val;
+ switch (long_options[i].definition->option_has_arg) {
+ default:
+ case OptionParser::eNoArgument:
+ break;
+ case OptionParser::eRequiredArgument:
+ sstr << ":";
+ break;
+ case OptionParser::eOptionalArgument:
+ sstr << "::";
+ break;
+ }
+ }
+ }
+
+ std::unique_lock<std::mutex> lock;
+ OptionParser::Prepare(lock);
+ OptionParser::EnableError(false);
+
+ int val;
+ auto opt_defs = GetDefinitions();
+
+ std::vector<char *> dummy_vec = GetArgvForParsing(args);
+
+ // I stick an element on the end of the input, because if the last element
+ // is option that requires an argument, getopt_long_only will freak out.
+ dummy_vec.push_back(const_cast<char *>("<FAKE-VALUE>"));
+
+ bool failed_once = false;
+ uint32_t dash_dash_pos = -1;
+
+ while (1) {
+ bool missing_argument = false;
+ int long_options_index = -1;
+
+ val = OptionParser::Parse(dummy_vec.size(), &dummy_vec[0], sstr.GetString(),
+ long_options, &long_options_index);
+
+ if (val == -1) {
+ // When we're completing a "--" which is the last option on line,
+ if (failed_once)
+ break;
+
+ failed_once = true;
+
+ // If this is a bare "--" we mark it as such so we can complete it
+ // successfully later. Handling the "--" is a little tricky, since that
+ // may mean end of options or arguments, or the user might want to
+ // complete options by long name. I make this work by checking whether
+ // the cursor is in the "--" argument, and if so I assume we're
+ // completing the long option, otherwise I let it pass to
+ // OptionParser::Parse which will terminate the option parsing. Note, in
+ // either case we continue parsing the line so we can figure out what
+ // other options were passed. This will be useful when we come to
+ // restricting completions based on what other options we've seen on the
+ // line.
+
+ if (static_cast<size_t>(OptionParser::GetOptionIndex()) <
+ dummy_vec.size() &&
+ (strcmp(dummy_vec[OptionParser::GetOptionIndex() - 1], "--") == 0)) {
+ dash_dash_pos = FindOriginalIndex(
+ dummy_vec[OptionParser::GetOptionIndex() - 1], args);
+ if (dash_dash_pos == cursor_index) {
+ option_element_vector.push_back(
+ OptionArgElement(OptionArgElement::eBareDoubleDash, dash_dash_pos,
+ OptionArgElement::eBareDoubleDash));
+ continue;
+ } else
+ break;
+ } else
+ break;
+ } else if (val == '?') {
+ option_element_vector.push_back(OptionArgElement(
+ OptionArgElement::eUnrecognizedArg,
+ FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 1],
+ args),
+ OptionArgElement::eUnrecognizedArg));
+ continue;
+ } else if (val == 0) {
+ continue;
+ } else if (val == ':') {
+ // This is a missing argument.
+ val = OptionParser::GetOptionErrorCause();
+ missing_argument = true;
+ }
+
+ OptionSeen(val);
+
+ // Look up the long option index
+ if (long_options_index == -1) {
+ for (int j = 0; long_options[j].definition || long_options[j].flag ||
+ long_options[j].val;
+ ++j) {
+ if (long_options[j].val == val) {
+ long_options_index = j;
+ break;
+ }
+ }
+ }
+
+ // See if the option takes an argument, and see if one was supplied.
+ if (long_options_index >= 0) {
+ int opt_defs_index = -1;
+ for (size_t i = 0; i < opt_defs.size(); i++) {
+ if (opt_defs[i].short_option != val)
+ continue;
+ opt_defs_index = i;
+ break;
+ }
+
+ const OptionDefinition *def = long_options[long_options_index].definition;
+ int has_arg =
+ (def == nullptr) ? OptionParser::eNoArgument : def->option_has_arg;
+ switch (has_arg) {
+ case OptionParser::eNoArgument:
+ option_element_vector.push_back(OptionArgElement(
+ opt_defs_index,
+ FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 1],
+ args),
+ 0));
+ break;
+ case OptionParser::eRequiredArgument:
+ if (OptionParser::GetOptionArgument() != nullptr) {
+ int arg_index;
+ if (missing_argument)
+ arg_index = -1;
+ else
+ arg_index = OptionParser::GetOptionIndex() - 2;
+
+ option_element_vector.push_back(OptionArgElement(
+ opt_defs_index,
+ FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 2],
+ args),
+ arg_index));
+ } else {
+ option_element_vector.push_back(OptionArgElement(
+ opt_defs_index,
+ FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 1],
+ args),
+ -1));
+ }
+ break;
+ case OptionParser::eOptionalArgument:
+ if (OptionParser::GetOptionArgument() != nullptr) {
+ option_element_vector.push_back(OptionArgElement(
+ opt_defs_index,
+ FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 2],
+ args),
+ FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 1],
+ args)));
+ } else {
+ option_element_vector.push_back(OptionArgElement(
+ opt_defs_index,
+ FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 2],
+ args),
+ FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 1],
+ args)));
+ }
+ break;
+ default:
+ // The options table is messed up. Here we'll just continue
+ option_element_vector.push_back(OptionArgElement(
+ OptionArgElement::eUnrecognizedArg,
+ FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 1],
+ args),
+ OptionArgElement::eUnrecognizedArg));
+ break;
+ }
+ } else {
+ option_element_vector.push_back(OptionArgElement(
+ OptionArgElement::eUnrecognizedArg,
+ FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 1],
+ args),
+ OptionArgElement::eUnrecognizedArg));
+ }
+ }
+
+ // Finally we have to handle the case where the cursor index points at a
+ // single "-". We want to mark that in the option_element_vector, but only
+ // if it is not after the "--". But it turns out that OptionParser::Parse
+ // just ignores an isolated "-". So we have to look it up by hand here. We
+ // only care if it is AT the cursor position. Note, a single quoted dash is
+ // not the same as a single dash...
+
+ const Args::ArgEntry &cursor = args[cursor_index];
+ if ((static_cast<int32_t>(dash_dash_pos) == -1 ||
+ cursor_index < dash_dash_pos) &&
+ !cursor.IsQuoted() && cursor.ref == "-") {
+ option_element_vector.push_back(
+ OptionArgElement(OptionArgElement::eBareDash, cursor_index,
+ OptionArgElement::eBareDash));
+ }
+ return option_element_vector;
+}
+
+llvm::Expected<Args> Options::Parse(const Args &args,
+ ExecutionContext *execution_context,
+ lldb::PlatformSP platform_sp,
+ bool require_validation) {
+ StreamString sstr;
+ Status error;
+ Option *long_options = GetLongOptions();
+ if (long_options == nullptr) {
+ return llvm::make_error<llvm::StringError>("Invalid long options.",
+ llvm::inconvertibleErrorCode());
+ }
+
+ for (int i = 0; long_options[i].definition != nullptr; ++i) {
+ if (long_options[i].flag == nullptr) {
+ if (isprint8(long_options[i].val)) {
+ sstr << (char)long_options[i].val;
+ switch (long_options[i].definition->option_has_arg) {
+ default:
+ case OptionParser::eNoArgument:
+ break;
+ case OptionParser::eRequiredArgument:
+ sstr << ':';
+ break;
+ case OptionParser::eOptionalArgument:
+ sstr << "::";
+ break;
+ }
+ }
+ }
+ }
+ std::vector<char *> argv = GetArgvForParsing(args);
+ std::unique_lock<std::mutex> lock;
+ OptionParser::Prepare(lock);
+ int val;
+ while (1) {
+ int long_options_index = -1;
+ val = OptionParser::Parse(argv.size(), &*argv.begin(), sstr.GetString(),
+ long_options, &long_options_index);
+ if (val == -1)
+ break;
+
+ // Did we get an error?
+ if (val == '?') {
+ error.SetErrorStringWithFormat("unknown or ambiguous option");
+ break;
+ }
+ // The option auto-set itself
+ if (val == 0)
+ continue;
+
+ OptionSeen(val);
+
+ // Lookup the long option index
+ if (long_options_index == -1) {
+ for (int i = 0; long_options[i].definition || long_options[i].flag ||
+ long_options[i].val;
+ ++i) {
+ if (long_options[i].val == val) {
+ long_options_index = i;
+ break;
+ }
+ }
+ }
+ // Call the callback with the option
+ if (long_options_index >= 0 &&
+ long_options[long_options_index].definition) {
+ const OptionDefinition *def = long_options[long_options_index].definition;
+
+ if (!platform_sp) {
+ // User did not pass in an explicit platform. Try to grab from the
+ // execution context.
+ TargetSP target_sp =
+ execution_context ? execution_context->GetTargetSP() : TargetSP();
+ platform_sp = target_sp ? target_sp->GetPlatform() : PlatformSP();
+ }
+ OptionValidator *validator = def->validator;
+
+ if (!platform_sp && require_validation) {
+ // Caller requires validation but we cannot validate as we don't have
+ // the mandatory platform against which to validate.
+ return llvm::make_error<llvm::StringError>(
+ "cannot validate options: no platform available",
+ llvm::inconvertibleErrorCode());
+ }
+
+ bool validation_failed = false;
+ if (platform_sp) {
+ // Ensure we have an execution context, empty or not.
+ ExecutionContext dummy_context;
+ ExecutionContext *exe_ctx_p =
+ execution_context ? execution_context : &dummy_context;
+ if (validator && !validator->IsValid(*platform_sp, *exe_ctx_p)) {
+ validation_failed = true;
+ error.SetErrorStringWithFormat("Option \"%s\" invalid. %s",
+ def->long_option,
+ def->validator->LongConditionString());
+ }
+ }
+
+ // As long as validation didn't fail, we set the option value.
+ if (!validation_failed)
+ error =
+ SetOptionValue(long_options_index,
+ (def->option_has_arg == OptionParser::eNoArgument)
+ ? nullptr
+ : OptionParser::GetOptionArgument(),
+ execution_context);
+ } else {
+ error.SetErrorStringWithFormat("invalid option with value '%i'", val);
+ }
+ if (error.Fail())
+ return error.ToError();
+ }
+
+ argv.erase(argv.begin(), argv.begin() + OptionParser::GetOptionIndex());
+ return ReconstituteArgsAfterParsing(argv, args);
+}
diff --git a/source/Interpreter/Property.cpp b/source/Interpreter/Property.cpp
index 5bac5ea0002f..369029bc570d 100644
--- a/source/Interpreter/Property.cpp
+++ b/source/Interpreter/Property.cpp
@@ -16,6 +16,7 @@
#include "lldb/Core/UserSettingsController.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionValues.h"
#include "lldb/Target/Language.h"
@@ -53,7 +54,7 @@ Property::Property(const PropertyDefinition &definition)
// "definition.default_cstr_value" as a string value that represents the
// default value.
if (definition.default_cstr_value)
- m_value_sp.reset(new OptionValueBoolean(Args::StringToBoolean(
+ m_value_sp.reset(new OptionValueBoolean(OptionArgParser::ToBoolean(
llvm::StringRef(definition.default_cstr_value), false, nullptr)));
else
m_value_sp.reset(
@@ -62,7 +63,8 @@ Property::Property(const PropertyDefinition &definition)
case OptionValue::eTypeChar: {
llvm::StringRef s(definition.default_cstr_value ? definition.default_cstr_value : "");
- m_value_sp = std::make_shared<OptionValueChar>(Args::StringToChar(s, '\0', nullptr));
+ m_value_sp = std::make_shared<OptionValueChar>(
+ OptionArgParser::ToChar(s, '\0', nullptr));
break;
}
case OptionValue::eTypeDictionary:
@@ -75,8 +77,7 @@ Property::Property(const PropertyDefinition &definition)
// "definition.default_uint_value" is the default enumeration value if
// "definition.default_cstr_value" is NULL, otherwise interpret
// "definition.default_cstr_value" as a string value that represents the
- // default
- // value.
+ // default value.
{
OptionValueEnumeration *enum_value = new OptionValueEnumeration(
definition.enum_values, definition.default_uint_value);
@@ -87,10 +88,10 @@ Property::Property(const PropertyDefinition &definition)
llvm::StringRef(definition.default_cstr_value))
.Success()) {
enum_value->SetDefaultValue(enum_value->GetCurrentValue());
- // Call Clear() since we don't want the value to appear as
- // having been set since we called SetValueFromString() above.
- // Clear will set the current value to the default and clear
- // the boolean that says that the value has been set.
+ // Call Clear() since we don't want the value to appear as having
+ // been set since we called SetValueFromString() above. Clear will
+ // set the current value to the default and clear the boolean that
+ // says that the value has been set.
enum_value->Clear();
}
}
@@ -99,8 +100,7 @@ Property::Property(const PropertyDefinition &definition)
case OptionValue::eTypeFileSpec: {
// "definition.default_uint_value" represents if the
- // "definition.default_cstr_value" should
- // be resolved or not
+ // "definition.default_cstr_value" should be resolved or not
const bool resolve = definition.default_uint_value != 0;
m_value_sp.reset(new OptionValueFileSpec(
FileSpec(definition.default_cstr_value, resolve), resolve));
@@ -115,16 +115,14 @@ Property::Property(const PropertyDefinition &definition)
case OptionValue::eTypeFormat:
// "definition.default_uint_value" is the default format enumeration value
- // if
- // "definition.default_cstr_value" is NULL, otherwise interpret
+ // if "definition.default_cstr_value" is NULL, otherwise interpret
// "definition.default_cstr_value" as a string value that represents the
- // default
- // value.
+ // default value.
{
Format new_format = eFormatInvalid;
if (definition.default_cstr_value)
- Args::StringToFormat(definition.default_cstr_value, new_format,
- nullptr);
+ OptionArgParser::ToFormat(definition.default_cstr_value, new_format,
+ nullptr);
else
new_format = (Format)definition.default_uint_value;
m_value_sp.reset(new OptionValueFormat(new_format));
@@ -132,12 +130,10 @@ Property::Property(const PropertyDefinition &definition)
break;
case OptionValue::eTypeLanguage:
- // "definition.default_uint_value" is the default language enumeration value
- // if
- // "definition.default_cstr_value" is NULL, otherwise interpret
+ // "definition.default_uint_value" is the default language enumeration
+ // value if "definition.default_cstr_value" is NULL, otherwise interpret
// "definition.default_cstr_value" as a string value that represents the
- // default
- // value.
+ // default value.
{
LanguageType new_lang = eLanguageTypeUnknown;
if (definition.default_cstr_value)
@@ -158,8 +154,7 @@ Property::Property(const PropertyDefinition &definition)
case OptionValue::eTypePathMap:
// "definition.default_uint_value" tells us if notifications should occur
- // for
- // path mappings
+ // for path mappings
m_value_sp.reset(
new OptionValuePathMappings(definition.default_uint_value != 0));
break;
@@ -175,8 +170,7 @@ Property::Property(const PropertyDefinition &definition)
// "definition.default_uint_value" is the default integer value if
// "definition.default_cstr_value" is NULL, otherwise interpret
// "definition.default_cstr_value" as a string value that represents the
- // default
- // value.
+ // default value.
m_value_sp.reset(new OptionValueSInt64(
definition.default_cstr_value
? StringConvert::ToSInt64(definition.default_cstr_value)
@@ -187,8 +181,7 @@ Property::Property(const PropertyDefinition &definition)
// "definition.default_uint_value" is the default unsigned integer value if
// "definition.default_cstr_value" is NULL, otherwise interpret
// "definition.default_cstr_value" as a string value that represents the
- // default
- // value.
+ // default value.
m_value_sp.reset(new OptionValueUInt64(
definition.default_cstr_value
? StringConvert::ToUInt64(definition.default_cstr_value)
@@ -201,15 +194,15 @@ Property::Property(const PropertyDefinition &definition)
{
UUID uuid;
if (definition.default_cstr_value)
- uuid.SetFromCString(definition.default_cstr_value);
+ uuid.SetFromStringRef(definition.default_cstr_value);
m_value_sp.reset(new OptionValueUUID(uuid));
}
break;
case OptionValue::eTypeString:
- // "definition.default_uint_value" can contain the string option flags OR'ed
- // together
- // "definition.default_cstr_value" can contain a default string value
+ // "definition.default_uint_value" can contain the string option flags
+ // OR'ed together "definition.default_cstr_value" can contain a default
+ // string value
{
OptionValueString *string_value =
new OptionValueString(definition.default_cstr_value);
diff --git a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
index 1bd1c1bf8dd4..e0e293d7ae68 100644
--- a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
+++ b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
@@ -1466,8 +1466,8 @@ bool ABIMacOSX_arm::GetArgumentValues(Thread &thread, ValueList &values) const {
addr_t sp = 0;
for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) {
- // We currently only support extracting values with Clang QualTypes.
- // Do we care about others?
+ // We currently only support extracting values with Clang QualTypes. Do we
+ // care about others?
Value *value = values.GetValueAtIndex(value_idx);
if (!value)
@@ -1589,10 +1589,8 @@ ValueObjectSP ABIMacOSX_arm::GetReturnValueObjectImpl(
case 128:
if (IsArmv7kProcess()) {
// "A composite type not larger than 16 bytes is returned in r0-r3. The
- // format is
- // as if the result had been stored in memory at a word-aligned address
- // and then
- // loaded into r0-r3 with an ldm instruction"
+ // format is as if the result had been stored in memory at a word-
+ // aligned address and then loaded into r0-r3 with an ldm instruction"
{
const RegisterInfo *r1_reg_info =
reg_ctx->GetRegisterInfoByName("r1", 0);
@@ -1756,10 +1754,8 @@ Status ABIMacOSX_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
}
} else if (num_bytes <= 16 && IsArmv7kProcess()) {
// "A composite type not larger than 16 bytes is returned in r0-r3. The
- // format is
- // as if the result had been stored in memory at a word-aligned address
- // and then
- // loaded into r0-r3 with an ldm instruction"
+ // format is as if the result had been stored in memory at a word-aligned
+ // address and then loaded into r0-r3 with an ldm instruction"
const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("r0", 0);
const RegisterInfo *r1_info = reg_ctx->GetRegisterInfoByName("r1", 0);
diff --git a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
index e301b21d542a..85f864ec7561 100644
--- a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
+++ b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
@@ -1760,8 +1760,8 @@ bool ABIMacOSX_arm64::GetArgumentValues(Thread &thread,
addr_t sp = 0;
for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) {
- // We currently only support extracting values with Clang QualTypes.
- // Do we care about others?
+ // We currently only support extracting values with Clang QualTypes. Do we
+ // care about others?
Value *value = values.GetValueAtIndex(value_idx);
if (!value)
@@ -2022,10 +2022,9 @@ bool ABIMacOSX_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
}
// AAPCS64 (Procedure Call Standard for the ARM 64-bit Architecture) says
-// registers x19 through x28 and sp are callee preserved.
-// v8-v15 are non-volatile (and specifically only the lower 8 bytes of these
-// regs),
-// the rest of the fp/SIMD registers are volatile.
+// registers x19 through x28 and sp are callee preserved. v8-v15 are non-
+// volatile (and specifically only the lower 8 bytes of these regs), the rest
+// of the fp/SIMD registers are volatile.
// We treat x29 as callee preserved also, else the unwinder won't try to
// retrieve fp saves.
@@ -2209,14 +2208,14 @@ static bool LoadValueFromConsecutiveGPRRegisters(
} else {
const RegisterInfo *reg_info = nullptr;
if (is_return_value) {
- // We are assuming we are decoding this immediately after returning
- // from a function call and that the address of the structure is in x8
+ // We are assuming we are decoding this immediately after returning from
+ // a function call and that the address of the structure is in x8
reg_info = reg_ctx->GetRegisterInfoByName("x8", 0);
} else {
// We are assuming we are stopped at the first instruction in a function
- // and that the ABI is being respected so all parameters appear where they
- // should be (functions with no external linkage can legally violate the
- // ABI).
+ // and that the ABI is being respected so all parameters appear where
+ // they should be (functions with no external linkage can legally violate
+ // the ABI).
if (NGRN >= 8)
return false;
diff --git a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
index 716a73b854b3..9e5e39ec28ca 100644
--- a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
+++ b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
@@ -736,10 +736,10 @@ bool ABIMacOSX_i386::PrepareTrivialCall(Thread &thread, addr_t sp,
uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
- // When writing a register value down to memory, the register info used
- // to write memory just needs to have the correct size of a 32 bit register,
- // the actual register it pertains to is not important, just the size needs
- // to be correct. Here we use "eax"...
+ // When writing a register value down to memory, the register info used to
+ // write memory just needs to have the correct size of a 32 bit register, the
+ // actual register it pertains to is not important, just the size needs to be
+ // correct. Here we use "eax"...
const RegisterInfo *reg_info_32 = reg_ctx->GetRegisterInfoByName("eax");
if (!reg_info_32)
return false; // TODO this should actually never happen
@@ -828,8 +828,8 @@ bool ABIMacOSX_i386::GetArgumentValues(Thread &thread,
if (!value)
return false;
- // We currently only support extracting values with Clang QualTypes.
- // Do we care about others?
+ // We currently only support extracting values with Clang QualTypes. Do we
+ // care about others?
CompilerType compiler_type(value->GetCompilerType());
if (compiler_type) {
bool is_signed;
@@ -1075,12 +1075,13 @@ bool ABIMacOSX_i386::RegisterIsVolatile(const RegisterInfo *reg_info) {
}
// v.
-// http://developer.apple.com/library/mac/#documentation/developertools/Conceptual/LowLevelABI/130-IA-32_Function_Calling_Conventions/IA32.html#//apple_ref/doc/uid/TP40002492-SW4
+// http://developer.apple.com/library/mac/#documentation/developertools/Conceptual/LowLevelABI/130
+// -IA-
+// 32_Function_Calling_Conventions/IA32.html#//apple_ref/doc/uid/TP40002492-SW4
//
// This document ("OS X ABI Function Call Guide", chapter "IA-32 Function
-// Calling Conventions")
-// says that the following registers on i386 are preserved aka non-volatile aka
-// callee-saved:
+// Calling Conventions") says that the following registers on i386 are
+// preserved aka non-volatile aka callee-saved:
//
// ebx, ebp, esi, edi, esp
diff --git a/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp b/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
index 882d5cd23e58..af7ac469e6db 100644
--- a/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
+++ b/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
@@ -1470,8 +1470,8 @@ bool ABISysV_arm::GetArgumentValues(Thread &thread, ValueList &values) const {
addr_t sp = 0;
for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) {
- // We currently only support extracting values with Clang QualTypes.
- // Do we care about others?
+ // We currently only support extracting values with Clang QualTypes. Do we
+ // care about others?
Value *value = values.GetValueAtIndex(value_idx);
if (!value)
diff --git a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
index dbe333c4649e..2c221689954c 100644
--- a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
+++ b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
@@ -1763,8 +1763,8 @@ bool ABISysV_arm64::GetArgumentValues(Thread &thread, ValueList &values) const {
addr_t sp = 0;
for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) {
- // We currently only support extracting values with Clang QualTypes.
- // Do we care about others?
+ // We currently only support extracting values with Clang QualTypes. Do we
+ // care about others?
Value *value = values.GetValueAtIndex(value_idx);
if (!value)
@@ -1994,10 +1994,9 @@ bool ABISysV_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
}
// AAPCS64 (Procedure Call Standard for the ARM 64-bit Architecture) says
-// registers x19 through x28 and sp are callee preserved.
-// v8-v15 are non-volatile (and specifically only the lower 8 bytes of these
-// regs),
-// the rest of the fp/SIMD registers are volatile.
+// registers x19 through x28 and sp are callee preserved. v8-v15 are non-
+// volatile (and specifically only the lower 8 bytes of these regs), the rest
+// of the fp/SIMD registers are volatile.
// We treat x29 as callee preserved also, else the unwinder won't try to
// retrieve fp saves.
@@ -2020,10 +2019,10 @@ bool ABISysV_arm64::RegisterIsVolatile(const RegisterInfo *reg_info) {
if (name[0] == 'x' || name[0] == 'r') {
// Volatile registers: x0-x18
- // Although documentation says only x19-28 + sp are callee saved
- // We ll also have to treat x30 as non-volatile.
- // Each dwarf frame has its own value of lr.
- // Return false for the non-volatile gpr regs, true for everything else
+ // Although documentation says only x19-28 + sp are callee saved We ll
+ // also have to treat x30 as non-volatile. Each dwarf frame has its own
+ // value of lr. Return false for the non-volatile gpr regs, true for
+ // everything else
switch (name[1]) {
case '1':
switch (name[2]) {
@@ -2180,14 +2179,14 @@ static bool LoadValueFromConsecutiveGPRRegisters(
} else {
const RegisterInfo *reg_info = nullptr;
if (is_return_value) {
- // We are assuming we are decoding this immediately after returning
- // from a function call and that the address of the structure is in x8
+ // We are assuming we are decoding this immediately after returning from
+ // a function call and that the address of the structure is in x8
reg_info = reg_ctx->GetRegisterInfoByName("x8", 0);
} else {
// We are assuming we are stopped at the first instruction in a function
- // and that the ABI is being respected so all parameters appear where they
- // should be (functions with no external linkage can legally violate the
- // ABI).
+ // and that the ABI is being respected so all parameters appear where
+ // they should be (functions with no external linkage can legally violate
+ // the ABI).
if (NGRN >= 8)
return false;
diff --git a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
index 74274f08b24f..a30416cf5a8e 100644
--- a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
+++ b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
@@ -1214,8 +1214,8 @@ ValueObjectSP ABISysV_hexagon::GetReturnValueObjectImpl(
return return_valobj_sp;
}
-// called when we are on the first instruction of a new function
-// for hexagon the return address is in RA (R31)
+// called when we are on the first instruction of a new function for hexagon
+// the return address is in RA (R31)
bool ABISysV_hexagon::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.Clear();
unwind_plan.SetRegisterKind(eRegisterKindGeneric);
diff --git a/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp b/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
index d799c587dd07..e7ddfccea338 100644
--- a/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
+++ b/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
@@ -3,8 +3,7 @@
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
-// License.
-// See LICENSE.TXT for details.
+// License. See LICENSE.TXT for details.
//===----------------------------------------------------------------------===//
#include "ABISysV_i386.h"
@@ -56,8 +55,8 @@ using namespace lldb_private;
// DWARF Register Number Mapping
// See Table 2.14 of the reference document (specified on top of this file)
-// Comment: Table 2.14 is followed till 'mm' entries.
-// After that, all entries are ignored here.
+// Comment: Table 2.14 is followed till 'mm' entries. After that, all entries
+// are ignored here.
enum dwarf_regnums {
dwarf_eax = 0,
@@ -228,12 +227,10 @@ bool ABISysV_i386::PrepareTrivialCall(Thread &thread, addr_t sp,
uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
- // While using register info to write a register value to memory, the register
- // info
- // just needs to have the correct size of a 32 bit register, the actual
- // register it
- // pertains to is not important, just the size needs to be correct.
- // "eax" is used here for this purpose.
+ // While using register info to write a register value to memory, the
+ // register info just needs to have the correct size of a 32 bit register,
+ // the actual register it pertains to is not important, just the size needs
+ // to be correct. "eax" is used here for this purpose.
const RegisterInfo *reg_info_32 = reg_ctx->GetRegisterInfoByName("eax");
if (!reg_info_32)
return false; // TODO this should actually never happen
@@ -364,8 +361,8 @@ Status ABISysV_i386::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
}
// Following "IF ELSE" block categorizes various 'Fundamental Data Types'.
- // The terminology 'Fundamental Data Types' used here is adopted from
- // Table 2.1 of the reference document (specified on top of this file)
+ // The terminology 'Fundamental Data Types' used here is adopted from Table
+ // 2.1 of the reference document (specified on top of this file)
if (type_flags & eTypeIsPointer) // 'Pointer'
{
@@ -390,8 +387,8 @@ Status ABISysV_i386::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
default:
break;
case 16:
- // For clang::BuiltinType::UInt128 & Int128
- // ToDo: Need to decide how to handle it
+ // For clang::BuiltinType::UInt128 & Int128 ToDo: Need to decide how to
+ // handle it
break;
case 8: {
uint32_t raw_value_low = data.GetMaxU32(&offset, 4);
@@ -470,8 +467,8 @@ Status ABISysV_i386::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
error.SetErrorString("Implementation is missing for this clang type.");
}
} else {
- // Neither 'Integral' nor 'Floating Point'. If flow reaches here
- // then check type_flags. This type_flags is not a valid type.
+ // Neither 'Integral' nor 'Floating Point'. If flow reaches here then
+ // check type_flags. This type_flags is not a valid type.
error.SetErrorString("Invalid clang type");
}
} else {
@@ -508,8 +505,8 @@ ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple(
reg_ctx->GetRegisterInfoByName("edx", 0)->kinds[eRegisterKindLLDB];
// Following "IF ELSE" block categorizes various 'Fundamental Data Types'.
- // The terminology 'Fundamental Data Types' used here is adopted from
- // Table 2.1 of the reference document (specified on top of this file)
+ // The terminology 'Fundamental Data Types' used here is adopted from Table
+ // 2.1 of the reference document (specified on top of this file)
if (type_flags & eTypeIsPointer) // 'Pointer'
{
@@ -543,8 +540,8 @@ ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple(
break;
case 16:
- // For clang::BuiltinType::UInt128 & Int128
- // ToDo: Need to decide how to handle it
+ // For clang::BuiltinType::UInt128 & Int128 ToDo: Need to decide how to
+ // handle it
break;
case 8:
@@ -612,8 +609,8 @@ ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple(
success = true;
} else if (byte_size == 8) // double is 8 bytes
{
- // On Android Platform: long double is also 8 bytes
- // It will be handled here only.
+ // On Android Platform: long double is also 8 bytes It will be
+ // handled here only.
double value_double = (double)value_long_double;
value.GetScalar() = value_double;
success = true;
@@ -639,8 +636,8 @@ ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple(
}
} else // Neither 'Integral' nor 'Floating Point'
{
- // If flow reaches here then check type_flags
- // This type_flags is unhandled
+ // If flow reaches here then check type_flags This type_flags is
+ // unhandled
}
} else if (type_flags & eTypeIsComplex) // 'Complex Floating Point'
{
@@ -797,9 +794,9 @@ bool ABISysV_i386::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
return true;
}
-// According to "Register Usage" in reference document (specified on top
-// of this source file) ebx, ebp, esi, edi and esp registers are preserved
-// i.e. non-volatile i.e. callee-saved on i386
+// According to "Register Usage" in reference document (specified on top of
+// this source file) ebx, ebp, esi, edi and esp registers are preserved i.e.
+// non-volatile i.e. callee-saved on i386
bool ABISysV_i386::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
if (!reg_info)
return false;
diff --git a/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp b/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
index 95e2a7b0afeb..ce02f8677a63 100644
--- a/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
+++ b/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
@@ -698,8 +698,8 @@ bool ABISysV_mips::PrepareTrivialCall(Thread &thread, addr_t sp,
if (log)
log->Printf("Writing r25: 0x%" PRIx64, (uint64_t)func_addr);
- // All callers of position independent functions must place the address of the
- // called function in t9 (r25)
+ // All callers of position independent functions must place the address of
+ // the called function in t9 (r25)
if (!reg_ctx->WriteRegisterFromUnsigned(r25_info, func_addr))
return false;
@@ -867,8 +867,8 @@ ValueObjectSP ABISysV_mips::GetReturnValueObjectImpl(
UINT32_MAX;
value.GetScalar() = ptr;
} else if (return_compiler_type.IsAggregateType()) {
- // Structure/Vector is always passed in memory and pointer to that memory is
- // passed in r2.
+ // Structure/Vector is always passed in memory and pointer to that memory
+ // is passed in r2.
uint64_t mem_address = reg_ctx->ReadRegisterAsUnsigned(
reg_ctx->GetRegisterInfoByName("r2", 0), 0);
// We have got the address. Create a memory object out of it
diff --git a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
index 749e170fa17d..b958abf25637 100644
--- a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
+++ b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
@@ -661,8 +661,8 @@ bool ABISysV_mips64::PrepareTrivialCall(Thread &thread, addr_t sp,
if (log)
log->Printf("Writing r25: 0x%" PRIx64, (uint64_t)func_addr);
- // All callers of position independent functions must place the address of the
- // called function in t9 (r25)
+ // All callers of position independent functions must place the address of
+ // the called function in t9 (r25)
if (!reg_ctx->WriteRegisterFromUnsigned(r25_info, func_addr))
return false;
@@ -1035,10 +1035,9 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
}
}
- // If we reach here, it means this structure either contains more than two
- // fields or
- // it contains at least one non floating point type.
- // In that case, all fields are returned in GP return registers.
+ // If we reach here, it means this structure either contains more than
+ // two fields or it contains at least one non floating point type. In
+ // that case, all fields are returned in GP return registers.
for (uint32_t idx = 0; idx < num_children; idx++) {
uint64_t field_bit_offset = 0;
bool is_signed;
@@ -1049,8 +1048,8 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
const size_t field_byte_width =
field_compiler_type.GetByteSize(nullptr);
- // if we don't know the size of the field (e.g. invalid type), just bail
- // out
+ // if we don't know the size of the field (e.g. invalid type), just
+ // bail out
if (field_byte_width == 0)
break;
@@ -1078,16 +1077,15 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
}
}
// We already have consumed at-least 8 bytes that means r2 is done,
- // and this field will be in r3.
- // Check if this field can fit in r3.
+ // and this field will be in r3. Check if this field can fit in r3.
else if (integer_bytes + field_byte_width + padding <= 16) {
integer_bytes = integer_bytes + field_byte_width + padding;
use_r3 = 1;
} else {
- // There isn't any space left for this field, this should not happen
- // as we have already checked
- // the overall size is not greater than 16 bytes. For now, return a
- // nullptr return value object.
+ // There isn't any space left for this field, this should not
+ // happen as we have already checked the overall size is not
+ // greater than 16 bytes. For now, return a nullptr return value
+ // object.
return return_valobj_sp;
}
}
@@ -1123,15 +1121,16 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
sucess = 1;
}
if (sucess) {
- // The result is in our data buffer. Create a variable object out of it
+ // The result is in our data buffer. Create a variable object out of
+ // it
return_valobj_sp = ValueObjectConstResult::Create(
&thread, return_compiler_type, ConstString(""), return_ext);
}
return return_valobj_sp;
}
- // Any structure/vector greater than 16 bytes in size is returned in memory.
- // The pointer to that memory is returned in r2.
+ // Any structure/vector greater than 16 bytes in size is returned in
+ // memory. The pointer to that memory is returned in r2.
uint64_t mem_address = reg_ctx->ReadRegisterAsUnsigned(
reg_ctx->GetRegisterInfoByName("r2", 0), 0);
diff --git a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
index 2fee176739f3..e93dcdbe1a59 100644
--- a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
+++ b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
@@ -402,8 +402,8 @@ bool ABISysV_ppc::GetArgumentValues(Thread &thread, ValueList &values) const {
if (!value)
return false;
- // We currently only support extracting values with Clang QualTypes.
- // Do we care about others?
+ // We currently only support extracting values with Clang QualTypes. Do we
+ // care about others?
CompilerType compiler_type = value->GetCompilerType();
if (!compiler_type)
return false;
@@ -501,8 +501,8 @@ Status ABISysV_ppc::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
if (!set_it_simple) {
// Okay we've got a structure or something that doesn't fit in a simple
- // register.
- // We should figure out where it really goes, but we don't support this yet.
+ // register. We should figure out where it really goes, but we don't
+ // support this yet.
error.SetErrorString("We only support setting simple integer and float "
"return types at present.");
}
@@ -735,10 +735,9 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectImpl(
copy_from_offset = integer_bytes - 8;
integer_bytes += field_byte_width;
} else {
- // The last field didn't fit. I can't see how that would happen w/o
- // the overall size being
- // greater than 16 bytes. For now, return a nullptr return value
- // object.
+ // The last field didn't fit. I can't see how that would happen
+ // w/o the overall size being greater than 16 bytes. For now,
+ // return a nullptr return value object.
return return_valobj_sp;
}
} else if (field_compiler_type.IsFloatingPointType(count, is_complex)) {
@@ -751,10 +750,9 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectImpl(
fp_bytes += field_byte_width;
} else if (field_bit_width == 32) {
// This one is kind of complicated. If we are in an "eightbyte"
- // with another float, we'll
- // be stuffed into an xmm register with it. If we are in an
- // "eightbyte" with one or more ints,
- // then we will be stuffed into the appropriate GPR with them.
+ // with another float, we'll be stuffed into an xmm register with
+ // it. If we are in an "eightbyte" with one or more ints, then we
+ // will be stuffed into the appropriate GPR with them.
bool in_gpr;
if (field_byte_offset % 8 == 0) {
// We are at the beginning of one of the eightbytes, so check the
@@ -776,9 +774,9 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectImpl(
}
}
} else if (field_byte_offset % 4 == 0) {
- // We are inside of an eightbyte, so see if the field before us is
- // floating point:
- // This could happen if somebody put padding in the structure.
+ // We are inside of an eightbyte, so see if the field before us
+ // is floating point: This could happen if somebody put padding
+ // in the structure.
if (idx == 0)
in_gpr = false;
else {
@@ -819,9 +817,9 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectImpl(
}
}
- // These two tests are just sanity checks. If I somehow get the
- // type calculation wrong above it is better to just return nothing
- // than to assert or crash.
+ // These two tests are just sanity checks. If I somehow get the type
+ // calculation wrong above it is better to just return nothing than to
+ // assert or crash.
if (!copy_from_extractor)
return return_valobj_sp;
if (copy_from_offset + field_byte_width >
@@ -845,9 +843,8 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectImpl(
// FIXME: This is just taking a guess, r3 may very well no longer hold the
// return storage location.
// If we are going to do this right, when we make a new frame we should
- // check to see if it uses a memory
- // return, and if we are at the first instruction and if so stash away the
- // return location. Then we would
+ // check to see if it uses a memory return, and if we are at the first
+ // instruction and if so stash away the return location. Then we would
// only return the memory return value if we know it is valid.
if (is_memory) {
@@ -918,9 +915,9 @@ bool ABISysV_ppc::RegisterIsVolatile(const RegisterInfo *reg_info) {
// See "Register Usage" in the
// "System V Application Binary Interface"
-// "64-bit PowerPC ELF Application Binary Interface Supplement"
-// current version is 1.9 released 2004 at
-// http://refspecs.linuxfoundation.org/ELF/ppc/PPC-elf64abi-1.9.pdf
+// "64-bit PowerPC ELF Application Binary Interface Supplement" current version
+// is 1.9 released 2004 at http://refspecs.linuxfoundation.org/ELF/ppc/PPC-
+// elf64abi-1.9.pdf
bool ABISysV_ppc::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
if (reg_info) {
diff --git a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
index 0348853c7fa0..d0140a0c894a 100644
--- a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
+++ b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
@@ -16,6 +16,8 @@
#include "llvm/ADT/Triple.h"
// Project includes
+#include "Utility/PPC64LE_DWARF_Registers.h"
+#include "Utility/PPC64_DWARF_Registers.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegisterValue.h"
@@ -23,6 +25,7 @@
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectMemory.h"
#include "lldb/Core/ValueObjectRegister.h"
+#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
@@ -34,201 +37,48 @@
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
-using namespace lldb;
-using namespace lldb_private;
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/Decl.h"
-enum dwarf_regnums {
- dwarf_r0 = 0,
- dwarf_r1,
- dwarf_r2,
- dwarf_r3,
- dwarf_r4,
- dwarf_r5,
- dwarf_r6,
- dwarf_r7,
- dwarf_r8,
- dwarf_r9,
- dwarf_r10,
- dwarf_r11,
- dwarf_r12,
- dwarf_r13,
- dwarf_r14,
- dwarf_r15,
- dwarf_r16,
- dwarf_r17,
- dwarf_r18,
- dwarf_r19,
- dwarf_r20,
- dwarf_r21,
- dwarf_r22,
- dwarf_r23,
- dwarf_r24,
- dwarf_r25,
- dwarf_r26,
- dwarf_r27,
- dwarf_r28,
- dwarf_r29,
- dwarf_r30,
- dwarf_r31,
- dwarf_f0,
- dwarf_f1,
- dwarf_f2,
- dwarf_f3,
- dwarf_f4,
- dwarf_f5,
- dwarf_f6,
- dwarf_f7,
- dwarf_f8,
- dwarf_f9,
- dwarf_f10,
- dwarf_f11,
- dwarf_f12,
- dwarf_f13,
- dwarf_f14,
- dwarf_f15,
- dwarf_f16,
- dwarf_f17,
- dwarf_f18,
- dwarf_f19,
- dwarf_f20,
- dwarf_f21,
- dwarf_f22,
- dwarf_f23,
- dwarf_f24,
- dwarf_f25,
- dwarf_f26,
- dwarf_f27,
- dwarf_f28,
- dwarf_f29,
- dwarf_f30,
- dwarf_f31,
- dwarf_cr,
- dwarf_fpscr,
- dwarf_xer = 101,
- dwarf_lr = 108,
- dwarf_ctr,
- dwarf_pc,
- dwarf_cfa,
-};
-
-// Note that the size and offset will be updated by platform-specific classes.
-#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
- { \
- #reg, alt, 8, 0, eEncodingUint, eFormatHex, {kind1, kind2, kind3, kind4 }, \
- nullptr, nullptr, nullptr, 0 \
- }
+#define DECLARE_REGISTER_INFOS_PPC64_STRUCT
+#include "Plugins/Process/Utility/RegisterInfos_ppc64.h"
+#undef DECLARE_REGISTER_INFOS_PPC64_STRUCT
-static const RegisterInfo g_register_infos[] = {
- // General purpose registers. eh_frame, DWARF,
- // Generic, Process Plugin
- DEFINE_GPR(r0, nullptr, dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r1, "sp", dwarf_r1, dwarf_r1, LLDB_REGNUM_GENERIC_SP,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r2, nullptr, dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r3, "arg1", dwarf_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG1,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r4, "arg2", dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG2,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r5, "arg3", dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG3,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r6, "arg4", dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG4,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r7, "arg5", dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG5,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r8, "arg6", dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG6,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r9, "arg7", dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG7,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r10, "arg8", dwarf_r10, dwarf_r10, LLDB_REGNUM_GENERIC_ARG8,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r11, nullptr, dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r12, nullptr, dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r13, nullptr, dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r14, nullptr, dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r15, nullptr, dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r16, nullptr, dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r17, nullptr, dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r18, nullptr, dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r19, nullptr, dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r20, nullptr, dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r21, nullptr, dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r22, nullptr, dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r23, nullptr, dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r24, nullptr, dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r25, nullptr, dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r26, nullptr, dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r27, nullptr, dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r28, nullptr, dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r29, nullptr, dwarf_r29, dwarf_r29, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r30, nullptr, dwarf_r30, dwarf_r30, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r31, nullptr, dwarf_r31, dwarf_r31, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(lr, "lr", dwarf_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(cr, "cr", dwarf_cr, dwarf_cr, LLDB_REGNUM_GENERIC_FLAGS,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(xer, "xer", dwarf_xer, dwarf_xer, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(ctr, "ctr", dwarf_ctr, dwarf_ctr, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(pc, "pc", dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC,
- LLDB_INVALID_REGNUM),
- {nullptr,
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {dwarf_cfa, dwarf_cfa, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0}};
+#define DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
+#include "Plugins/Process/Utility/RegisterInfos_ppc64le.h"
+#undef DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
-static const uint32_t k_num_register_infos =
- llvm::array_lengthof(g_register_infos);
+using namespace lldb;
+using namespace lldb_private;
const lldb_private::RegisterInfo *
ABISysV_ppc64::GetRegisterInfoArray(uint32_t &count) {
- count = k_num_register_infos;
- return g_register_infos;
+ if (GetByteOrder() == lldb::eByteOrderLittle) {
+ count = llvm::array_lengthof(g_register_infos_ppc64le);
+ return g_register_infos_ppc64le;
+ } else {
+ count = llvm::array_lengthof(g_register_infos_ppc64);
+ return g_register_infos_ppc64;
+ }
}
size_t ABISysV_ppc64::GetRedZoneSize() const { return 224; }
+lldb::ByteOrder ABISysV_ppc64::GetByteOrder() const {
+ return GetProcessSP()->GetByteOrder();
+}
+
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
ABISP
-ABISysV_ppc64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
- static ABISP g_abi_sp;
- if (arch.GetTriple().getArch() == llvm::Triple::ppc64) {
- if (!g_abi_sp)
- g_abi_sp.reset(new ABISysV_ppc64(process_sp));
- return g_abi_sp;
+ABISysV_ppc64::CreateInstance(lldb::ProcessSP process_sp,
+ const ArchSpec &arch) {
+ if (arch.GetTriple().getArch() == llvm::Triple::ppc64 ||
+ arch.GetTriple().getArch() == llvm::Triple::ppc64le) {
+ return ABISP(new ABISysV_ppc64(process_sp));
}
return ABISP();
}
@@ -280,28 +130,68 @@ bool ABISysV_ppc64::PrepareTrivialCall(Thread &thread, addr_t sp,
sp &= ~(0xfull); // 16-byte alignment
- sp -= 8;
+ sp -= 544; // allocate frame to save TOC, RA and SP.
Status error;
+ uint64_t reg_value;
const RegisterInfo *pc_reg_info =
reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
const RegisterInfo *sp_reg_info =
reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
ProcessSP process_sp(thread.GetProcess());
+ const RegisterInfo *lr_reg_info =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
+ const RegisterInfo *r2_reg_info = reg_ctx->GetRegisterInfoAtIndex(2);
+ const RegisterInfo *r12_reg_info = reg_ctx->GetRegisterInfoAtIndex(12);
- RegisterValue reg_value;
-
+ // Save return address onto the stack.
if (log)
log->Printf("Pushing the return address onto the stack: 0x%" PRIx64
- ": 0x%" PRIx64,
+ "(+16): 0x%" PRIx64,
(uint64_t)sp, (uint64_t)return_addr);
+ if (!process_sp->WritePointerToMemory(sp + 16, return_addr, error))
+ return false;
- // Save return address onto the stack
- if (!process_sp->WritePointerToMemory(sp, return_addr, error))
+ // Write the return address to link register.
+ if (log)
+ log->Printf("Writing LR: 0x%" PRIx64, (uint64_t)return_addr);
+ if (!reg_ctx->WriteRegisterFromUnsigned(lr_reg_info, return_addr))
return false;
- // %r1 is set to the actual stack value.
+ // Write target address to %r12 register.
+ if (log)
+ log->Printf("Writing R12: 0x%" PRIx64, (uint64_t)func_addr);
+ if (!reg_ctx->WriteRegisterFromUnsigned(r12_reg_info, func_addr))
+ return false;
+
+ // Read TOC pointer value.
+ reg_value = reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0);
+
+ // Write TOC pointer onto the stack.
+ uint64_t stack_offset;
+ if (GetByteOrder() == lldb::eByteOrderLittle)
+ stack_offset = 24;
+ else
+ stack_offset = 40;
+
+ if (log)
+ log->Printf("Writing R2 (TOC) at SP(0x%" PRIx64 ")+%d: 0x%" PRIx64,
+ (uint64_t)(sp + stack_offset), (int)stack_offset,
+ (uint64_t)reg_value);
+ if (!process_sp->WritePointerToMemory(sp + stack_offset, reg_value, error))
+ return false;
+
+ // Read the current SP value.
+ reg_value = reg_ctx->ReadRegisterAsUnsigned(sp_reg_info, 0);
+
+ // Save current SP onto the stack.
+ if (log)
+ log->Printf("Writing SP at SP(0x%" PRIx64 ")+0: 0x%" PRIx64, (uint64_t)sp,
+ (uint64_t)reg_value);
+ if (!process_sp->WritePointerToMemory(sp, reg_value, error))
+ return false;
+ // %r1 is set to the actual stack value.
if (log)
log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
@@ -365,34 +255,23 @@ bool ABISysV_ppc64::GetArgumentValues(Thread &thread, ValueList &values) const {
if (!sp)
return false;
- addr_t current_stack_argument = sp + 48; // jump over return address
+ uint64_t stack_offset;
+ if (GetByteOrder() == lldb::eByteOrderLittle)
+ stack_offset = 32;
+ else
+ stack_offset = 48;
+ // jump over return address.
+ addr_t current_stack_argument = sp + stack_offset;
uint32_t argument_register_ids[8];
- argument_register_ids[0] =
- reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)
- ->kinds[eRegisterKindLLDB];
- argument_register_ids[1] =
- reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)
- ->kinds[eRegisterKindLLDB];
- argument_register_ids[2] =
- reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)
- ->kinds[eRegisterKindLLDB];
- argument_register_ids[3] =
- reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)
- ->kinds[eRegisterKindLLDB];
- argument_register_ids[4] =
- reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5)
- ->kinds[eRegisterKindLLDB];
- argument_register_ids[5] =
- reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG6)
- ->kinds[eRegisterKindLLDB];
- argument_register_ids[6] =
- reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG7)
- ->kinds[eRegisterKindLLDB];
- argument_register_ids[7] =
- reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG8)
- ->kinds[eRegisterKindLLDB];
+ for (size_t i = 0; i < 8; ++i) {
+ argument_register_ids[i] =
+ reg_ctx
+ ->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_ARG1 + i)
+ ->kinds[eRegisterKindLLDB];
+ }
unsigned int current_argument_register = 0;
@@ -402,8 +281,8 @@ bool ABISysV_ppc64::GetArgumentValues(Thread &thread, ValueList &values) const {
if (!value)
return false;
- // We currently only support extracting values with Clang QualTypes.
- // Do we care about others?
+ // We currently only support extracting values with Clang QualTypes. Do we
+ // care about others?
CompilerType compiler_type = value->GetCompilerType();
if (!compiler_type)
return false;
@@ -501,8 +380,8 @@ Status ABISysV_ppc64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
if (!set_it_simple) {
// Okay we've got a structure or something that doesn't fit in a simple
- // register.
- // We should figure out where it really goes, but we don't support this yet.
+ // register. We should figure out where it really goes, but we don't
+ // support this yet.
error.SetErrorString("We only support setting simple integer and float "
"return types at present.");
}
@@ -510,367 +389,584 @@ Status ABISysV_ppc64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
return error;
}
-ValueObjectSP ABISysV_ppc64::GetReturnValueObjectSimple(
- Thread &thread, CompilerType &return_compiler_type) const {
- ValueObjectSP return_valobj_sp;
- Value value;
+//
+// ReturnValueExtractor
+//
- if (!return_compiler_type)
- return return_valobj_sp;
+namespace {
- // value.SetContext (Value::eContextTypeClangType, return_value_type);
- value.SetCompilerType(return_compiler_type);
+#define LOG_PREFIX "ReturnValueExtractor: "
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return return_valobj_sp;
+class ReturnValueExtractor {
+ // This class represents a register, from which data may be extracted.
+ //
+ // It may be constructed by directly specifying its index (where 0 is the
+ // first register used to return values) or by specifying the offset of a
+ // given struct field, in which case the appropriated register index will be
+ // calculated.
+ class Register {
+ public:
+ enum Type {
+ GPR, // General Purpose Register
+ FPR // Floating Point Register
+ };
- const uint32_t type_flags = return_compiler_type.GetTypeInfo();
- if (type_flags & eTypeIsScalar) {
- value.SetValueType(Value::eValueTypeScalar);
+ // main constructor
+ //
+ // offs - field offset in struct
+ Register(Type ty, uint32_t index, uint32_t offs, RegisterContext *reg_ctx,
+ ByteOrder byte_order)
+ : m_index(index), m_offs(offs % sizeof(uint64_t)),
+ m_avail(sizeof(uint64_t) - m_offs), m_type(ty), m_reg_ctx(reg_ctx),
+ m_byte_order(byte_order) {}
- bool success = false;
- if (type_flags & eTypeIsInteger) {
- // Extract the register context so we can read arguments from registers
+ // explicit index, no offset
+ Register(Type ty, uint32_t index, RegisterContext *reg_ctx,
+ ByteOrder byte_order)
+ : Register(ty, index, 0, reg_ctx, byte_order) {}
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
- uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
- reg_ctx->GetRegisterInfoByName("r3", 0), 0);
- const bool is_signed = (type_flags & eTypeIsSigned) != 0;
- switch (byte_size) {
- default:
- break;
+ // GPR, calculate index from offs
+ Register(uint32_t offs, RegisterContext *reg_ctx, ByteOrder byte_order)
+ : Register(GPR, offs / sizeof(uint64_t), offs, reg_ctx, byte_order) {}
- case sizeof(uint64_t):
- if (is_signed)
- value.GetScalar() = (int64_t)(raw_value);
- else
- value.GetScalar() = (uint64_t)(raw_value);
- success = true;
- break;
+ uint32_t Index() const { return m_index; }
- case sizeof(uint32_t):
- if (is_signed)
- value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
- else
- value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
- success = true;
- break;
+ // register offset where data is located
+ uint32_t Offs() const { return m_offs; }
- case sizeof(uint16_t):
- if (is_signed)
- value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
- else
- value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
- success = true;
- break;
+ // available bytes in this register
+ uint32_t Avail() const { return m_avail; }
- case sizeof(uint8_t):
- if (is_signed)
- value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
- else
- value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
- success = true;
- break;
+ bool IsValid() const {
+ if (m_index > 7) {
+ LLDB_LOG(m_log, LOG_PREFIX
+ "No more than 8 registers should be used to return values");
+ return false;
}
- } else if (type_flags & eTypeIsFloat) {
- if (type_flags & eTypeIsComplex) {
- // Don't handle complex yet.
- } else {
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
- if (byte_size <= sizeof(long double)) {
- const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
- RegisterValue f1_value;
- if (reg_ctx->ReadRegister(f1_info, f1_value)) {
- DataExtractor data;
- if (f1_value.GetData(data)) {
- lldb::offset_t offset = 0;
- if (byte_size == sizeof(float)) {
- value.GetScalar() = (float)data.GetFloat(&offset);
- success = true;
- } else if (byte_size == sizeof(double)) {
- value.GetScalar() = (double)data.GetDouble(&offset);
- success = true;
- }
- }
- }
- }
+ return true;
+ }
+
+ std::string GetName() const {
+ if (m_type == GPR)
+ return ("r" + llvm::Twine(m_index + 3)).str();
+ else
+ return ("f" + llvm::Twine(m_index + 1)).str();
+ }
+
+ // get raw register data
+ bool GetRawData(uint64_t &raw_data) {
+ const RegisterInfo *reg_info =
+ m_reg_ctx->GetRegisterInfoByName(GetName());
+ if (!reg_info) {
+ LLDB_LOG(m_log, LOG_PREFIX "Failed to get RegisterInfo");
+ return false;
+ }
+
+ RegisterValue reg_val;
+ if (!m_reg_ctx->ReadRegister(reg_info, reg_val)) {
+ LLDB_LOG(m_log, LOG_PREFIX "ReadRegister() failed");
+ return false;
}
+
+ Status error;
+ uint32_t rc = reg_val.GetAsMemoryData(
+ reg_info, &raw_data, sizeof(raw_data), m_byte_order, error);
+ if (rc != sizeof(raw_data)) {
+ LLDB_LOG(m_log, LOG_PREFIX "GetAsMemoryData() failed");
+ return false;
+ }
+
+ return true;
}
- if (success)
- return_valobj_sp = ValueObjectConstResult::Create(
- thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
- } else if (type_flags & eTypeIsPointer) {
- unsigned r3_id =
- reg_ctx->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB];
- value.GetScalar() =
- (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id, 0);
- value.SetValueType(Value::eValueTypeScalar);
- return_valobj_sp = ValueObjectConstResult::Create(
- thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
- } else if (type_flags & eTypeIsVector) {
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
- if (byte_size > 0) {
- const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v2", 0);
- if (altivec_reg) {
- if (byte_size <= altivec_reg->byte_size) {
- ProcessSP process_sp(thread.GetProcess());
- if (process_sp) {
- std::unique_ptr<DataBufferHeap> heap_data_ap(
- new DataBufferHeap(byte_size, 0));
- const ByteOrder byte_order = process_sp->GetByteOrder();
- RegisterValue reg_value;
- if (reg_ctx->ReadRegister(altivec_reg, reg_value)) {
- Status error;
- if (reg_value.GetAsMemoryData(
- altivec_reg, heap_data_ap->GetBytes(),
- heap_data_ap->GetByteSize(), byte_order, error)) {
- DataExtractor data(DataBufferSP(heap_data_ap.release()),
- byte_order, process_sp->GetTarget()
- .GetArchitecture()
- .GetAddressByteSize());
- return_valobj_sp = ValueObjectConstResult::Create(
- &thread, return_compiler_type, ConstString(""), data);
- }
- }
- }
+ private:
+ uint32_t m_index;
+ uint32_t m_offs;
+ uint32_t m_avail;
+ Type m_type;
+ RegisterContext *m_reg_ctx;
+ ByteOrder m_byte_order;
+ Log *m_log =
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
+ };
+
+ Register GetGPR(uint32_t index) const {
+ return Register(Register::GPR, index, m_reg_ctx, m_byte_order);
+ }
+
+ Register GetFPR(uint32_t index) const {
+ return Register(Register::FPR, index, m_reg_ctx, m_byte_order);
+ }
+
+ Register GetGPRByOffs(uint32_t offs) const {
+ return Register(offs, m_reg_ctx, m_byte_order);
+ }
+
+public:
+ // factory
+ static llvm::Expected<ReturnValueExtractor> Create(Thread &thread,
+ CompilerType &type) {
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return llvm::make_error<llvm::StringError>(
+ LOG_PREFIX "Failed to get RegisterContext",
+ llvm::inconvertibleErrorCode());
+
+ ProcessSP process_sp = thread.GetProcess();
+ if (!process_sp)
+ return llvm::make_error<llvm::StringError>(
+ LOG_PREFIX "GetProcess() failed", llvm::inconvertibleErrorCode());
+
+ return ReturnValueExtractor(thread, type, reg_ctx, process_sp);
+ }
+
+ // main method: get value of the type specified at construction time
+ ValueObjectSP GetValue() {
+ const uint32_t type_flags = m_type.GetTypeInfo();
+
+ // call the appropriate type handler
+ ValueSP value_sp;
+ ValueObjectSP valobj_sp;
+ if (type_flags & eTypeIsScalar) {
+ if (type_flags & eTypeIsInteger) {
+ value_sp = GetIntegerValue(0);
+ } else if (type_flags & eTypeIsFloat) {
+ if (type_flags & eTypeIsComplex) {
+ LLDB_LOG(m_log, LOG_PREFIX "Complex numbers are not supported yet");
+ return ValueObjectSP();
+ } else {
+ value_sp = GetFloatValue(m_type, 0);
}
}
+ } else if (type_flags & eTypeIsPointer) {
+ value_sp = GetPointerValue(0);
+ }
+
+ if (value_sp) {
+ valobj_sp = ValueObjectConstResult::Create(
+ m_thread.GetStackFrameAtIndex(0).get(), *value_sp, ConstString(""));
+ } else if (type_flags & eTypeIsVector) {
+ valobj_sp = GetVectorValueObject();
+ } else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass) {
+ valobj_sp = GetStructValueObject();
}
+
+ return valobj_sp;
}
- return return_valobj_sp;
-}
+private:
+ // data
+ Thread &m_thread;
+ CompilerType &m_type;
+ uint64_t m_byte_size;
+ std::unique_ptr<DataBufferHeap> m_data_ap;
+ int32_t m_src_offs = 0;
+ int32_t m_dst_offs = 0;
+ bool m_packed = false;
+ Log *m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
+ RegisterContext *m_reg_ctx;
+ ProcessSP m_process_sp;
+ ByteOrder m_byte_order;
+ uint32_t m_addr_size;
-ValueObjectSP ABISysV_ppc64::GetReturnValueObjectImpl(
- Thread &thread, CompilerType &return_compiler_type) const {
- ValueObjectSP return_valobj_sp;
+ // methods
- if (!return_compiler_type)
- return return_valobj_sp;
+ // constructor
+ ReturnValueExtractor(Thread &thread, CompilerType &type,
+ RegisterContext *reg_ctx, ProcessSP process_sp)
+ : m_thread(thread), m_type(type),
+ m_byte_size(m_type.GetByteSize(nullptr)),
+ m_data_ap(new DataBufferHeap(m_byte_size, 0)), m_reg_ctx(reg_ctx),
+ m_process_sp(process_sp), m_byte_order(process_sp->GetByteOrder()),
+ m_addr_size(
+ process_sp->GetTarget().GetArchitecture().GetAddressByteSize()) {}
- ExecutionContext exe_ctx(thread.shared_from_this());
- return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
- if (return_valobj_sp)
- return return_valobj_sp;
+ // build a new scalar value
+ ValueSP NewScalarValue(CompilerType &type) {
+ ValueSP value_sp(new Value);
+ value_sp->SetCompilerType(type);
+ value_sp->SetValueType(Value::eValueTypeScalar);
+ return value_sp;
+ }
+
+ // get an integer value in the specified register
+ ValueSP GetIntegerValue(uint32_t reg_index) {
+ uint64_t raw_value;
+ auto reg = GetGPR(reg_index);
+ if (!reg.GetRawData(raw_value))
+ return ValueSP();
- RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
- if (!reg_ctx_sp)
- return return_valobj_sp;
+ // build value from data
+ ValueSP value_sp(NewScalarValue(m_type));
- const size_t bit_width = return_compiler_type.GetBitSize(&thread);
- if (return_compiler_type.IsAggregateType()) {
- Target *target = exe_ctx.GetTargetPtr();
- bool is_memory = true;
- if (bit_width <= 128) {
- ByteOrder target_byte_order = target->GetArchitecture().GetByteOrder();
- DataBufferSP data_sp(new DataBufferHeap(16, 0));
- DataExtractor return_ext(data_sp, target_byte_order,
- target->GetArchitecture().GetAddressByteSize());
+ uint32_t type_flags = m_type.GetTypeInfo();
+ bool is_signed = (type_flags & eTypeIsSigned) != 0;
- const RegisterInfo *r3_info = reg_ctx_sp->GetRegisterInfoByName("r3", 0);
- const RegisterInfo *rdx_info =
- reg_ctx_sp->GetRegisterInfoByName("rdx", 0);
+ switch (m_byte_size) {
+ case sizeof(uint64_t):
+ if (is_signed)
+ value_sp->GetScalar() = (int64_t)(raw_value);
+ else
+ value_sp->GetScalar() = (uint64_t)(raw_value);
+ break;
- RegisterValue r3_value, rdx_value;
- reg_ctx_sp->ReadRegister(r3_info, r3_value);
- reg_ctx_sp->ReadRegister(rdx_info, rdx_value);
+ case sizeof(uint32_t):
+ if (is_signed)
+ value_sp->GetScalar() = (int32_t)(raw_value & UINT32_MAX);
+ else
+ value_sp->GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
+ break;
- DataExtractor r3_data, rdx_data;
+ case sizeof(uint16_t):
+ if (is_signed)
+ value_sp->GetScalar() = (int16_t)(raw_value & UINT16_MAX);
+ else
+ value_sp->GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
+ break;
- r3_value.GetData(r3_data);
- rdx_value.GetData(rdx_data);
+ case sizeof(uint8_t):
+ if (is_signed)
+ value_sp->GetScalar() = (int8_t)(raw_value & UINT8_MAX);
+ else
+ value_sp->GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
+ break;
- uint32_t fp_bytes =
- 0; // Tracks how much of the xmm registers we've consumed so far
- uint32_t integer_bytes =
- 0; // Tracks how much of the r3/rds registers we've consumed so far
+ default:
+ llvm_unreachable("Invalid integer size");
+ }
+
+ return value_sp;
+ }
- const uint32_t num_children = return_compiler_type.GetNumFields();
+ // get a floating point value on the specified register
+ ValueSP GetFloatValue(CompilerType &type, uint32_t reg_index) {
+ uint64_t raw_data;
+ auto reg = GetFPR(reg_index);
+ if (!reg.GetRawData(raw_data))
+ return ValueSP();
- // Since we are in the small struct regime, assume we are not in memory.
- is_memory = false;
+ // build value from data
+ ValueSP value_sp(NewScalarValue(type));
- for (uint32_t idx = 0; idx < num_children; idx++) {
- std::string name;
- uint64_t field_bit_offset = 0;
- bool is_signed;
- bool is_complex;
- uint32_t count;
+ DataExtractor de(&raw_data, sizeof(raw_data), m_byte_order, m_addr_size);
- CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(
- idx, name, &field_bit_offset, nullptr, nullptr);
- const size_t field_bit_width = field_compiler_type.GetBitSize(&thread);
+ offset_t offset = 0;
+ size_t byte_size = type.GetByteSize(nullptr);
+ switch (byte_size) {
+ case sizeof(float):
+ value_sp->GetScalar() = (float)de.GetDouble(&offset);
+ break;
- // If there are any unaligned fields, this is stored in memory.
- if (field_bit_offset % field_bit_width != 0) {
- is_memory = true;
- break;
+ case sizeof(double):
+ value_sp->GetScalar() = de.GetDouble(&offset);
+ break;
+
+ default:
+ llvm_unreachable("Invalid floating point size");
+ }
+
+ return value_sp;
+ }
+
+ // get pointer value from register
+ ValueSP GetPointerValue(uint32_t reg_index) {
+ uint64_t raw_data;
+ auto reg = GetGPR(reg_index);
+ if (!reg.GetRawData(raw_data))
+ return ValueSP();
+
+ // build value from raw data
+ ValueSP value_sp(NewScalarValue(m_type));
+ value_sp->GetScalar() = raw_data;
+ return value_sp;
+ }
+
+ // build the ValueObject from our data buffer
+ ValueObjectSP BuildValueObject() {
+ DataExtractor de(DataBufferSP(m_data_ap.release()), m_byte_order,
+ m_addr_size);
+ return ValueObjectConstResult::Create(&m_thread, m_type, ConstString(""),
+ de);
+ }
+
+ // get a vector return value
+ ValueObjectSP GetVectorValueObject() {
+ const uint32_t MAX_VRS = 2;
+
+ // get first V register used to return values
+ const RegisterInfo *vr[MAX_VRS];
+ vr[0] = m_reg_ctx->GetRegisterInfoByName("vr2");
+ if (!vr[0]) {
+ LLDB_LOG(m_log, LOG_PREFIX "Failed to get vr2 RegisterInfo");
+ return ValueObjectSP();
+ }
+
+ const uint32_t vr_size = vr[0]->byte_size;
+ size_t vrs = 1;
+ if (m_byte_size > 2 * vr_size) {
+ LLDB_LOG(
+ m_log, LOG_PREFIX
+ "Returning vectors that don't fit in 2 VR regs is not supported");
+ return ValueObjectSP();
+ }
+
+ // load vr3, if needed
+ if (m_byte_size > vr_size) {
+ vrs++;
+ vr[1] = m_reg_ctx->GetRegisterInfoByName("vr3");
+ if (!vr[1]) {
+ LLDB_LOG(m_log, LOG_PREFIX "Failed to get vr3 RegisterInfo");
+ return ValueObjectSP();
+ }
+ }
+
+ // Get the whole contents of vector registers and let the logic here
+ // arrange the data properly.
+
+ RegisterValue vr_val[MAX_VRS];
+ Status error;
+ std::unique_ptr<DataBufferHeap> vr_data(
+ new DataBufferHeap(vrs * vr_size, 0));
+
+ for (uint32_t i = 0; i < vrs; i++) {
+ if (!m_reg_ctx->ReadRegister(vr[i], vr_val[i])) {
+ LLDB_LOG(m_log, LOG_PREFIX "Failed to read vector register contents");
+ return ValueObjectSP();
+ }
+ if (!vr_val[i].GetAsMemoryData(vr[i], vr_data->GetBytes() + i * vr_size,
+ vr_size, m_byte_order, error)) {
+ LLDB_LOG(m_log, LOG_PREFIX "Failed to extract vector register bytes");
+ return ValueObjectSP();
+ }
+ }
+
+ // The compiler generated code seems to always put the vector elements at
+ // the end of the vector register, in case they don't occupy all of it.
+ // This offset variable handles this.
+ uint32_t offs = 0;
+ if (m_byte_size < vr_size)
+ offs = vr_size - m_byte_size;
+
+ // copy extracted data to our buffer
+ memcpy(m_data_ap->GetBytes(), vr_data->GetBytes() + offs, m_byte_size);
+ return BuildValueObject();
+ }
+
+ // get a struct return value
+ ValueObjectSP GetStructValueObject() {
+ // case 1: get from stack
+ if (m_byte_size > 2 * sizeof(uint64_t)) {
+ uint64_t addr;
+ auto reg = GetGPR(0);
+ if (!reg.GetRawData(addr))
+ return ValueObjectSP();
+
+ Status error;
+ size_t rc = m_process_sp->ReadMemory(addr, m_data_ap->GetBytes(),
+ m_byte_size, error);
+ if (rc != m_byte_size) {
+ LLDB_LOG(m_log, LOG_PREFIX "Failed to read memory pointed by r3");
+ return ValueObjectSP();
+ }
+ return BuildValueObject();
+ }
+
+ // get number of children
+ const bool omit_empty_base_classes = true;
+ uint32_t n = m_type.GetNumChildren(omit_empty_base_classes);
+ if (!n) {
+ LLDB_LOG(m_log, LOG_PREFIX "No children found in struct");
+ return ValueObjectSP();
+ }
+
+ // case 2: homogeneous double or float aggregate
+ CompilerType elem_type;
+ if (m_type.IsHomogeneousAggregate(&elem_type)) {
+ uint32_t type_flags = elem_type.GetTypeInfo();
+ uint64_t elem_size = elem_type.GetByteSize(nullptr);
+ if (type_flags & eTypeIsComplex || !(type_flags & eTypeIsFloat)) {
+ LLDB_LOG(m_log,
+ LOG_PREFIX "Unexpected type found in homogeneous aggregate");
+ return ValueObjectSP();
+ }
+
+ for (uint32_t i = 0; i < n; i++) {
+ ValueSP val_sp = GetFloatValue(elem_type, i);
+ if (!val_sp)
+ return ValueObjectSP();
+
+ // copy to buffer
+ Status error;
+ size_t rc = val_sp->GetScalar().GetAsMemoryData(
+ m_data_ap->GetBytes() + m_dst_offs, elem_size, m_byte_order, error);
+ if (rc != elem_size) {
+ LLDB_LOG(m_log, LOG_PREFIX "Failed to get float data");
+ return ValueObjectSP();
}
+ m_dst_offs += elem_size;
+ }
+ return BuildValueObject();
+ }
- uint32_t field_byte_width = field_bit_width / 8;
- uint32_t field_byte_offset = field_bit_offset / 8;
+ // case 3: get from GPRs
- DataExtractor *copy_from_extractor = nullptr;
- uint32_t copy_from_offset = 0;
+ // first, check if this is a packed struct or not
+ ClangASTContext *ast =
+ llvm::dyn_cast<ClangASTContext>(m_type.GetTypeSystem());
+ if (ast) {
+ clang::RecordDecl *record_decl = ClangASTContext::GetAsRecordDecl(m_type);
- if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
- field_compiler_type.IsPointerType()) {
- if (integer_bytes < 8) {
- if (integer_bytes + field_byte_width <= 8) {
- // This is in RAX, copy from register to our result structure:
- copy_from_extractor = &r3_data;
- copy_from_offset = integer_bytes;
- integer_bytes += field_byte_width;
- } else {
- // The next field wouldn't fit in the remaining space, so we
- // pushed it to rdx.
- copy_from_extractor = &rdx_data;
- copy_from_offset = 0;
- integer_bytes = 8 + field_byte_width;
- }
- } else if (integer_bytes + field_byte_width <= 16) {
- copy_from_extractor = &rdx_data;
- copy_from_offset = integer_bytes - 8;
- integer_bytes += field_byte_width;
- } else {
- // The last field didn't fit. I can't see how that would happen w/o
- // the overall size being
- // greater than 16 bytes. For now, return a nullptr return value
- // object.
- return return_valobj_sp;
- }
- } else if (field_compiler_type.IsFloatingPointType(count, is_complex)) {
- // Structs with long doubles are always passed in memory.
- if (field_bit_width == 128) {
- is_memory = true;
+ if (record_decl) {
+ auto attrs = record_decl->attrs();
+ for (const auto &attr : attrs) {
+ if (attr->getKind() == clang::attr::Packed) {
+ m_packed = true;
break;
- } else if (field_bit_width == 64) {
- copy_from_offset = 0;
- fp_bytes += field_byte_width;
- } else if (field_bit_width == 32) {
- // This one is kind of complicated. If we are in an "eightbyte"
- // with another float, we'll
- // be stuffed into an xmm register with it. If we are in an
- // "eightbyte" with one or more ints,
- // then we will be stuffed into the appropriate GPR with them.
- bool in_gpr;
- if (field_byte_offset % 8 == 0) {
- // We are at the beginning of one of the eightbytes, so check the
- // next element (if any)
- if (idx == num_children - 1)
- in_gpr = false;
- else {
- uint64_t next_field_bit_offset = 0;
- CompilerType next_field_compiler_type =
- return_compiler_type.GetFieldAtIndex(idx + 1, name,
- &next_field_bit_offset,
- nullptr, nullptr);
- if (next_field_compiler_type.IsIntegerOrEnumerationType(
- is_signed))
- in_gpr = true;
- else {
- copy_from_offset = 0;
- in_gpr = false;
- }
- }
- } else if (field_byte_offset % 4 == 0) {
- // We are inside of an eightbyte, so see if the field before us is
- // floating point:
- // This could happen if somebody put padding in the structure.
- if (idx == 0)
- in_gpr = false;
- else {
- uint64_t prev_field_bit_offset = 0;
- CompilerType prev_field_compiler_type =
- return_compiler_type.GetFieldAtIndex(idx - 1, name,
- &prev_field_bit_offset,
- nullptr, nullptr);
- if (prev_field_compiler_type.IsIntegerOrEnumerationType(
- is_signed))
- in_gpr = true;
- else {
- copy_from_offset = 4;
- in_gpr = false;
- }
- }
- } else {
- is_memory = true;
- continue;
- }
-
- // Okay, we've figured out whether we are in GPR or XMM, now figure
- // out which one.
- if (in_gpr) {
- if (integer_bytes < 8) {
- // This is in RAX, copy from register to our result structure:
- copy_from_extractor = &r3_data;
- copy_from_offset = integer_bytes;
- integer_bytes += field_byte_width;
- } else {
- copy_from_extractor = &rdx_data;
- copy_from_offset = integer_bytes - 8;
- integer_bytes += field_byte_width;
- }
- } else {
- fp_bytes += field_byte_width;
- }
}
}
+ }
+ }
- // These two tests are just sanity checks. If I somehow get the
- // type calculation wrong above it is better to just return nothing
- // than to assert or crash.
- if (!copy_from_extractor)
- return return_valobj_sp;
- if (copy_from_offset + field_byte_width >
- copy_from_extractor->GetByteSize())
- return return_valobj_sp;
+ LLDB_LOG(m_log, LOG_PREFIX "{0} struct",
+ m_packed ? "packed" : "not packed");
- copy_from_extractor->CopyByteOrderedData(
- copy_from_offset, field_byte_width,
- data_sp->GetBytes() + field_byte_offset, field_byte_width,
- target_byte_order);
- }
+ for (uint32_t i = 0; i < n; i++) {
+ std::string name;
+ uint32_t size;
+ GetChildType(i, name, size);
+ // NOTE: the offset returned by GetChildCompilerTypeAtIndex()
+ // can't be used because it never considers alignment bytes
+ // between struct fields.
+ LLDB_LOG(m_log, LOG_PREFIX "field={0}, size={1}", name, size);
+ if (!ExtractField(size))
+ return ValueObjectSP();
+ }
- if (!is_memory) {
- // The result is in our data buffer. Let's make a variable object out
- // of it:
- return_valobj_sp = ValueObjectConstResult::Create(
- &thread, return_compiler_type, ConstString(""), return_ext);
- }
+ return BuildValueObject();
+ }
+
+ // extract 'size' bytes at 'offs' from GPRs
+ bool ExtractFromRegs(int32_t offs, uint32_t size, void *buf) {
+ while (size) {
+ auto reg = GetGPRByOffs(offs);
+ if (!reg.IsValid())
+ return false;
+
+ uint32_t n = std::min(reg.Avail(), size);
+ uint64_t raw_data;
+
+ if (!reg.GetRawData(raw_data))
+ return false;
+
+ memcpy(buf, (char *)&raw_data + reg.Offs(), n);
+ offs += n;
+ size -= n;
+ buf = (char *)buf + n;
}
+ return true;
+ }
+
+ // extract one field from GPRs and put it in our buffer
+ bool ExtractField(uint32_t size) {
+ auto reg = GetGPRByOffs(m_src_offs);
+ if (!reg.IsValid())
+ return false;
- // FIXME: This is just taking a guess, r3 may very well no longer hold the
- // return storage location.
- // If we are going to do this right, when we make a new frame we should
- // check to see if it uses a memory
- // return, and if we are at the first instruction and if so stash away the
- // return location. Then we would
- // only return the memory return value if we know it is valid.
+ // handle padding
+ if (!m_packed) {
+ uint32_t n = m_src_offs % size;
- if (is_memory) {
- unsigned r3_id =
- reg_ctx_sp->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB];
- lldb::addr_t storage_addr =
- (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id,
- 0);
- return_valobj_sp = ValueObjectMemory::Create(
- &thread, "", Address(storage_addr, nullptr), return_compiler_type);
+ // not 'size' bytes aligned
+ if (n) {
+ LLDB_LOG(m_log,
+ LOG_PREFIX "Extracting {0} alignment bytes at offset {1}", n,
+ m_src_offs);
+ // get alignment bytes
+ if (!ExtractFromRegs(m_src_offs, n, m_data_ap->GetBytes() + m_dst_offs))
+ return false;
+ m_src_offs += n;
+ m_dst_offs += n;
+ }
}
+
+ // get field
+ LLDB_LOG(m_log, LOG_PREFIX "Extracting {0} field bytes at offset {1}", size,
+ m_src_offs);
+ if (!ExtractFromRegs(m_src_offs, size, m_data_ap->GetBytes() + m_dst_offs))
+ return false;
+ m_src_offs += size;
+ m_dst_offs += size;
+ return true;
}
- return return_valobj_sp;
+ // get child
+ CompilerType GetChildType(uint32_t i, std::string &name, uint32_t &size) {
+ // GetChild constant inputs
+ const bool transparent_pointers = false;
+ const bool omit_empty_base_classes = true;
+ const bool ignore_array_bounds = false;
+ // GetChild output params
+ int32_t child_offs;
+ uint32_t child_bitfield_bit_size;
+ uint32_t child_bitfield_bit_offset;
+ bool child_is_base_class;
+ bool child_is_deref_of_parent;
+ ValueObject *valobj = nullptr;
+ uint64_t language_flags;
+ ExecutionContext exe_ctx;
+ m_thread.CalculateExecutionContext(exe_ctx);
+
+ return m_type.GetChildCompilerTypeAtIndex(
+ &exe_ctx, i, transparent_pointers, omit_empty_base_classes,
+ ignore_array_bounds, name, size, child_offs, child_bitfield_bit_size,
+ child_bitfield_bit_offset, child_is_base_class,
+ child_is_deref_of_parent, valobj, language_flags);
+ }
+};
+
+#undef LOG_PREFIX
+
+} // anonymous namespace
+
+ValueObjectSP
+ABISysV_ppc64::GetReturnValueObjectSimple(Thread &thread,
+ CompilerType &type) const {
+ if (!type)
+ return ValueObjectSP();
+
+ auto exp_extractor = ReturnValueExtractor::Create(thread, type);
+ if (!exp_extractor) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
+ LLDB_LOG_ERROR(log, exp_extractor.takeError(),
+ "Extracting return value failed: {0}");
+ return ValueObjectSP();
+ }
+
+ return exp_extractor.get().GetValue();
+}
+
+ValueObjectSP ABISysV_ppc64::GetReturnValueObjectImpl(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ return GetReturnValueObjectSimple(thread, return_compiler_type);
}
bool ABISysV_ppc64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.Clear();
unwind_plan.SetRegisterKind(eRegisterKindDWARF);
- uint32_t lr_reg_num = dwarf_lr;
- uint32_t sp_reg_num = dwarf_r1;
- uint32_t pc_reg_num = dwarf_pc;
+ uint32_t lr_reg_num;
+ uint32_t sp_reg_num;
+ uint32_t pc_reg_num;
+
+ if (GetByteOrder() == lldb::eByteOrderLittle) {
+ lr_reg_num = ppc64le_dwarf::dwarf_lr_ppc64le;
+ sp_reg_num = ppc64le_dwarf::dwarf_r1_ppc64le;
+ pc_reg_num = ppc64le_dwarf::dwarf_pc_ppc64le;
+ } else {
+ lr_reg_num = ppc64_dwarf::dwarf_lr_ppc64;
+ sp_reg_num = ppc64_dwarf::dwarf_r1_ppc64;
+ pc_reg_num = ppc64_dwarf::dwarf_pc_ppc64;
+ }
UnwindPlan::RowSP row(new UnwindPlan::Row);
@@ -893,23 +989,33 @@ bool ABISysV_ppc64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.Clear();
unwind_plan.SetRegisterKind(eRegisterKindDWARF);
- uint32_t sp_reg_num = dwarf_r1;
- uint32_t pc_reg_num = dwarf_lr;
+ uint32_t sp_reg_num;
+ uint32_t pc_reg_num;
+ uint32_t cr_reg_num;
- UnwindPlan::RowSP row(new UnwindPlan::Row);
+ if (GetByteOrder() == lldb::eByteOrderLittle) {
+ sp_reg_num = ppc64le_dwarf::dwarf_r1_ppc64le;
+ pc_reg_num = ppc64le_dwarf::dwarf_lr_ppc64le;
+ cr_reg_num = ppc64le_dwarf::dwarf_cr_ppc64le;
+ } else {
+ sp_reg_num = ppc64_dwarf::dwarf_r1_ppc64;
+ pc_reg_num = ppc64_dwarf::dwarf_lr_ppc64;
+ cr_reg_num = ppc64_dwarf::dwarf_cr_ppc64;
+ }
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
const int32_t ptr_size = 8;
row->GetCFAValue().SetIsRegisterDereferenced(sp_reg_num);
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * 2, true);
row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
- row->SetRegisterLocationToAtCFAPlusOffset(dwarf_cr, ptr_size, true);
+ row->SetRegisterLocationToAtCFAPlusOffset(cr_reg_num, ptr_size, true);
unwind_plan.AppendRow(row);
unwind_plan.SetSourceName("ppc64 default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
- unwind_plan.SetReturnAddressRegister(dwarf_lr);
+ unwind_plan.SetReturnAddressRegister(pc_reg_num);
return true;
}
@@ -919,10 +1025,9 @@ bool ABISysV_ppc64::RegisterIsVolatile(const RegisterInfo *reg_info) {
// See "Register Usage" in the
// "System V Application Binary Interface"
-// "64-bit PowerPC ELF Application Binary Interface Supplement"
-// current version is 1.9 released 2004 at
-// http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.pdf
-
+// "64-bit PowerPC ELF Application Binary Interface Supplement" current version
+// is 2 released 2015 at
+// https://members.openpowerfoundation.org/document/dl/576
bool ABISysV_ppc64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
if (reg_info) {
// Preserved registers are :
@@ -954,7 +1059,7 @@ bool ABISysV_ppc64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
return true;
if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
- return true;
+ return false;
if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
return true;
}
diff --git a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h
index 21608a5c1cdd..52765a773c0b 100644
--- a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h
+++ b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h
@@ -108,6 +108,8 @@ private:
ABISysV_ppc64(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
// Call CreateInstance instead.
}
+
+ lldb::ByteOrder GetByteOrder() const;
};
#endif // liblldb_ABISysV_ppc64_h_
diff --git a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp
index 967e407188fa..31e2825c0fa2 100644
--- a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp
+++ b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp
@@ -380,8 +380,8 @@ bool ABISysV_s390x::GetArgumentValues(Thread &thread, ValueList &values) const {
if (!value)
return false;
- // We currently only support extracting values with Clang QualTypes.
- // Do we care about others?
+ // We currently only support extracting values with Clang QualTypes. Do we
+ // care about others?
CompilerType compiler_type = value->GetCompilerType();
if (!compiler_type)
return false;
@@ -483,8 +483,8 @@ Status ABISysV_s390x::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
if (!set_it_simple) {
// Okay we've got a structure or something that doesn't fit in a simple
- // register.
- // We should figure out where it really goes, but we don't support this yet.
+ // register. We should figure out where it really goes, but we don't
+ // support this yet.
error.SetErrorString("We only support setting simple integer and float "
"return types at present.");
}
@@ -618,9 +618,8 @@ ValueObjectSP ABISysV_s390x::GetReturnValueObjectImpl(
// FIXME: This is just taking a guess, r2 may very well no longer hold the
// return storage location.
// If we are going to do this right, when we make a new frame we should
- // check to see if it uses a memory
- // return, and if we are at the first instruction and if so stash away the
- // return location. Then we would
+ // check to see if it uses a memory return, and if we are at the first
+ // instruction and if so stash away the return location. Then we would
// only return the memory return value if we know it is valid.
unsigned r2_id =
@@ -654,8 +653,8 @@ bool ABISysV_s390x::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
}
bool ABISysV_s390x::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
- // There's really no default way to unwind on s390x.
- // Trust the .eh_frame CFI, which should always be good.
+ // There's really no default way to unwind on s390x. Trust the .eh_frame CFI,
+ // which should always be good.
return false;
}
@@ -663,8 +662,8 @@ bool ABISysV_s390x::GetFallbackRegisterLocation(
const RegisterInfo *reg_info,
UnwindPlan::Row::RegisterLocation &unwind_regloc) {
// If a volatile register is being requested, we don't want to forward the
- // next frame's register contents
- // up the stack -- the register is not retrievable at this frame.
+ // next frame's register contents up the stack -- the register is not
+ // retrievable at this frame.
if (RegisterIsVolatile(reg_info)) {
unwind_regloc.SetUndefined();
return true;
diff --git a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
index 41d146f24526..36ae3a49827c 100644
--- a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
+++ b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
@@ -1267,8 +1267,8 @@ bool ABISysV_x86_64::GetArgumentValues(Thread &thread,
if (!value)
return false;
- // We currently only support extracting values with Clang QualTypes.
- // Do we care about others?
+ // We currently only support extracting values with Clang QualTypes. Do we
+ // care about others?
CompilerType compiler_type = value->GetCompilerType();
if (!compiler_type)
return false;
@@ -1371,8 +1371,8 @@ Status ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
if (!set_it_simple) {
// Okay we've got a structure or something that doesn't fit in a simple
- // register.
- // We should figure out where it really goes, but we don't support this yet.
+ // register. We should figure out where it really goes, but we don't
+ // support this yet.
error.SetErrorString("We only support setting simple integer and float "
"return types at present.");
}
@@ -1624,8 +1624,8 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectImpl(
idx, name, &field_bit_offset, nullptr, nullptr);
const size_t field_bit_width = field_compiler_type.GetBitSize(&thread);
- // if we don't know the size of the field (e.g. invalid type), just bail
- // out
+ // if we don't know the size of the field (e.g. invalid type), just
+ // bail out
if (field_bit_width == 0)
break;
@@ -1661,10 +1661,9 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectImpl(
copy_from_offset = integer_bytes - 8;
integer_bytes += field_byte_width;
} else {
- // The last field didn't fit. I can't see how that would happen w/o
- // the overall size being
- // greater than 16 bytes. For now, return a nullptr return value
- // object.
+ // The last field didn't fit. I can't see how that would happen
+ // w/o the overall size being greater than 16 bytes. For now,
+ // return a nullptr return value object.
return return_valobj_sp;
}
} else if (field_compiler_type.IsFloatingPointType(count, is_complex)) {
@@ -1683,10 +1682,9 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectImpl(
fp_bytes += field_byte_width;
} else if (field_bit_width == 32) {
// This one is kind of complicated. If we are in an "eightbyte"
- // with another float, we'll
- // be stuffed into an xmm register with it. If we are in an
- // "eightbyte" with one or more ints,
- // then we will be stuffed into the appropriate GPR with them.
+ // with another float, we'll be stuffed into an xmm register with
+ // it. If we are in an "eightbyte" with one or more ints, then we
+ // will be stuffed into the appropriate GPR with them.
bool in_gpr;
if (field_byte_offset % 8 == 0) {
// We are at the beginning of one of the eightbytes, so check the
@@ -1708,9 +1706,9 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectImpl(
}
}
} else if (field_byte_offset % 4 == 0) {
- // We are inside of an eightbyte, so see if the field before us is
- // floating point:
- // This could happen if somebody put padding in the structure.
+ // We are inside of an eightbyte, so see if the field before us
+ // is floating point: This could happen if somebody put padding
+ // in the structure.
if (idx == 0)
in_gpr = false;
else {
@@ -1756,9 +1754,9 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectImpl(
}
}
- // These two tests are just sanity checks. If I somehow get the
- // type calculation wrong above it is better to just return nothing
- // than to assert or crash.
+ // These two tests are just sanity checks. If I somehow get the type
+ // calculation wrong above it is better to just return nothing than to
+ // assert or crash.
if (!copy_from_extractor)
return return_valobj_sp;
if (copy_from_offset + field_byte_width >
@@ -1782,9 +1780,8 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectImpl(
// FIXME: This is just taking a guess, rax may very well no longer hold the
// return storage location.
// If we are going to do this right, when we make a new frame we should
- // check to see if it uses a memory
- // return, and if we are at the first instruction and if so stash away the
- // return location. Then we would
+ // check to see if it uses a memory return, and if we are at the first
+ // instruction and if so stash away the return location. Then we would
// only return the memory return value if we know it is valid.
if (is_memory) {
@@ -1858,12 +1855,11 @@ bool ABISysV_x86_64::RegisterIsVolatile(const RegisterInfo *reg_info) {
// See "Register Usage" in the
// "System V Application Binary Interface"
-// "AMD64 Architecture Processor Supplement"
-// (or "x86-64(tm) Architecture Processor Supplement" in earlier revisions)
-// (this doc is also commonly referred to as the x86-64/AMD64 psABI)
-// Edited by Michael Matz, Jan Hubicka, Andreas Jaeger, and Mark Mitchell
-// current version is 0.99.6 released 2012-07-02 at
-// http://refspecs.linuxfoundation.org/elf/x86-64-abi-0.99.pdf
+// "AMD64 Architecture Processor Supplement" (or "x86-64(tm) Architecture
+// Processor Supplement" in earlier revisions) (this doc is also commonly
+// referred to as the x86-64/AMD64 psABI) Edited by Michael Matz, Jan Hubicka,
+// Andreas Jaeger, and Mark Mitchell current version is 0.99.6 released
+// 2012-07-02 at http://refspecs.linuxfoundation.org/elf/x86-64-abi-0.99.pdf
// It's being revised & updated at https://github.com/hjl-tools/x86-psABI/
bool ABISysV_x86_64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
diff --git a/source/Plugins/Architecture/Arm/ArchitectureArm.cpp b/source/Plugins/Architecture/Arm/ArchitectureArm.cpp
index abac6d3001af..1b7ecc88c35e 100644
--- a/source/Plugins/Architecture/Arm/ArchitectureArm.cpp
+++ b/source/Plugins/Architecture/Arm/ArchitectureArm.cpp
@@ -41,32 +41,32 @@ std::unique_ptr<Architecture> ArchitectureArm::Create(const ArchSpec &arch) {
ConstString ArchitectureArm::GetPluginName() { return GetPluginNameStatic(); }
uint32_t ArchitectureArm::GetPluginVersion() { return 1; }
-void ArchitectureArm::OverrideStopInfo(Thread &thread) {
- // We need to check if we are stopped in Thumb mode in a IT instruction
- // and detect if the condition doesn't pass. If this is the case it means
- // we won't actually execute this instruction. If this happens we need to
- // clear the stop reason to no thread plans think we are stopped for a
- // reason and the plans should keep going.
+void ArchitectureArm::OverrideStopInfo(Thread &thread) const {
+ // We need to check if we are stopped in Thumb mode in a IT instruction and
+ // detect if the condition doesn't pass. If this is the case it means we
+ // won't actually execute this instruction. If this happens we need to clear
+ // the stop reason to no thread plans think we are stopped for a reason and
+ // the plans should keep going.
//
// We do this because when single stepping many ARM processes, debuggers
- // often use the BVR/BCR registers that says "stop when the PC is not
- // equal to its current value". This method of stepping means we can end
- // up stopping on instructions inside an if/then block that wouldn't get
- // executed. By fixing this we can stop the debugger from seeming like
- // you stepped through both the "if" _and_ the "else" clause when source
- // level stepping because the debugger stops regardless due to the BVR/BCR
+ // often use the BVR/BCR registers that says "stop when the PC is not equal
+ // to its current value". This method of stepping means we can end up
+ // stopping on instructions inside an if/then block that wouldn't get
+ // executed. By fixing this we can stop the debugger from seeming like you
+ // stepped through both the "if" _and_ the "else" clause when source level
+ // stepping because the debugger stops regardless due to the BVR/BCR
// triggering a stop.
//
- // It also means we can set breakpoints on instructions inside an an
- // if/then block and correctly skip them if we use the BKPT instruction.
- // The ARM and Thumb BKPT instructions are unconditional even when executed
- // in a Thumb IT block.
+ // It also means we can set breakpoints on instructions inside an an if/then
+ // block and correctly skip them if we use the BKPT instruction. The ARM and
+ // Thumb BKPT instructions are unconditional even when executed in a Thumb IT
+ // block.
//
- // If your debugger inserts software traps in ARM/Thumb code, it will
- // need to use 16 and 32 bit instruction for 16 and 32 bit thumb
- // instructions respectively. If your debugger inserts a 16 bit thumb
- // trap on top of a 32 bit thumb instruction for an opcode that is inside
- // an if/then, it will change the it/then to conditionally execute your
+ // If your debugger inserts software traps in ARM/Thumb code, it will need to
+ // use 16 and 32 bit instruction for 16 and 32 bit thumb instructions
+ // respectively. If your debugger inserts a 16 bit thumb trap on top of a 32
+ // bit thumb instruction for an opcode that is inside an if/then, it will
+ // change the it/then to conditionally execute your
// 16 bit trap and then cause your program to crash if it executes the
// trailing 16 bits (the second half of the 32 bit thumb instruction you
// partially overwrote).
@@ -85,23 +85,20 @@ void ArchitectureArm::OverrideStopInfo(Thread &thread) {
const uint32_t ISETSTATE = J << 1 | T;
if (ISETSTATE == 0) {
// NOTE: I am pretty sure we want to enable the code below
-// that detects when we stop on an instruction in ARM mode
-// that is conditional and the condition doesn't pass. This
-// can happen if you set a breakpoint on an instruction that
-// is conditional. We currently will _always_ stop on the
-// instruction which is bad. You can also run into this while
-// single stepping and you could appear to run code in the "if"
-// and in the "else" clause because it would stop at all of the
-// conditional instructions in both.
-// In such cases, we really don't want to stop at this location.
+// that detects when we stop on an instruction in ARM mode that is conditional
+// and the condition doesn't pass. This can happen if you set a breakpoint on
+// an instruction that is conditional. We currently will _always_ stop on the
+// instruction which is bad. You can also run into this while single stepping
+// and you could appear to run code in the "if" and in the "else" clause
+// because it would stop at all of the conditional instructions in both. In
+// such cases, we really don't want to stop at this location.
// I will check with the lldb-dev list first before I enable this.
#if 0
- // ARM mode: check for condition on intsruction
+ // ARM mode: check for condition on instruction
const addr_t pc = reg_ctx_sp->GetPC();
Status error;
- // If we fail to read the opcode we will get UINT64_MAX as the
- // result in "opcode" which we can use to detect if we read a
- // valid opcode.
+ // If we fail to read the opcode we will get UINT64_MAX as the result in
+ // "opcode" which we can use to detect if we read a valid opcode.
const uint64_t opcode = thread.GetProcess()->ReadUnsignedIntegerFromMemory(pc, 4, UINT64_MAX, error);
if (opcode <= UINT32_MAX)
{
@@ -109,8 +106,8 @@ void ArchitectureArm::OverrideStopInfo(Thread &thread) {
if (!ARMConditionPassed(condition, cpsr))
{
// We ARE stopped on an ARM instruction whose condition doesn't
- // pass so this instruction won't get executed.
- // Regardless of why it stopped, we need to clear the stop info
+ // pass so this instruction won't get executed. Regardless of why
+ // it stopped, we need to clear the stop info
thread.SetStopInfo (StopInfoSP());
}
}
diff --git a/source/Plugins/Architecture/Arm/ArchitectureArm.h b/source/Plugins/Architecture/Arm/ArchitectureArm.h
index 9ce6c69ef271..484c4a52fcc6 100644
--- a/source/Plugins/Architecture/Arm/ArchitectureArm.h
+++ b/source/Plugins/Architecture/Arm/ArchitectureArm.h
@@ -23,7 +23,7 @@ public:
ConstString GetPluginName() override;
uint32_t GetPluginVersion() override;
- void OverrideStopInfo(Thread &thread) override;
+ void OverrideStopInfo(Thread &thread) const override;
private:
static std::unique_ptr<Architecture> Create(const ArchSpec &arch);
diff --git a/source/Plugins/Architecture/CMakeLists.txt b/source/Plugins/Architecture/CMakeLists.txt
index 5abaa8e68231..01365a64cf96 100644
--- a/source/Plugins/Architecture/CMakeLists.txt
+++ b/source/Plugins/Architecture/CMakeLists.txt
@@ -1 +1,2 @@
add_subdirectory(Arm)
+add_subdirectory(PPC64)
diff --git a/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp b/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp
new file mode 100644
index 000000000000..619de093aacc
--- /dev/null
+++ b/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp
@@ -0,0 +1,69 @@
+//===-- ArchitecturePPC64.cpp -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/Architecture/PPC64/ArchitecturePPC64.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/Symbol.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/ArchSpec.h"
+
+#include "llvm/BinaryFormat/ELF.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+ConstString ArchitecturePPC64::GetPluginNameStatic() {
+ return ConstString("ppc64");
+}
+
+void ArchitecturePPC64::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ "PPC64-specific algorithms",
+ &ArchitecturePPC64::Create);
+}
+
+void ArchitecturePPC64::Terminate() {
+ PluginManager::UnregisterPlugin(&ArchitecturePPC64::Create);
+}
+
+std::unique_ptr<Architecture> ArchitecturePPC64::Create(const ArchSpec &arch) {
+ if ((arch.GetMachine() != llvm::Triple::ppc64 &&
+ arch.GetMachine() != llvm::Triple::ppc64le) ||
+ arch.GetTriple().getObjectFormat() != llvm::Triple::ObjectFormatType::ELF)
+ return nullptr;
+ return std::unique_ptr<Architecture>(new ArchitecturePPC64());
+}
+
+ConstString ArchitecturePPC64::GetPluginName() { return GetPluginNameStatic(); }
+uint32_t ArchitecturePPC64::GetPluginVersion() { return 1; }
+
+static int32_t GetLocalEntryOffset(const Symbol &sym) {
+ unsigned char other = sym.GetFlags() >> 8 & 0xFF;
+ return llvm::ELF::decodePPC64LocalEntryOffset(other);
+}
+
+size_t ArchitecturePPC64::GetBytesToSkip(Symbol &func,
+ const Address &curr_addr) const {
+ if (curr_addr.GetFileAddress() ==
+ func.GetFileAddress() + GetLocalEntryOffset(func))
+ return func.GetPrologueByteSize();
+ return 0;
+}
+
+void ArchitecturePPC64::AdjustBreakpointAddress(const Symbol &func,
+ Address &addr) const {
+ int32_t loffs = GetLocalEntryOffset(func);
+ if (!loffs)
+ return;
+
+ addr.SetOffset(addr.GetOffset() + loffs);
+}
diff --git a/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h b/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h
new file mode 100644
index 000000000000..95638853ad3d
--- /dev/null
+++ b/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h
@@ -0,0 +1,44 @@
+//===-- ArchitecturePPC64.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_PLUGIN_ARCHITECTURE_PPC64_H
+#define LLDB_PLUGIN_ARCHITECTURE_PPC64_H
+
+#include "lldb/Core/Architecture.h"
+
+namespace lldb_private {
+
+class ArchitecturePPC64 : public Architecture {
+public:
+ static ConstString GetPluginNameStatic();
+ static void Initialize();
+ static void Terminate();
+
+ ConstString GetPluginName() override;
+ uint32_t GetPluginVersion() override;
+
+ void OverrideStopInfo(Thread &thread) const override {}
+
+ //------------------------------------------------------------------
+ /// This method compares current address with current function's
+ /// local entry point, returning the bytes to skip if they match.
+ //------------------------------------------------------------------
+ size_t GetBytesToSkip(Symbol &func, const Address &curr_addr) const override;
+
+ void AdjustBreakpointAddress(const Symbol &func,
+ Address &addr) const override;
+
+private:
+ static std::unique_ptr<Architecture> Create(const ArchSpec &arch);
+ ArchitecturePPC64() = default;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_PLUGIN_ARCHITECTURE_PPC64_H
diff --git a/source/Plugins/Architecture/PPC64/CMakeLists.txt b/source/Plugins/Architecture/PPC64/CMakeLists.txt
new file mode 100644
index 000000000000..2cba112cf882
--- /dev/null
+++ b/source/Plugins/Architecture/PPC64/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_lldb_library(lldbPluginArchitecturePPC64 PLUGIN
+ ArchitecturePPC64.cpp
+
+ LINK_LIBS
+ lldbPluginProcessUtility
+ lldbCore
+ lldbTarget
+ lldbUtility
+ LINK_COMPONENTS
+ Support
+ )
diff --git a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
index a61abb9898ac..9b381dd3b96c 100644
--- a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
+++ b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
@@ -10,6 +10,9 @@
// C Includes
// C++ Includes
// Project includes
+#include "DisassemblerLLVMC.h"
+
+// Other libraries and framework includes
#include "llvm-c/Disassembler.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -27,9 +30,6 @@
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
-// Other libraries and framework includes
-#include "DisassemblerLLVMC.h"
-
#include "lldb/Core/Address.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/SymbolContext.h"
@@ -41,13 +41,47 @@
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Stream.h"
-
#include "lldb/Utility/RegularExpression.h"
+#include "lldb/Utility/Stream.h"
using namespace lldb;
using namespace lldb_private;
+class DisassemblerLLVMC::MCDisasmInstance {
+public:
+ static std::unique_ptr<MCDisasmInstance>
+ Create(const char *triple, const char *cpu, const char *features_str,
+ unsigned flavor, DisassemblerLLVMC &owner);
+
+ ~MCDisasmInstance() = default;
+
+ uint64_t GetMCInst(const uint8_t *opcode_data, size_t opcode_data_len,
+ lldb::addr_t pc, llvm::MCInst &mc_inst) const;
+ void PrintMCInst(llvm::MCInst &mc_inst, std::string &inst_string,
+ std::string &comments_string);
+ void SetStyle(bool use_hex_immed, HexImmediateStyle hex_style);
+ bool CanBranch(llvm::MCInst &mc_inst) const;
+ bool HasDelaySlot(llvm::MCInst &mc_inst) const;
+ bool IsCall(llvm::MCInst &mc_inst) const;
+
+private:
+ MCDisasmInstance(std::unique_ptr<llvm::MCInstrInfo> &&instr_info_up,
+ std::unique_ptr<llvm::MCRegisterInfo> &&reg_info_up,
+ std::unique_ptr<llvm::MCSubtargetInfo> &&subtarget_info_up,
+ std::unique_ptr<llvm::MCAsmInfo> &&asm_info_up,
+ std::unique_ptr<llvm::MCContext> &&context_up,
+ std::unique_ptr<llvm::MCDisassembler> &&disasm_up,
+ std::unique_ptr<llvm::MCInstPrinter> &&instr_printer_up);
+
+ std::unique_ptr<llvm::MCInstrInfo> m_instr_info_up;
+ std::unique_ptr<llvm::MCRegisterInfo> m_reg_info_up;
+ std::unique_ptr<llvm::MCSubtargetInfo> m_subtarget_info_up;
+ std::unique_ptr<llvm::MCAsmInfo> m_asm_info_up;
+ std::unique_ptr<llvm::MCContext> m_context_up;
+ std::unique_ptr<llvm::MCDisassembler> m_disasm_up;
+ std::unique_ptr<llvm::MCInstPrinter> m_instr_printer_up;
+};
+
class InstructionLLVMC : public lldb_private::Instruction {
public:
InstructionLLVMC(DisassemblerLLVMC &disasm,
@@ -72,7 +106,7 @@ public:
bool is_alternate_isa;
lldb::addr_t pc = m_address.GetFileAddress();
- DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr =
+ DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr =
GetDisasmToUse(is_alternate_isa);
const uint8_t *opcode_data = data.GetDataStart();
const size_t opcode_data_len = data.GetByteSize();
@@ -107,7 +141,7 @@ public:
bool is_alternate_isa;
lldb::addr_t pc = m_address.GetFileAddress();
- DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr =
+ DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr =
GetDisasmToUse(is_alternate_isa);
const uint8_t *opcode_data = data.GetDataStart();
const size_t opcode_data_len = data.GetByteSize();
@@ -132,19 +166,19 @@ public:
return m_has_delay_slot == eLazyBoolYes;
}
- DisassemblerLLVMC::LLVMCDisassembler *GetDisasmToUse(bool &is_alternate_isa) {
+ DisassemblerLLVMC::MCDisasmInstance *GetDisasmToUse(bool &is_alternate_isa) {
is_alternate_isa = false;
std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
if (disasm_sp) {
- if (disasm_sp->m_alternate_disasm_ap.get() != NULL) {
+ if (disasm_sp->m_alternate_disasm_up) {
const AddressClass address_class = GetAddressClass();
- if (address_class == eAddressClassCodeAlternateISA) {
+ if (address_class == AddressClass::eCodeAlternateISA) {
is_alternate_isa = true;
- return disasm_sp->m_alternate_disasm_ap.get();
+ return disasm_sp->m_alternate_disasm_up.get();
}
}
- return disasm_sp->m_disasm_ap.get();
+ return disasm_sp->m_disasm_up.get();
}
return nullptr;
}
@@ -197,7 +231,7 @@ public:
}
if (!got_op) {
bool is_alternate_isa = false;
- DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr =
+ DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr =
GetDisasmToUse(is_alternate_isa);
const llvm::Triple::ArchType machine = arch.GetMachine();
@@ -264,12 +298,12 @@ public:
std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
if (disasm_sp) {
- DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr;
+ DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr;
- if (address_class == eAddressClassCodeAlternateISA)
- mc_disasm_ptr = disasm_sp->m_alternate_disasm_ap.get();
+ if (address_class == AddressClass::eCodeAlternateISA)
+ mc_disasm_ptr = disasm_sp->m_alternate_disasm_up.get();
else
- mc_disasm_ptr = disasm_sp->m_disasm_ap.get();
+ mc_disasm_ptr = disasm_sp->m_disasm_up.get();
lldb::addr_t pc = m_address.GetFileAddress();
m_using_file_addr = true;
@@ -850,7 +884,7 @@ public:
bool is_alternate_isa;
lldb::addr_t pc = m_address.GetFileAddress();
- DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr =
+ DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr =
GetDisasmToUse(is_alternate_isa);
const uint8_t *opcode_data = data.GetDataStart();
const size_t opcode_data_len = data.GetByteSize();
@@ -881,80 +915,103 @@ protected:
bool m_using_file_addr;
};
-DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler(
- const char *triple, const char *cpu, const char *features_str,
- unsigned flavor, DisassemblerLLVMC &owner)
- : m_is_valid(true) {
+std::unique_ptr<DisassemblerLLVMC::MCDisasmInstance>
+DisassemblerLLVMC::MCDisasmInstance::Create(const char *triple, const char *cpu,
+ const char *features_str,
+ unsigned flavor,
+ DisassemblerLLVMC &owner) {
+ using Instance = std::unique_ptr<DisassemblerLLVMC::MCDisasmInstance>;
+
std::string Status;
const llvm::Target *curr_target =
llvm::TargetRegistry::lookupTarget(triple, Status);
- if (!curr_target) {
- m_is_valid = false;
- return;
- }
+ if (!curr_target)
+ return Instance();
- m_instr_info_ap.reset(curr_target->createMCInstrInfo());
- m_reg_info_ap.reset(curr_target->createMCRegInfo(triple));
+ std::unique_ptr<llvm::MCInstrInfo> instr_info_up(
+ curr_target->createMCInstrInfo());
+ if (!instr_info_up)
+ return Instance();
- m_subtarget_info_ap.reset(
+ std::unique_ptr<llvm::MCRegisterInfo> reg_info_up(
+ curr_target->createMCRegInfo(triple));
+ if (!reg_info_up)
+ return Instance();
+
+ std::unique_ptr<llvm::MCSubtargetInfo> subtarget_info_up(
curr_target->createMCSubtargetInfo(triple, cpu, features_str));
+ if (!subtarget_info_up)
+ return Instance();
- std::unique_ptr<llvm::MCRegisterInfo> reg_info(
- curr_target->createMCRegInfo(triple));
- m_asm_info_ap.reset(curr_target->createMCAsmInfo(*reg_info, triple));
+ std::unique_ptr<llvm::MCAsmInfo> asm_info_up(
+ curr_target->createMCAsmInfo(*reg_info_up, triple));
+ if (!asm_info_up)
+ return Instance();
- if (m_instr_info_ap.get() == NULL || m_reg_info_ap.get() == NULL ||
- m_subtarget_info_ap.get() == NULL || m_asm_info_ap.get() == NULL) {
- m_is_valid = false;
- return;
- }
+ std::unique_ptr<llvm::MCContext> context_up(
+ new llvm::MCContext(asm_info_up.get(), reg_info_up.get(), 0));
+ if (!context_up)
+ return Instance();
- m_context_ap.reset(
- new llvm::MCContext(m_asm_info_ap.get(), m_reg_info_ap.get(), 0));
+ std::unique_ptr<llvm::MCDisassembler> disasm_up(
+ curr_target->createMCDisassembler(*subtarget_info_up, *context_up));
+ if (!disasm_up)
+ return Instance();
- m_disasm_ap.reset(curr_target->createMCDisassembler(
- *m_subtarget_info_ap.get(), *m_context_ap.get()));
- if (m_disasm_ap.get() && m_context_ap.get()) {
- std::unique_ptr<llvm::MCRelocationInfo> RelInfo(
- curr_target->createMCRelocationInfo(triple, *m_context_ap.get()));
- if (!RelInfo) {
- m_is_valid = false;
- return;
- }
- std::unique_ptr<llvm::MCSymbolizer> symbolizer_up(
- curr_target->createMCSymbolizer(
- triple, NULL, DisassemblerLLVMC::SymbolLookupCallback,
- (void *)&owner, m_context_ap.get(), std::move(RelInfo)));
- m_disasm_ap->setSymbolizer(std::move(symbolizer_up));
+ std::unique_ptr<llvm::MCRelocationInfo> rel_info_up(
+ curr_target->createMCRelocationInfo(triple, *context_up));
+ if (!rel_info_up)
+ return Instance();
- unsigned asm_printer_variant;
- if (flavor == ~0U)
- asm_printer_variant = m_asm_info_ap->getAssemblerDialect();
- else {
- asm_printer_variant = flavor;
- }
+ std::unique_ptr<llvm::MCSymbolizer> symbolizer_up(
+ curr_target->createMCSymbolizer(
+ triple, nullptr, DisassemblerLLVMC::SymbolLookupCallback, &owner,
+ context_up.get(), std::move(rel_info_up)));
+ disasm_up->setSymbolizer(std::move(symbolizer_up));
- m_instr_printer_ap.reset(curr_target->createMCInstPrinter(
- llvm::Triple{triple}, asm_printer_variant, *m_asm_info_ap.get(),
- *m_instr_info_ap.get(), *m_reg_info_ap.get()));
- if (m_instr_printer_ap.get() == NULL) {
- m_disasm_ap.reset();
- m_is_valid = false;
- }
- } else
- m_is_valid = false;
+ unsigned asm_printer_variant =
+ flavor == ~0U ? asm_info_up->getAssemblerDialect() : flavor;
+
+ std::unique_ptr<llvm::MCInstPrinter> instr_printer_up(
+ curr_target->createMCInstPrinter(llvm::Triple{triple},
+ asm_printer_variant, *asm_info_up,
+ *instr_info_up, *reg_info_up));
+ if (!instr_printer_up)
+ return Instance();
+
+ return Instance(
+ new MCDisasmInstance(std::move(instr_info_up), std::move(reg_info_up),
+ std::move(subtarget_info_up), std::move(asm_info_up),
+ std::move(context_up), std::move(disasm_up),
+ std::move(instr_printer_up)));
}
-DisassemblerLLVMC::LLVMCDisassembler::~LLVMCDisassembler() = default;
+DisassemblerLLVMC::MCDisasmInstance::MCDisasmInstance(
+ std::unique_ptr<llvm::MCInstrInfo> &&instr_info_up,
+ std::unique_ptr<llvm::MCRegisterInfo> &&reg_info_up,
+ std::unique_ptr<llvm::MCSubtargetInfo> &&subtarget_info_up,
+ std::unique_ptr<llvm::MCAsmInfo> &&asm_info_up,
+ std::unique_ptr<llvm::MCContext> &&context_up,
+ std::unique_ptr<llvm::MCDisassembler> &&disasm_up,
+ std::unique_ptr<llvm::MCInstPrinter> &&instr_printer_up)
+ : m_instr_info_up(std::move(instr_info_up)),
+ m_reg_info_up(std::move(reg_info_up)),
+ m_subtarget_info_up(std::move(subtarget_info_up)),
+ m_asm_info_up(std::move(asm_info_up)),
+ m_context_up(std::move(context_up)), m_disasm_up(std::move(disasm_up)),
+ m_instr_printer_up(std::move(instr_printer_up)) {
+ assert(m_instr_info_up && m_reg_info_up && m_subtarget_info_up &&
+ m_asm_info_up && m_context_up && m_disasm_up && m_instr_printer_up);
+}
-uint64_t DisassemblerLLVMC::LLVMCDisassembler::GetMCInst(
+uint64_t DisassemblerLLVMC::MCDisasmInstance::GetMCInst(
const uint8_t *opcode_data, size_t opcode_data_len, lldb::addr_t pc,
- llvm::MCInst &mc_inst) {
+ llvm::MCInst &mc_inst) const {
llvm::ArrayRef<uint8_t> data(opcode_data, opcode_data_len);
llvm::MCDisassembler::DecodeStatus status;
uint64_t new_inst_size;
- status = m_disasm_ap->getInstruction(mc_inst, new_inst_size, data, pc,
+ status = m_disasm_up->getInstruction(mc_inst, new_inst_size, data, pc,
llvm::nulls(), llvm::nulls());
if (status == llvm::MCDisassembler::Success)
return new_inst_size;
@@ -962,16 +1019,16 @@ uint64_t DisassemblerLLVMC::LLVMCDisassembler::GetMCInst(
return 0;
}
-void DisassemblerLLVMC::LLVMCDisassembler::PrintMCInst(
+void DisassemblerLLVMC::MCDisasmInstance::PrintMCInst(
llvm::MCInst &mc_inst, std::string &inst_string,
std::string &comments_string) {
llvm::raw_string_ostream inst_stream(inst_string);
llvm::raw_string_ostream comments_stream(comments_string);
- m_instr_printer_ap->setCommentStream(comments_stream);
- m_instr_printer_ap->printInst(&mc_inst, inst_stream, llvm::StringRef(),
- *m_subtarget_info_ap);
- m_instr_printer_ap->setCommentStream(llvm::nulls());
+ m_instr_printer_up->setCommentStream(comments_stream);
+ m_instr_printer_up->printInst(&mc_inst, inst_stream, llvm::StringRef(),
+ *m_subtarget_info_up);
+ m_instr_printer_up->setCommentStream(llvm::nulls());
comments_stream.flush();
static std::string g_newlines("\r\n");
@@ -985,30 +1042,32 @@ void DisassemblerLLVMC::LLVMCDisassembler::PrintMCInst(
}
}
-void DisassemblerLLVMC::LLVMCDisassembler::SetStyle(
+void DisassemblerLLVMC::MCDisasmInstance::SetStyle(
bool use_hex_immed, HexImmediateStyle hex_style) {
- m_instr_printer_ap->setPrintImmHex(use_hex_immed);
+ m_instr_printer_up->setPrintImmHex(use_hex_immed);
switch (hex_style) {
case eHexStyleC:
- m_instr_printer_ap->setPrintHexStyle(llvm::HexStyle::C);
+ m_instr_printer_up->setPrintHexStyle(llvm::HexStyle::C);
break;
case eHexStyleAsm:
- m_instr_printer_ap->setPrintHexStyle(llvm::HexStyle::Asm);
+ m_instr_printer_up->setPrintHexStyle(llvm::HexStyle::Asm);
break;
}
}
-bool DisassemblerLLVMC::LLVMCDisassembler::CanBranch(llvm::MCInst &mc_inst) {
- return m_instr_info_ap->get(mc_inst.getOpcode())
- .mayAffectControlFlow(mc_inst, *m_reg_info_ap.get());
+bool DisassemblerLLVMC::MCDisasmInstance::CanBranch(
+ llvm::MCInst &mc_inst) const {
+ return m_instr_info_up->get(mc_inst.getOpcode())
+ .mayAffectControlFlow(mc_inst, *m_reg_info_up);
}
-bool DisassemblerLLVMC::LLVMCDisassembler::HasDelaySlot(llvm::MCInst &mc_inst) {
- return m_instr_info_ap->get(mc_inst.getOpcode()).hasDelaySlot();
+bool DisassemblerLLVMC::MCDisasmInstance::HasDelaySlot(
+ llvm::MCInst &mc_inst) const {
+ return m_instr_info_up->get(mc_inst.getOpcode()).hasDelaySlot();
}
-bool DisassemblerLLVMC::LLVMCDisassembler::IsCall(llvm::MCInst &mc_inst) {
- return m_instr_info_ap->get(mc_inst.getOpcode()).isCall();
+bool DisassemblerLLVMC::MCDisasmInstance::IsCall(llvm::MCInst &mc_inst) const {
+ return m_instr_info_up->get(mc_inst.getOpcode()).isCall();
}
DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch,
@@ -1023,8 +1082,7 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch,
llvm::Triple triple = arch.GetTriple();
// So far the only supported flavor is "intel" on x86. The base class will
- // set this
- // correctly coming in.
+ // set this correctly coming in.
if (triple.getArch() == llvm::Triple::x86 ||
triple.getArch() == llvm::Triple::x86_64) {
if (m_flavor == "intel") {
@@ -1048,12 +1106,10 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch,
}
// If no sub architecture specified then use the most recent arm architecture
- // so the
- // disassembler will return all instruction. Without it we will see a lot of
- // unknow opcode
- // in case the code uses instructions which are not available in the oldest
- // arm version
- // (used when no sub architecture is specified)
+ // so the disassembler will return all instruction. Without it we will see a
+ // lot of unknow opcode in case the code uses instructions which are not
+ // available in the oldest arm version (used when no sub architecture is
+ // specified)
if (triple.getArch() == llvm::Triple::arm &&
triple.getSubArch() == llvm::Triple::NoSubArch)
triple.setArchName("armv8.2a");
@@ -1127,20 +1183,16 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch,
features_str += "+dspr2,";
}
- // If any AArch64 variant, enable the ARMv8.2 ISA
- // extensions so we can disassemble newer instructions.
+ // If any AArch64 variant, enable the ARMv8.2 ISA extensions so we can
+ // disassemble newer instructions.
if (triple.getArch() == llvm::Triple::aarch64)
features_str += "+v8.2a";
- m_disasm_ap.reset(new LLVMCDisassembler(triple_str, cpu, features_str.c_str(),
- flavor, *this));
- if (!m_disasm_ap->IsValid()) {
- // We use m_disasm_ap.get() to tell whether we are valid or not, so if this
- // isn't good for some reason,
- // we reset it, and then we won't be valid and FindPlugin will fail and we
- // won't get used.
- m_disasm_ap.reset();
- }
+ // We use m_disasm_ap.get() to tell whether we are valid or not, so if this
+ // isn't good for some reason, we won't be valid and FindPlugin will fail and
+ // we won't get used.
+ m_disasm_up = MCDisasmInstance::Create(triple_str, cpu, features_str.c_str(),
+ flavor, *this);
llvm::Triple::ArchType llvm_arch = triple.getArch();
@@ -1148,12 +1200,11 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch,
// thumb instruction disassembler.
if (llvm_arch == llvm::Triple::arm) {
std::string thumb_triple(thumb_arch.GetTriple().getTriple());
- m_alternate_disasm_ap.reset(
- new LLVMCDisassembler(thumb_triple.c_str(), "", "", flavor, *this));
- if (!m_alternate_disasm_ap->IsValid()) {
- m_disasm_ap.reset();
- m_alternate_disasm_ap.reset();
- }
+ m_alternate_disasm_up =
+ MCDisasmInstance::Create(thumb_triple.c_str(), "", "", flavor, *this);
+ if (!m_alternate_disasm_up)
+ m_disasm_up.reset();
+
} else if (llvm_arch == llvm::Triple::mips ||
llvm_arch == llvm::Triple::mipsel ||
llvm_arch == llvm::Triple::mips64 ||
@@ -1165,12 +1216,10 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch,
else if (arch_flags & ArchSpec::eMIPSAse_micromips)
features_str += "+micromips,";
- m_alternate_disasm_ap.reset(new LLVMCDisassembler(
- triple_str, cpu, features_str.c_str(), flavor, *this));
- if (!m_alternate_disasm_ap->IsValid()) {
- m_disasm_ap.reset();
- m_alternate_disasm_ap.reset();
- }
+ m_alternate_disasm_up = MCDisasmInstance::Create(
+ triple_str, cpu, features_str.c_str(), flavor, *this);
+ if (!m_alternate_disasm_up)
+ m_disasm_up.reset();
}
}
@@ -1208,9 +1257,9 @@ size_t DisassemblerLLVMC::DecodeInstructions(const Address &base_addr,
while (data_cursor < data_byte_size &&
instructions_parsed < num_instructions) {
- AddressClass address_class = eAddressClassCode;
+ AddressClass address_class = AddressClass::eCode;
- if (m_alternate_disasm_ap.get() != NULL)
+ if (m_alternate_disasm_up)
address_class = inst_addr.GetAddressClass();
InstructionSP inst_sp(
@@ -1285,6 +1334,8 @@ bool DisassemblerLLVMC::FlavorValidForArchSpec(
return false;
}
+bool DisassemblerLLVMC::IsValid() const { return m_disasm_up.operator bool(); }
+
int DisassemblerLLVMC::OpInfo(uint64_t PC, uint64_t Offset, uint64_t Size,
int tag_type, void *tag_bug) {
switch (tag_type) {
@@ -1337,8 +1388,8 @@ const char *DisassemblerLLVMC::SymbolLookup(uint64_t value, uint64_t *type_ptr,
}
}
- // If the "value" address (the target address we're symbolicating)
- // is inside the same SymbolContext as the current instruction pc
+ // If the "value" address (the target address we're symbolicating) is
+ // inside the same SymbolContext as the current instruction pc
// (pc_so_addr), don't print the full function name - just print it
// with DumpStyleNoFunctionName style, e.g. "<+36>".
if (format_omitting_current_func_name) {
@@ -1353,9 +1404,8 @@ const char *DisassemblerLLVMC::SymbolLookup(uint64_t value, uint64_t *type_ptr,
if (!ss.GetString().empty()) {
// If Address::Dump returned a multi-line description, most commonly
- // seen when we
- // have multiple levels of inlined functions at an address, only show
- // the first line.
+ // seen when we have multiple levels of inlined functions at an
+ // address, only show the first line.
std::string str = ss.GetString();
size_t first_eol_char = str.find_first_of("\r\n");
if (first_eol_char != std::string::npos) {
diff --git a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h
index 26bed7ee0d7b..b7e9ccb34701 100644
--- a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h
+++ b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h
@@ -16,62 +16,14 @@
#include <mutex>
#include <string>
-// Other libraries and framework includes
-#include "llvm-c/Disassembler.h"
-
// Project includes
#include "lldb/Core/Address.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/PluginManager.h"
-// Opaque references to C++ Objects in LLVM's MC.
-namespace llvm {
-class MCContext;
-class MCInst;
-class MCInstrInfo;
-class MCRegisterInfo;
-class MCDisassembler;
-class MCInstPrinter;
-class MCAsmInfo;
-class MCSubtargetInfo;
-} // namespace llvm
-
class InstructionLLVMC;
class DisassemblerLLVMC : public lldb_private::Disassembler {
- // Since we need to make two actual MC Disassemblers for ARM (ARM & THUMB),
- // and there's a bit of goo to set up and own
- // in the MC disassembler world, I added this class to manage the actual
- // disassemblers.
- class LLVMCDisassembler {
- public:
- LLVMCDisassembler(const char *triple, const char *cpu,
- const char *features_str, unsigned flavor,
- DisassemblerLLVMC &owner);
-
- ~LLVMCDisassembler();
-
- uint64_t GetMCInst(const uint8_t *opcode_data, size_t opcode_data_len,
- lldb::addr_t pc, llvm::MCInst &mc_inst);
- void PrintMCInst(llvm::MCInst &mc_inst, std::string &inst_string,
- std::string &comments_string);
- void SetStyle(bool use_hex_immed, HexImmediateStyle hex_style);
- bool CanBranch(llvm::MCInst &mc_inst);
- bool HasDelaySlot(llvm::MCInst &mc_inst);
- bool IsCall(llvm::MCInst &mc_inst);
- bool IsValid() { return m_is_valid; }
-
- private:
- bool m_is_valid;
- std::unique_ptr<llvm::MCContext> m_context_ap;
- std::unique_ptr<llvm::MCAsmInfo> m_asm_info_ap;
- std::unique_ptr<llvm::MCSubtargetInfo> m_subtarget_info_ap;
- std::unique_ptr<llvm::MCInstrInfo> m_instr_info_ap;
- std::unique_ptr<llvm::MCRegisterInfo> m_reg_info_ap;
- std::unique_ptr<llvm::MCInstPrinter> m_instr_printer_ap;
- std::unique_ptr<llvm::MCDisassembler> m_disasm_ap;
- };
-
public:
DisassemblerLLVMC(const lldb_private::ArchSpec &arch,
const char *flavor /* = NULL */);
@@ -108,9 +60,7 @@ protected:
bool FlavorValidForArchSpec(const lldb_private::ArchSpec &arch,
const char *flavor) override;
- bool IsValid() {
- return (m_disasm_ap.get() != NULL && m_disasm_ap->IsValid());
- }
+ bool IsValid() const;
int OpInfo(uint64_t PC, uint64_t Offset, uint64_t Size, int TagType,
void *TagBug);
@@ -145,8 +95,12 @@ protected:
std::mutex m_mutex;
bool m_data_from_file;
- std::unique_ptr<LLVMCDisassembler> m_disasm_ap;
- std::unique_ptr<LLVMCDisassembler> m_alternate_disasm_ap;
+ // Since we need to make two actual MC Disassemblers for ARM (ARM & THUMB),
+ // and there's a bit of goo to set up and own in the MC disassembler world,
+ // this class was added to manage the actual disassemblers.
+ class MCDisasmInstance;
+ std::unique_ptr<MCDisasmInstance> m_disasm_up;
+ std::unique_ptr<MCDisasmInstance> m_alternate_disasm_up;
};
#endif // liblldb_DisassemblerLLVM_h_
diff --git a/source/Plugins/DynamicLoader/CMakeLists.txt b/source/Plugins/DynamicLoader/CMakeLists.txt
index 8e1b316a3c25..9f3b2ab0e50f 100644
--- a/source/Plugins/DynamicLoader/CMakeLists.txt
+++ b/source/Plugins/DynamicLoader/CMakeLists.txt
@@ -1,9 +1,6 @@
+add_subdirectory(Darwin-Kernel)
add_subdirectory(MacOSX-DYLD)
add_subdirectory(POSIX-DYLD)
add_subdirectory(Static)
add_subdirectory(Hexagon-DYLD)
add_subdirectory(Windows-DYLD)
-
-if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
- add_subdirectory(Darwin-Kernel)
-endif()
diff --git a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
index a81a0306671e..8999000dff8c 100644
--- a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ b/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -8,8 +8,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Utility/SafeMachO.h"
-
#include "Plugins/Platform/MacOSX/PlatformDarwinKernel.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Debugger.h"
@@ -45,10 +43,10 @@
using namespace lldb;
using namespace lldb_private;
-// Progressively greater amounts of scanning we will allow
-// For some targets very early in startup, we can't do any random reads of
-// memory or we can crash the device
-// so a setting is needed that can completely disable the KASLR scans.
+// Progressively greater amounts of scanning we will allow For some targets
+// very early in startup, we can't do any random reads of memory or we can
+// crash the device so a setting is needed that can completely disable the
+// KASLR scans.
enum KASLRScanType {
eKASLRScanNone = 0, // No reading into the inferior at all
@@ -122,15 +120,15 @@ static const DynamicLoaderDarwinKernelPropertiesSP &GetGlobalProperties() {
}
//----------------------------------------------------------------------
-// Create an instance of this class. This function is filled into
-// the plugin info class that gets handed out by the plugin factory and
-// allows the lldb to instantiate an instance of this class.
+// Create an instance of this class. This function is filled into the plugin
+// info class that gets handed out by the plugin factory and allows the lldb to
+// instantiate an instance of this class.
//----------------------------------------------------------------------
DynamicLoader *DynamicLoaderDarwinKernel::CreateInstance(Process *process,
bool force) {
if (!force) {
- // If the user provided an executable binary and it is not a kernel,
- // this plugin should not create an instance.
+ // If the user provided an executable binary and it is not a kernel, this
+ // plugin should not create an instance.
Module *exe_module = process->GetTarget().GetExecutableModulePointer();
if (exe_module) {
ObjectFile *object_file = exe_module->GetObjectFile();
@@ -155,8 +153,8 @@ DynamicLoader *DynamicLoaderDarwinKernel::CreateInstance(Process *process,
return NULL;
}
break;
- // If we have triple like armv7-unknown-unknown, we should try looking for a
- // Darwin kernel.
+ // If we have triple like armv7-unknown-unknown, we should try looking for
+ // a Darwin kernel.
case llvm::Triple::UnknownOS:
break;
default:
@@ -166,9 +164,8 @@ DynamicLoader *DynamicLoaderDarwinKernel::CreateInstance(Process *process,
}
// At this point if there is an ExecutableModule, it is a kernel and the
- // Target is some variant of an Apple system.
- // If the Process hasn't provided the kernel load address, we need to look
- // around in memory to find it.
+ // Target is some variant of an Apple system. If the Process hasn't provided
+ // the kernel load address, we need to look around in memory to find it.
const addr_t kernel_load_address = SearchForDarwinKernel(process);
if (CheckForKernelImageAtAddress(kernel_load_address, process).IsValid()) {
@@ -197,10 +194,9 @@ DynamicLoaderDarwinKernel::SearchForDarwinKernel(Process *process) {
}
//----------------------------------------------------------------------
-// Check if the kernel binary is loaded in memory without a slide.
-// First verify that the ExecutableModule is a kernel before we proceed.
-// Returns the address of the kernel if one was found, else
-// LLDB_INVALID_ADDRESS.
+// Check if the kernel binary is loaded in memory without a slide. First verify
+// that the ExecutableModule is a kernel before we proceed. Returns the address
+// of the kernel if one was found, else LLDB_INVALID_ADDRESS.
//----------------------------------------------------------------------
lldb::addr_t
DynamicLoaderDarwinKernel::SearchForKernelAtSameLoadAddr(Process *process) {
@@ -229,10 +225,8 @@ DynamicLoaderDarwinKernel::SearchForKernelAtSameLoadAddr(Process *process) {
//----------------------------------------------------------------------
// If the debug flag is included in the boot-args nvram setting, the kernel's
-// load address
-// will be noted in the lowglo page at a fixed address
-// Returns the address of the kernel if one was found, else
-// LLDB_INVALID_ADDRESS.
+// load address will be noted in the lowglo page at a fixed address Returns the
+// address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
//----------------------------------------------------------------------
lldb::addr_t
DynamicLoaderDarwinKernel::SearchForKernelWithDebugHints(Process *process) {
@@ -282,8 +276,8 @@ DynamicLoaderDarwinKernel::SearchForKernelWithDebugHints(Process *process) {
}
//----------------------------------------------------------------------
-// If the kernel is currently executing when lldb attaches, and we don't have
-// a better way of finding the kernel's load address, try searching backwards
+// If the kernel is currently executing when lldb attaches, and we don't have a
+// better way of finding the kernel's load address, try searching backwards
// from the current pc value looking for the kernel's Mach header in memory.
// Returns the address of the kernel if one was found, else
// LLDB_INVALID_ADDRESS.
@@ -304,9 +298,8 @@ DynamicLoaderDarwinKernel::SearchForKernelNearPC(Process *process) {
return LLDB_INVALID_ADDRESS;
// The kernel will load at at one megabyte boundary (0x100000), or at that
- // boundary plus
- // an offset of one page (0x1000) or two, or four (0x4000), depending on the
- // device.
+ // boundary plus an offset of one page (0x1000) or two, or four (0x4000),
+ // depending on the device.
// Round the current pc down to the nearest one megabyte boundary - the place
// where we will start searching.
@@ -329,11 +322,10 @@ DynamicLoaderDarwinKernel::SearchForKernelNearPC(Process *process) {
}
//----------------------------------------------------------------------
-// Scan through the valid address range for a kernel binary.
-// This is uselessly slow in 64-bit environments so we don't even try it.
-// This scan is not enabled by default even for 32-bit targets.
-// Returns the address of the kernel if one was found, else
-// LLDB_INVALID_ADDRESS.
+// Scan through the valid address range for a kernel binary. This is uselessly
+// slow in 64-bit environments so we don't even try it. This scan is not
+// enabled by default even for 32-bit targets. Returns the address of the
+// kernel if one was found, else LLDB_INVALID_ADDRESS.
//----------------------------------------------------------------------
lldb::addr_t DynamicLoaderDarwinKernel::SearchForKernelViaExhaustiveSearch(
Process *process) {
@@ -374,47 +366,30 @@ lldb::addr_t DynamicLoaderDarwinKernel::SearchForKernelViaExhaustiveSearch(
}
//----------------------------------------------------------------------
-// Given an address in memory, look to see if there is a kernel image at that
-// address.
-// Returns a UUID; if a kernel was not found at that address, UUID.IsValid()
-// will be false.
+// Read the mach_header struct out of memory and return it.
+// Returns true if the mach_header was successfully read,
+// Returns false if there was a problem reading the header, or it was not
+// a Mach-O header.
//----------------------------------------------------------------------
-lldb_private::UUID
-DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress(lldb::addr_t addr,
- Process *process) {
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (addr == LLDB_INVALID_ADDRESS)
- return UUID();
-
- if (log)
- log->Printf("DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress: "
- "looking for kernel binary at 0x%" PRIx64,
- addr);
-
- // First try a quick test -- read the first 4 bytes and see if there is a
- // valid Mach-O magic field there
- // (the first field of the mach_header/mach_header_64 struct).
+bool
+DynamicLoaderDarwinKernel::ReadMachHeader(addr_t addr, Process *process, llvm::MachO::mach_header &header) {
Status read_error;
- uint8_t magicbuf[4];
- if (process->ReadMemoryFromInferior (addr, magicbuf, sizeof (magicbuf), read_error) != sizeof (magicbuf))
- return UUID();
+
+ // Read the mach header and see whether it looks like a kernel
+ if (process->DoReadMemory (addr, &header, sizeof(header), read_error) !=
+ sizeof(header))
+ return false;
const uint32_t magicks[] = { llvm::MachO::MH_MAGIC_64, llvm::MachO::MH_MAGIC, llvm::MachO::MH_CIGAM, llvm::MachO::MH_CIGAM_64};
bool found_matching_pattern = false;
for (size_t i = 0; i < llvm::array_lengthof (magicks); i++)
- if (::memcmp (magicbuf, &magicks[i], sizeof (magicbuf)) == 0)
+ if (::memcmp (&header.magic, &magicks[i], sizeof (uint32_t)) == 0)
found_matching_pattern = true;
if (found_matching_pattern == false)
- return UUID();
-
- // Read the mach header and see whether it looks like a kernel
- llvm::MachO::mach_header header;
- if (process->DoReadMemory(addr, &header, sizeof(header), read_error) !=
- sizeof(header))
- return UUID();
+ return false;
if (header.magic == llvm::MachO::MH_CIGAM ||
header.magic == llvm::MachO::MH_CIGAM_64) {
@@ -427,6 +402,35 @@ DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress(lldb::addr_t addr,
header.flags = llvm::ByteSwap_32(header.flags);
}
+ return true;
+}
+
+//----------------------------------------------------------------------
+// Given an address in memory, look to see if there is a kernel image at that
+// address.
+// Returns a UUID; if a kernel was not found at that address, UUID.IsValid()
+// will be false.
+//----------------------------------------------------------------------
+lldb_private::UUID
+DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress(lldb::addr_t addr,
+ Process *process) {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (addr == LLDB_INVALID_ADDRESS)
+ return UUID();
+
+ if (log)
+ log->Printf("DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress: "
+ "looking for kernel binary at 0x%" PRIx64,
+ addr);
+
+ llvm::MachO::mach_header header;
+
+ if (ReadMachHeader (addr, process, header) == false)
+ return UUID();
+
+ // First try a quick test -- read the first 4 bytes and see if there is a
+ // valid Mach-O magic field there
+ // (the first field of the mach_header/mach_header_64 struct).
// A kernel is an executable which does not have the dynamic link object flag
// set.
if (header.filetype == llvm::MachO::MH_EXECUTE &&
@@ -630,10 +634,8 @@ UUID DynamicLoaderDarwinKernel::KextImageInfo::GetUUID() const {
}
// Given the m_load_address from the kext summaries, and a UUID, try to create
-// an in-memory
-// Module at that address. Require that the MemoryModule have a matching UUID
-// and detect
-// if this MemoryModule is a kernel or a kext.
+// an in-memory Module at that address. Require that the MemoryModule have a
+// matching UUID and detect if this MemoryModule is a kernel or a kext.
//
// Returns true if m_memory_module_sp is now set to a valid Module.
@@ -646,10 +648,19 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::ReadMemoryModule(
return false;
FileSpec file_spec;
- file_spec.SetFile(m_name.c_str(), false);
+ file_spec.SetFile(m_name.c_str(), false, FileSpec::Style::native);
+
+ llvm::MachO::mach_header mh;
+ size_t size_to_read = 512;
+ if (ReadMachHeader (m_load_address, process, mh)) {
+ if (mh.magic == llvm::MachO::MH_CIGAM || llvm::MachO::MH_MAGIC)
+ size_to_read = sizeof (llvm::MachO::mach_header) + mh.sizeofcmds;
+ if (mh.magic == llvm::MachO::MH_CIGAM_64 || llvm::MachO::MH_MAGIC_64)
+ size_to_read = sizeof (llvm::MachO::mach_header_64) + mh.sizeofcmds;
+ }
ModuleSP memory_module_sp =
- process->ReadModuleFromMemory(file_spec, m_load_address);
+ process->ReadModuleFromMemory(file_spec, m_load_address, size_to_read);
if (memory_module_sp.get() == NULL)
return false;
@@ -668,10 +679,8 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::ReadMemoryModule(
}
// If this is a kext, and the kernel specified what UUID we should find at
- // this
- // load address, require that the memory module have a matching UUID or
- // something
- // has gone wrong and we should discard it.
+ // this load address, require that the memory module have a matching UUID or
+ // something has gone wrong and we should discard it.
if (m_uuid.IsValid()) {
if (m_uuid != memory_module_sp->GetUUID()) {
if (log) {
@@ -737,9 +746,8 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
Target &target = process->GetTarget();
- // If we don't have / can't create a memory module for this kext, don't try to
- // load it - we won't
- // have the correct segment load addresses.
+ // If we don't have / can't create a memory module for this kext, don't try
+ // to load it - we won't have the correct segment load addresses.
if (!ReadMemoryModule(process)) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
if (log)
@@ -772,9 +780,8 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
module_spec.GetUUID() = m_uuid;
module_spec.GetArchitecture() = target.GetArchitecture();
- // For the kernel, we really do need an on-disk file copy of the binary to
- // do anything useful.
- // This will force a clal to
+ // For the kernel, we really do need an on-disk file copy of the binary
+ // to do anything useful. This will force a clal to
if (IsKernel()) {
if (Symbols::DownloadObjectAndSymbolFile(module_spec, true)) {
if (module_spec.GetFileSpec().Exists()) {
@@ -791,10 +798,8 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
}
// If the current platform is PlatformDarwinKernel, create a ModuleSpec
- // with the filename set
- // to be the bundle ID for this kext, e.g.
- // "com.apple.filesystems.msdosfs", and ask the platform
- // to find it.
+ // with the filename set to be the bundle ID for this kext, e.g.
+ // "com.apple.filesystems.msdosfs", and ask the platform to find it.
PlatformSP platform_sp(target.GetPlatform());
if (!m_module_sp && platform_sp) {
ConstString platform_name(platform_sp->GetPluginName());
@@ -828,8 +833,9 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
}
}
- // If we managed to find a module, append it to the target's list of images.
- // If we also have a memory module, require that they have matching UUIDs
+ // If we managed to find a module, append it to the target's list of
+ // images. If we also have a memory module, require that they have matching
+ // UUIDs
if (m_module_sp) {
bool uuid_match_ok = true;
if (m_memory_module_sp) {
@@ -871,15 +877,15 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
SectionList *memory_section_list = memory_object_file->GetSectionList();
if (memory_section_list && ondisk_section_list) {
const uint32_t num_ondisk_sections = ondisk_section_list->GetSize();
- // There may be CTF sections in the memory image so we can't
- // always just compare the number of sections (which are actually
- // segments in mach-o parlance)
+ // There may be CTF sections in the memory image so we can't always
+ // just compare the number of sections (which are actually segments
+ // in mach-o parlance)
uint32_t sect_idx = 0;
- // Use the memory_module's addresses for each section to set the
- // file module's load address as appropriate. We don't want to use
- // a single slide value for the entire kext - different segments may
- // be slid different amounts by the kext loader.
+ // Use the memory_module's addresses for each section to set the file
+ // module's load address as appropriate. We don't want to use a
+ // single slide value for the entire kext - different segments may be
+ // slid different amounts by the kext loader.
uint32_t num_sections_loaded = 0;
for (sect_idx = 0; sect_idx < num_ondisk_sections; ++sect_idx) {
@@ -969,10 +975,9 @@ DynamicLoaderDarwinKernel::KextImageInfo::GetArchitecture() const {
}
//----------------------------------------------------------------------
-// Load the kernel module and initialize the "m_kernel" member. Return
-// true _only_ if the kernel is loaded the first time through (subsequent
-// calls to this function should return false after the kernel has been
-// already loaded).
+// Load the kernel module and initialize the "m_kernel" member. Return true
+// _only_ if the kernel is loaded the first time through (subsequent calls to
+// this function should return false after the kernel has been already loaded).
//----------------------------------------------------------------------
void DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
if (!m_kext_summary_header_ptr_addr.IsValid()) {
@@ -996,9 +1001,8 @@ void DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
m_kernel.SetLoadAddress(m_kernel_load_address);
if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS &&
m_kernel.GetModule()) {
- // We didn't get a hint from the process, so we will
- // try the kernel at the address that it exists at in
- // the file if we have one
+ // We didn't get a hint from the process, so we will try the kernel at
+ // the address that it exists at in the file if we have one
ObjectFile *kernel_object_file = m_kernel.GetModule()->GetObjectFile();
if (kernel_object_file) {
addr_t load_address =
@@ -1011,8 +1015,7 @@ void DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
if (load_address != file_address) {
// Don't accidentally relocate the kernel to the File address --
// the Load address has already been set to its actual in-memory
- // address.
- // Mark it as IsLoaded.
+ // address. Mark it as IsLoaded.
m_kernel.SetProcessStopId(m_process->GetStopID());
}
} else {
@@ -1028,10 +1031,10 @@ void DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
}
}
- // The operating system plugin gets loaded and initialized in
- // LoadImageUsingMemoryModule when we discover the kernel dSYM. For a
- // core file in particular, that's the wrong place to do this, since
- // we haven't fixed up the section addresses yet. So let's redo it here.
+ // The operating system plugin gets loaded and initialized in
+ // LoadImageUsingMemoryModule when we discover the kernel dSYM. For a core
+ // file in particular, that's the wrong place to do this, since we haven't
+ // fixed up the section addresses yet. So let's redo it here.
LoadOperatingSystemPlugin(false);
if (m_kernel.IsLoaded() && m_kernel.GetModule()) {
@@ -1052,9 +1055,9 @@ void DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
//----------------------------------------------------------------------
// Static callback function that gets called when our DYLD notification
-// breakpoint gets hit. We update all of our image infos and then
-// let our super class DynamicLoader class decide if we should stop
-// or not (based on global preference).
+// breakpoint gets hit. We update all of our image infos and then let our super
+// class DynamicLoader class decide if we should stop or not (based on global
+// preference).
//----------------------------------------------------------------------
bool DynamicLoaderDarwinKernel::BreakpointHitCallback(
void *baton, StoppointCallbackContext *context, user_id_t break_id,
@@ -1087,8 +1090,8 @@ bool DynamicLoaderDarwinKernel::ReadKextSummaryHeader() {
const uint32_t addr_size = m_kernel.GetAddressByteSize();
const ByteOrder byte_order = m_kernel.GetByteOrder();
Status error;
- // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure
- // which is currently 4 uint32_t and a pointer.
+ // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure which
+ // is currently 4 uint32_t and a pointer.
uint8_t buf[24];
DataExtractor data(buf, sizeof(buf), byte_order, addr_size);
const size_t count = 4 * sizeof(uint32_t) + addr_size;
@@ -1130,7 +1133,8 @@ bool DynamicLoaderDarwinKernel::ReadKextSummaryHeader() {
return false;
}
} else {
- // Versions less than 2 didn't have an entry size, it was hard coded
+ // Versions less than 2 didn't have an entry size, it was hard
+ // coded
m_kext_summary_header.entry_size =
KERNEL_MODULE_ENTRY_SIZE_VERSION_1;
}
@@ -1156,13 +1160,10 @@ bool DynamicLoaderDarwinKernel::ReadKextSummaryHeader() {
}
// We've either (a) just attached to a new kernel, or (b) the kexts-changed
-// breakpoint was hit
-// and we need to figure out what kexts have been added or removed.
-// Read the kext summaries from the inferior kernel memory, compare them against
-// the
-// m_known_kexts vector and update the m_known_kexts vector as needed to keep in
-// sync with the
-// inferior.
+// breakpoint was hit and we need to figure out what kexts have been added or
+// removed. Read the kext summaries from the inferior kernel memory, compare
+// them against the m_known_kexts vector and update the m_known_kexts vector as
+// needed to keep in sync with the inferior.
bool DynamicLoaderDarwinKernel::ParseKextSummaries(
const Address &kext_summary_addr, uint32_t count) {
@@ -1178,14 +1179,13 @@ bool DynamicLoaderDarwinKernel::ParseKextSummaries(
return false;
// read the plugin.dynamic-loader.darwin-kernel.load-kexts setting -- if the
- // user requested no
- // kext loading, don't print any messages about kexts & don't try to read
- // them.
+ // user requested no kext loading, don't print any messages about kexts &
+ // don't try to read them.
const bool load_kexts = GetGlobalProperties()->GetLoadKexts();
// By default, all kexts we've loaded in the past are marked as "remove" and
- // all of the kexts
- // we just found out about from ReadKextSummaries are marked as "add".
+ // all of the kexts we just found out about from ReadKextSummaries are marked
+ // as "add".
std::vector<bool> to_be_removed(m_known_kexts.size(), true);
std::vector<bool> to_be_added(count, true);
@@ -1195,8 +1195,8 @@ bool DynamicLoaderDarwinKernel::ParseKextSummaries(
const uint32_t new_kexts_size = kext_summaries.size();
const uint32_t old_kexts_size = m_known_kexts.size();
- // The m_known_kexts vector may have entries that have been Cleared,
- // or are a kernel.
+ // The m_known_kexts vector may have entries that have been Cleared, or are a
+ // kernel.
for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++) {
bool ignore = false;
KextImageInfo &image_info = m_known_kexts[old_kext];
@@ -1229,10 +1229,9 @@ bool DynamicLoaderDarwinKernel::ParseKextSummaries(
break;
}
}
- // If this "kext" entry is actually an alias for the kernel --
- // the kext was compiled into the kernel or something -- then
- // we don't want to load the kernel's text section at a different
- // address. Ignore this kext entry.
+ // If this "kext" entry is actually an alias for the kernel -- the kext was
+ // compiled into the kernel or something -- then we don't want to load the
+ // kernel's text section at a different address. Ignore this kext entry.
if (kext_summaries[new_kext].GetUUID().IsValid()
&& m_kernel.GetUUID().IsValid()
&& kext_summaries[new_kext].GetUUID() == m_kernel.GetUUID()) {
@@ -1322,9 +1321,8 @@ bool DynamicLoaderDarwinKernel::ParseKextSummaries(
s->Printf(".");
image_info.Clear();
// should pull it out of the KextImageInfos vector but that would
- // mutate the list and invalidate
- // the to_be_removed bool vector; leaving it in place once Cleared()
- // is relatively harmless.
+ // mutate the list and invalidate the to_be_removed bool vector;
+ // leaving it in place once Cleared() is relatively harmless.
}
}
m_process->GetTarget().ModulesDidUnload(unloaded_module_list, false);
@@ -1370,7 +1368,7 @@ uint32_t DynamicLoaderDarwinKernel::ReadKextSummaries(
if (name_data == NULL)
break;
image_infos[i].SetName((const char *)name_data);
- UUID uuid(extractor.GetData(&offset, 16), 16);
+ UUID uuid = UUID::fromOptionalData(extractor.GetData(&offset, 16), 16);
image_infos[i].SetUUID(uuid);
image_infos[i].SetLoadAddress(extractor.GetU64(&offset));
image_infos[i].SetSize(extractor.GetU64(&offset));
@@ -1405,36 +1403,18 @@ bool DynamicLoaderDarwinKernel::ReadAllKextSummaries() {
// Dump an image info structure to the file handle provided.
//----------------------------------------------------------------------
void DynamicLoaderDarwinKernel::KextImageInfo::PutToLog(Log *log) const {
- if (log == NULL)
- return;
- const uint8_t *u = static_cast<const uint8_t *>(m_uuid.GetBytes());
-
if (m_load_address == LLDB_INVALID_ADDRESS) {
- if (u) {
- log->Printf("\tuuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2."
- "2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\" (UNLOADED)",
- u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7], u[8], u[9],
- u[10], u[11], u[12], u[13], u[14], u[15], m_name.c_str());
- } else
- log->Printf("\tname=\"%s\" (UNLOADED)", m_name.c_str());
+ LLDB_LOG(log, "uuid={0} name=\"{1}\" (UNLOADED)", m_uuid.GetAsString(),
+ m_name);
} else {
- if (u) {
- log->Printf("\taddr=0x%16.16" PRIx64 " size=0x%16.16" PRIx64
- " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-"
- "%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\"",
- m_load_address, m_size, u[0], u[1], u[2], u[3], u[4], u[5],
- u[6], u[7], u[8], u[9], u[10], u[11], u[12], u[13], u[14],
- u[15], m_name.c_str());
- } else {
- log->Printf("\t[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") name=\"%s\"",
- m_load_address, m_load_address + m_size, m_name.c_str());
- }
+ LLDB_LOG(log, "addr={0:x+16} size={1:x+16} uuid={2} name=\"{3}\"",
+ m_load_address, m_size, m_uuid.GetAsString(), m_name);
}
}
//----------------------------------------------------------------------
-// Dump the _dyld_all_image_infos members and all current image infos
-// that we have parsed to the file handle provided.
+// Dump the _dyld_all_image_infos members and all current image infos that we
+// have parsed to the file handle provided.
//----------------------------------------------------------------------
void DynamicLoaderDarwinKernel::PutToLog(Log *log) const {
if (log == NULL)
diff --git a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h b/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
index ad4f7c631d84..75998f1cc3be 100644
--- a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
+++ b/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
@@ -17,6 +17,9 @@
#include <vector>
// Other libraries and framework includes
+
+#include "lldb/Utility/SafeMachO.h"
+
// Project includes
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Process.h"
@@ -284,6 +287,9 @@ protected:
static lldb::addr_t
SearchForKernelViaExhaustiveSearch(lldb_private::Process *process);
+ static bool
+ ReadMachHeader(lldb::addr_t addr, lldb_private::Process *process, llvm::MachO::mach_header &mh);
+
static lldb_private::UUID
CheckForKernelImageAtAddress(lldb::addr_t addr,
lldb_private::Process *process);
diff --git a/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp b/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
index d0d60017e869..5ca20229d018 100644
--- a/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
+++ b/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
@@ -127,8 +127,8 @@ void DynamicLoaderHexagonDYLD::DidAttach() {
executable = GetTargetExecutable();
- // Find the difference between the desired load address in the elf file
- // and the real load address in memory
+ // Find the difference between the desired load address in the elf file and
+ // the real load address in memory
load_offset = ComputeLoadOffset();
// Check that there is a valid executable
@@ -157,10 +157,10 @@ void DynamicLoaderHexagonDYLD::DidAttach() {
// Callback for the target to give it the loaded module list
m_process->GetTarget().ModulesDidLoad(module_list);
- // Try to set a breakpoint at the rendezvous breakpoint.
- // DidLaunch uses ProbeEntry() instead. That sets a breakpoint,
- // at the dyld breakpoint address, with a callback so that when hit,
- // the dyld structure can be parsed.
+ // Try to set a breakpoint at the rendezvous breakpoint. DidLaunch uses
+ // ProbeEntry() instead. That sets a breakpoint, at the dyld breakpoint
+ // address, with a callback so that when hit, the dyld structure can be
+ // parsed.
if (!SetRendezvousBreakpoint()) {
// fail
}
@@ -203,8 +203,8 @@ ModuleSP DynamicLoaderHexagonDYLD::GetTargetExecutable() {
// TODO: What case is this code used?
executable = target.GetSharedModule(module_spec);
if (executable.get() != target.GetExecutableModulePointer()) {
- // Don't load dependent images since we are in dyld where we will know
- // and find out about all images that are loaded
+ // Don't load dependent images since we are in dyld where we will know and
+ // find out about all images that are loaded
const bool get_dependent_images = false;
target.SetExecutableModule(executable, get_dependent_images);
}
@@ -270,9 +270,8 @@ bool DynamicLoaderHexagonDYLD::SetRendezvousBreakpoint() {
// This is the original code, which want to look in the rendezvous structure
// to find the breakpoint address. Its backwards for us, since we can easily
- // find the breakpoint address, since it is exported in our executable.
- // We however know that we cant read the Rendezvous structure until we have
- // hit
+ // find the breakpoint address, since it is exported in our executable. We
+ // however know that we cant read the Rendezvous structure until we have hit
// the breakpoint once.
const ConstString dyldBpName("_rtld_debug_state");
addr_t break_addr = findSymbolAddress(m_process, dyldBpName);
@@ -326,8 +325,8 @@ bool DynamicLoaderHexagonDYLD::RendezvousBreakpointHit(
DynamicLoaderHexagonDYLD *dyld_instance = nullptr;
dyld_instance = static_cast<DynamicLoaderHexagonDYLD *>(baton);
- // if the dyld_instance is still not valid then
- // try to locate it on the symbol table
+ // if the dyld_instance is still not valid then try to locate it on the
+ // symbol table
if (!dyld_instance->m_rendezvous.IsValid()) {
Process *proc = dyld_instance->m_process;
@@ -480,8 +479,8 @@ void DynamicLoaderHexagonDYLD::LoadAllCurrentModules() {
return;
}
- // The rendezvous class doesn't enumerate the main module, so track
- // that ourselves here.
+ // The rendezvous class doesn't enumerate the main module, so track that
+ // ourselves here.
ModuleSP executable = GetTargetExecutable();
m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress();
@@ -517,12 +516,11 @@ addr_t DynamicLoaderHexagonDYLD::ComputeLoadOffset() {
return 0;
}
-// Here we must try to read the entry point directly from
-// the elf header. This is possible if the process is not
-// relocatable or dynamically linked.
+// Here we must try to read the entry point directly from the elf header. This
+// is possible if the process is not relocatable or dynamically linked.
//
-// an alternative is to look at the PC if we can be sure
-// that we have connected when the process is at the entry point.
+// an alternative is to look at the PC if we can be sure that we have connected
+// when the process is at the entry point.
// I dont think that is reliable for us.
addr_t DynamicLoaderHexagonDYLD::GetEntryPoint() {
if (m_entry_point != LLDB_INVALID_ADDRESS)
diff --git a/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp b/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
index c49cdc2f11b1..d5f60e07bd77 100644
--- a/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
+++ b/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
@@ -115,8 +115,8 @@ bool HexagonDYLDRendezvous::UpdateSOEntries() {
if (m_current.map_addr == 0)
return false;
- // When the previous and current states are consistent this is the first
- // time we have been asked to update. Just take a snapshot of the currently
+ // When the previous and current states are consistent this is the first time
+ // we have been asked to update. Just take a snapshot of the currently
// loaded modules.
if (m_previous.state == eConsistent && m_current.state == eConsistent)
return TakeSnapshot(m_soentries);
@@ -126,8 +126,8 @@ bool HexagonDYLDRendezvous::UpdateSOEntries() {
if (m_current.state == eAdd || m_current.state == eDelete) {
// this is a fudge so that we can clear the assert below.
m_previous.state = eConsistent;
- // We hit this assert on the 2nd run of this function after running the calc
- // example
+ // We hit this assert on the 2nd run of this function after running the
+ // calc example
assert(m_previous.state == eConsistent);
m_soentries.clear();
m_added_soentries.clear();
@@ -159,9 +159,9 @@ bool HexagonDYLDRendezvous::UpdateSOEntriesForAddition() {
if (!ReadSOEntryFromMemory(cursor, entry))
return false;
- // Only add shared libraries and not the executable.
- // On Linux this is indicated by an empty path in the entry.
- // On FreeBSD it is the name of the executable.
+ // Only add shared libraries and not the executable. On Linux this is
+ // indicated by an empty path in the entry. On FreeBSD it is the name of
+ // the executable.
if (entry.path.empty() || ::strcmp(entry.path.c_str(), m_exe_path) == 0)
continue;
@@ -204,9 +204,9 @@ bool HexagonDYLDRendezvous::TakeSnapshot(SOEntryList &entry_list) {
if (!ReadSOEntryFromMemory(cursor, entry))
return false;
- // Only add shared libraries and not the executable.
- // On Linux this is indicated by an empty path in the entry.
- // On FreeBSD it is the name of the executable.
+ // Only add shared libraries and not the executable. On Linux this is
+ // indicated by an empty path in the entry. On FreeBSD it is the name of
+ // the executable.
if (entry.path.empty() || ::strcmp(entry.path.c_str(), m_exe_path) == 0)
continue;
diff --git a/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h b/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
index b68f89b9ce83..bdf6bae75197 100644
--- a/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
+++ b/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
@@ -11,8 +11,10 @@
#define liblldb_HexagonDYLDRendezvous_H_
// C Includes
+#include <limits.h> // for PATH_MAX
// C++ Includes
#include <list>
+#include <map>
#include <string>
// Other libraries and framework includes
@@ -24,12 +26,12 @@ class Process;
}
/// @class HexagonDYLDRendezvous
-/// @brief Interface to the runtime linker.
+/// Interface to the runtime linker.
///
/// A structure is present in a processes memory space which is updated by the
-/// runtime liker each time a module is loaded or unloaded. This class provides
-/// an interface to this structure and maintains a consistent snapshot of the
-/// currently loaded modules.
+/// runtime liker each time a module is loaded or unloaded. This class
+/// provides an interface to this structure and maintains a consistent
+/// snapshot of the currently loaded modules.
class HexagonDYLDRendezvous {
// This structure is used to hold the contents of the debug rendezvous
@@ -124,7 +126,7 @@ public:
void DumpToLog(lldb_private::Log *log) const;
- /// @brief Constants describing the state of the rendezvous.
+ /// Constants describing the state of the rendezvous.
///
/// @see GetState().
enum RendezvousState {
@@ -133,8 +135,8 @@ public:
eDelete,
};
- /// @brief Structure representing the shared objects currently loaded into
- /// the inferior process.
+ /// Structure representing the shared objects currently loaded into the
+ /// inferior process.
///
/// This object is a rough analogue to the struct link_map object which
/// actually lives in the inferiors memory.
@@ -198,7 +200,8 @@ protected:
/// List of SOEntry objects corresponding to the current link map state.
SOEntryList m_soentries;
- /// List of SOEntry's added to the link map since the last call to Resolve().
+ /// List of SOEntry's added to the link map since the last call to
+ /// Resolve().
SOEntryList m_added_soentries;
/// List of SOEntry's removed from the link map since the last call to
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
index 703b461f6fe1..c6439a30c8a3 100644
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
@@ -112,8 +112,8 @@ ModuleSP DynamicLoaderDarwin::FindTargetModuleForImageInfo(
if (module_sp && !module_spec.GetUUID().IsValid() &&
!module_sp->GetUUID().IsValid()) {
- // No UUID, we must rely upon the cached module modification
- // time and the modification time of the file on disk
+ // No UUID, we must rely upon the cached module modification time and the
+ // modification time of the file on disk
if (module_sp->GetModificationTime() !=
FileSystem::GetModificationTime(module_sp->GetFileSpec()))
module_sp.reset();
@@ -198,8 +198,7 @@ void DynamicLoaderDarwin::UnloadAllImages() {
ModuleSP module_sp = target_modules.GetModuleAtIndexUnlocked(i);
// Don't remove dyld - else we'll lose our breakpoint notifying us about
- // libraries
- // being re-loaded...
+ // libraries being re-loaded...
if (module_sp.get() != nullptr && module_sp.get() != dyld_sp.get()) {
UnloadSections(module_sp);
unloaded_modules_list.Append(module_sp);
@@ -219,8 +218,8 @@ void DynamicLoaderDarwin::UnloadAllImages() {
}
//----------------------------------------------------------------------
-// Update the load addresses for all segments in MODULE using the
-// updated INFO that is passed in.
+// Update the load addresses for all segments in MODULE using the updated INFO
+// that is passed in.
//----------------------------------------------------------------------
bool DynamicLoaderDarwin::UpdateImageLoadAddress(Module *module,
ImageInfo &info) {
@@ -231,13 +230,12 @@ bool DynamicLoaderDarwin::UpdateImageLoadAddress(Module *module,
SectionList *section_list = image_object_file->GetSectionList();
if (section_list) {
std::vector<uint32_t> inaccessible_segment_indexes;
- // We now know the slide amount, so go through all sections
- // and update the load addresses with the correct values.
+ // We now know the slide amount, so go through all sections and update
+ // the load addresses with the correct values.
const size_t num_segments = info.segments.size();
for (size_t i = 0; i < num_segments; ++i) {
- // Only load a segment if it has protections. Things like
- // __PAGEZERO don't have any protections, and they shouldn't
- // be slid
+ // Only load a segment if it has protections. Things like __PAGEZERO
+ // don't have any protections, and they shouldn't be slid
SectionSP section_sp(
section_list->FindSectionByName(info.segments[i].name));
@@ -249,10 +247,10 @@ bool DynamicLoaderDarwin::UpdateImageLoadAddress(Module *module,
static ConstString g_section_name_LINKEDIT("__LINKEDIT");
if (section_sp) {
- // __LINKEDIT sections from files in the shared cache
- // can overlap so check to see what the segment name is
- // and pass "false" so we don't warn of overlapping
- // "Section" objects, and "true" for all other sections.
+ // __LINKEDIT sections from files in the shared cache can overlap
+ // so check to see what the segment name is and pass "false" so
+ // we don't warn of overlapping "Section" objects, and "true" for
+ // all other sections.
const bool warn_multiple =
section_sp->GetName() != g_section_name_LINKEDIT;
@@ -270,13 +268,12 @@ bool DynamicLoaderDarwin::UpdateImageLoadAddress(Module *module,
}
}
- // If the loaded the file (it changed) and we have segments that
- // are not readable or writeable, add them to the invalid memory
- // region cache for the process. This will typically only be
- // the __PAGEZERO segment in the main executable. We might be able
- // to apply this more generally to more sections that have no
- // protections in the future, but for now we are going to just
- // do __PAGEZERO.
+ // If the loaded the file (it changed) and we have segments that are
+ // not readable or writeable, add them to the invalid memory region
+ // cache for the process. This will typically only be the __PAGEZERO
+ // segment in the main executable. We might be able to apply this more
+ // generally to more sections that have no protections in the future,
+ // but for now we are going to just do __PAGEZERO.
if (changed && !inaccessible_segment_indexes.empty()) {
for (uint32_t i = 0; i < inaccessible_segment_indexes.size(); ++i) {
const uint32_t seg_idx = inaccessible_segment_indexes[i];
@@ -344,8 +341,7 @@ bool DynamicLoaderDarwin::UnloadModuleSections(Module *module,
}
// Given a JSON dictionary (from debugserver, most likely) of binary images
-// loaded in the inferior
-// process, add the images to the ImageInfo collection.
+// loaded in the inferior process, add the images to the ImageInfo collection.
bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo(
StructuredData::ObjectSP image_details,
@@ -378,7 +374,8 @@ bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo(
image_infos[i].mod_date =
image->GetValueForKey("mod_date")->GetAsInteger()->GetValue();
image_infos[i].file_spec.SetFile(
- image->GetValueForKey("pathname")->GetAsString()->GetValue(), false);
+ image->GetValueForKey("pathname")->GetAsString()->GetValue(), false,
+ FileSpec::Style::native);
StructuredData::Dictionary *mh =
image->GetValueForKey("mach_header")->GetAsDictionary();
@@ -412,8 +409,7 @@ bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo(
}
// Fields that aren't used by DynamicLoaderDarwin so debugserver doesn't
- // currently send them
- // in the reply.
+ // currently send them in the reply.
if (mh->HasKey("flags"))
image_infos[i].header.flags =
@@ -454,8 +450,7 @@ bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo(
seg->GetValueForKey("maxprot")->GetAsInteger()->GetValue();
// Fields that aren't used by DynamicLoaderDarwin so debugserver doesn't
- // currently send them
- // in the reply.
+ // currently send them in the reply.
if (seg->HasKey("initprot"))
segment.initprot =
@@ -481,25 +476,23 @@ bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo(
image_infos[i].uuid.SetFromStringRef(
image->GetValueForKey("uuid")->GetAsString()->GetValue());
- // All sections listed in the dyld image info structure will all
- // either be fixed up already, or they will all be off by a single
- // slide amount that is determined by finding the first segment
- // that is at file offset zero which also has bytes (a file size
- // that is greater than zero) in the object file.
+ // All sections listed in the dyld image info structure will all either be
+ // fixed up already, or they will all be off by a single slide amount that
+ // is determined by finding the first segment that is at file offset zero
+ // which also has bytes (a file size that is greater than zero) in the
+ // object file.
// Determine the slide amount (if any)
const size_t num_sections = image_infos[i].segments.size();
for (size_t k = 0; k < num_sections; ++k) {
- // Iterate through the object file sections to find the
- // first section that starts of file offset zero and that
- // has bytes in the file...
+ // Iterate through the object file sections to find the first section
+ // that starts of file offset zero and that has bytes in the file...
if ((image_infos[i].segments[k].fileoff == 0 &&
image_infos[i].segments[k].filesize > 0) ||
(image_infos[i].segments[k].name == ConstString("__TEXT"))) {
image_infos[i].slide =
image_infos[i].address - image_infos[i].segments[k].vmaddr;
- // We have found the slide amount, so we can exit
- // this for loop.
+ // We have found the slide amount, so we can exit this for loop.
break;
}
}
@@ -520,16 +513,15 @@ void DynamicLoaderDarwin::UpdateSpecialBinariesFromNewImageInfos(
const size_t image_infos_size = image_infos.size();
for (size_t i = 0; i < image_infos_size; i++) {
if (image_infos[i].header.filetype == llvm::MachO::MH_DYLINKER) {
- // In a "simulator" process (an x86 process that is ios/tvos/watchos)
- // we will have two dyld modules -- a "dyld" that we want to keep track
- // of,
- // and a "dyld_sim" which we don't need to keep track of here.
- // If the target is an x86 system and the OS of the dyld binary is
+ // In a "simulator" process (an x86 process that is ios/tvos/watchos) we
+ // will have two dyld modules -- a "dyld" that we want to keep track of,
+ // and a "dyld_sim" which we don't need to keep track of here. If the
+ // target is an x86 system and the OS of the dyld binary is
// ios/tvos/watchos, then we are looking at dyld_sym.
- // debugserver has only recently (late 2016) started sending up the
- // os type for each binary it sees -- so if we don't have an os
- // type, use a filename check as our next best guess.
+ // debugserver has only recently (late 2016) started sending up the os
+ // type for each binary it sees -- so if we don't have an os type, use a
+ // filename check as our next best guess.
if (image_infos[i].os_type == llvm::Triple::OSType::UnknownOS) {
if (image_infos[i].file_spec.GetFilename() != g_dyld_sim_filename) {
dyld_idx = i;
@@ -543,7 +535,8 @@ void DynamicLoaderDarwin::UpdateSpecialBinariesFromNewImageInfos(
}
}
else {
- // catch-all for any other environment -- trust that dyld is actually dyld
+ // catch-all for any other environment -- trust that dyld is actually
+ // dyld
dyld_idx = i;
}
} else if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE) {
@@ -669,11 +662,10 @@ bool DynamicLoaderDarwin::AddModulesUsingImageInfos(
}
}
- // UpdateImageLoadAddress will return true if any segments
- // change load address. We need to check this so we don't
- // mention that all loaded shared libraries are newly loaded
- // each time we hit out dyld breakpoint since dyld will list all
- // shared libraries each time.
+ // UpdateImageLoadAddress will return true if any segments change load
+ // address. We need to check this so we don't mention that all loaded
+ // shared libraries are newly loaded each time we hit out dyld breakpoint
+ // since dyld will list all shared libraries each time.
if (UpdateImageLoadAddress(image_module_sp.get(), image_infos[idx])) {
target_images.AppendIfNeeded(image_module_sp);
loaded_module_list.AppendIfNeeded(image_module_sp);
@@ -692,12 +684,11 @@ bool DynamicLoaderDarwin::AddModulesUsingImageInfos(
//----------------------------------------------------------------------
// On Mac OS X libobjc (the Objective-C runtime) has several critical dispatch
-// functions written in hand-written assembly, and also have hand-written unwind
-// information in the eh_frame section. Normally we prefer analyzing the
-// assembly instructions of a currently executing frame to unwind from that
-// frame --
-// but on hand-written functions this profiling can fail. We should use the
-// eh_frame instructions for these functions all the time.
+// functions written in hand-written assembly, and also have hand-written
+// unwind information in the eh_frame section. Normally we prefer analyzing
+// the assembly instructions of a currently executing frame to unwind from that
+// frame -- but on hand-written functions this profiling can fail. We should
+// use the eh_frame instructions for these functions all the time.
//
// As an aside, it would be better if the eh_frame entries had a flag (or were
// extensible so they could have an Apple-specific flag) which indicates that
@@ -756,35 +747,14 @@ DynamicLoaderDarwin::ImageInfo::FindSegment(const ConstString &name) const {
// Dump an image info structure to the file handle provided.
//----------------------------------------------------------------------
void DynamicLoaderDarwin::ImageInfo::PutToLog(Log *log) const {
- if (log == NULL)
+ if (!log)
return;
- const uint8_t *u = (const uint8_t *)uuid.GetBytes();
-
if (address == LLDB_INVALID_ADDRESS) {
- if (u) {
- log->Printf("\t modtime=0x%8.8" PRIx64
- " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-"
- "%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s' (UNLOADED)",
- mod_date, u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7],
- u[8], u[9], u[10], u[11], u[12], u[13], u[14], u[15],
- file_spec.GetPath().c_str());
- } else
- log->Printf("\t modtime=0x%8.8" PRIx64
- " path='%s' (UNLOADED)",
- mod_date, file_spec.GetPath().c_str());
+ LLDB_LOG(log, "modtime={0:x+8} uuid={1} path='{2}' (UNLOADED)", mod_date,
+ uuid.GetAsString(), file_spec.GetPath());
} else {
- if (u) {
- log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64
- " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-"
- "%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s'",
- address, mod_date, u[0], u[1], u[2], u[3], u[4], u[5], u[6],
- u[7], u[8], u[9], u[10], u[11], u[12], u[13], u[14], u[15],
- file_spec.GetPath().c_str());
- } else {
- log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64
- " path='%s'",
- address, mod_date, file_spec.GetPath().c_str());
- }
+ LLDB_LOG(log, "address={0:x+16} modtime={1:x+8} uuid={2} path='{3}'",
+ address, mod_date, uuid.GetAsString(), file_spec.GetPath());
for (uint32_t i = 0; i < segments.size(); ++i)
segments[i].PutToLog(log, slide);
}
@@ -817,8 +787,8 @@ void DynamicLoaderDarwin::PrivateProcessStateChanged(Process *process,
break;
case eStateStopped:
- // Keep trying find dyld and set our notification breakpoint each time
- // we stop until we succeed
+ // Keep trying find dyld and set our notification breakpoint each time we
+ // stop until we succeed
if (!DidSetNotificationBreakpoint() && m_process->IsAlive()) {
if (NeedToDoInitialImageFetch())
DoInitialImageFetch();
@@ -956,8 +926,8 @@ DynamicLoaderDarwin::GetStepThroughTrampolinePlan(Thread &thread,
}
if (addresses.size() > 0) {
- // First check whether any of the addresses point to Indirect symbols, and
- // if they do, resolve them:
+ // First check whether any of the addresses point to Indirect symbols,
+ // and if they do, resolve them:
std::vector<lldb::addr_t> load_addrs;
for (Address address : addresses) {
Symbol *symbol = address.CalculateSymbolContextSymbol();
@@ -1073,10 +1043,10 @@ DynamicLoaderDarwin::GetThreadLocalData(const lldb::ModuleSP module_sp,
const lldb::addr_t pthread_key = data.GetAddress(&offset);
const lldb::addr_t tls_offset = data.GetAddress(&offset);
if (pthread_key != 0) {
- // First check to see if we have already figured out the location
- // of TLS data for the pthread_key on a specific thread yet. If we
- // have we can re-use it since its location will not change unless
- // the process execs.
+ // First check to see if we have already figured out the location of
+ // TLS data for the pthread_key on a specific thread yet. If we have we
+ // can re-use it since its location will not change unless the process
+ // execs.
const tid_t tid = thread_sp->GetID();
auto tid_pos = m_tid_to_tls_map.find(tid);
if (tid_pos != m_tid_to_tls_map.end()) {
@@ -1131,34 +1101,29 @@ DynamicLoaderDarwin::GetThreadLocalData(const lldb::ModuleSP module_sp,
bool DynamicLoaderDarwin::UseDYLDSPI(Process *process) {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- uint32_t major, minor, update;
-
bool use_new_spi_interface = false;
- if (process->GetHostOSVersion(major, minor, update)) {
+ llvm::VersionTuple version = process->GetHostOSVersion();
+ if (!version.empty()) {
const llvm::Triple::OSType os_type =
process->GetTarget().GetArchitecture().GetTriple().getOS();
// macOS 10.12 and newer
if (os_type == llvm::Triple::MacOSX &&
- (major > 10 || (major == 10 && minor >= 12))) {
+ version >= llvm::VersionTuple(10, 12))
use_new_spi_interface = true;
- }
// iOS 10 and newer
- if (os_type == llvm::Triple::IOS && major >= 10) {
+ if (os_type == llvm::Triple::IOS && version >= llvm::VersionTuple(10))
use_new_spi_interface = true;
- }
// tvOS 10 and newer
- if (os_type == llvm::Triple::TvOS && major >= 10) {
+ if (os_type == llvm::Triple::TvOS && version >= llvm::VersionTuple(10))
use_new_spi_interface = true;
- }
// watchOS 3 and newer
- if (os_type == llvm::Triple::WatchOS && major >= 3) {
+ if (os_type == llvm::Triple::WatchOS && version >= llvm::VersionTuple(3))
use_new_spi_interface = true;
- }
}
if (log) {
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
index 66085a23759b..4a8ad38d1785 100644
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
@@ -29,9 +29,9 @@ using namespace lldb;
using namespace lldb_private;
//----------------------------------------------------------------------
-// Create an instance of this class. This function is filled into
-// the plugin info class that gets handed out by the plugin factory and
-// allows the lldb to instantiate an instance of this class.
+// Create an instance of this class. This function is filled into the plugin
+// info class that gets handed out by the plugin factory and allows the lldb to
+// instantiate an instance of this class.
//----------------------------------------------------------------------
DynamicLoader *DynamicLoaderMacOS::CreateInstance(Process *process,
bool force) {
@@ -144,17 +144,18 @@ void DynamicLoaderMacOS::ClearNotificationBreakpoint() {
}
//----------------------------------------------------------------------
-// Try and figure out where dyld is by first asking the Process
-// if it knows (which currently calls down in the lldb::Process
-// to get the DYLD info (available on SnowLeopard only). If that fails,
-// then check in the default addresses.
+// Try and figure out where dyld is by first asking the Process if it knows
+// (which currently calls down in the lldb::Process to get the DYLD info
+// (available on SnowLeopard only). If that fails, then check in the default
+// addresses.
//----------------------------------------------------------------------
void DynamicLoaderMacOS::DoInitialImageFetch() {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- // Remove any binaries we pre-loaded in the Target before launching/attaching.
- // If the same binaries are present in the process, we'll get them from the
- // shared module cache, we won't need to re-load them from disk.
+ // Remove any binaries we pre-loaded in the Target before
+ // launching/attaching. If the same binaries are present in the process,
+ // we'll get them from the shared module cache, we won't need to re-load them
+ // from disk.
UnloadAllImages();
StructuredData::ObjectSP all_image_info_json_sp(
@@ -184,9 +185,9 @@ bool DynamicLoaderMacOS::NeedToDoInitialImageFetch() { return true; }
//----------------------------------------------------------------------
// Static callback function that gets called when our DYLD notification
-// breakpoint gets hit. We update all of our image infos and then
-// let our super class DynamicLoader class decide if we should stop
-// or not (based on global preference).
+// breakpoint gets hit. We update all of our image infos and then let our super
+// class DynamicLoader class decide if we should stop or not (based on global
+// preference).
//----------------------------------------------------------------------
bool DynamicLoaderMacOS::NotifyBreakpointHit(void *baton,
StoppointCallbackContext *context,
@@ -194,11 +195,10 @@ bool DynamicLoaderMacOS::NotifyBreakpointHit(void *baton,
lldb::user_id_t break_loc_id) {
// Let the event know that the images have changed
// DYLD passes three arguments to the notification breakpoint.
- // Arg1: enum dyld_notify_mode mode - 0 = adding, 1 = removing, 2 = remove all
- // Arg2: unsigned long icount - Number of shared libraries
- // added/removed
- // Arg3: uint64_t mach_headers[] - Array of load addresses of binaries
- // added/removed
+ // Arg1: enum dyld_notify_mode mode - 0 = adding, 1 = removing, 2 = remove
+ // all Arg2: unsigned long icount - Number of shared libraries
+ // added/removed Arg3: uint64_t mach_headers[] - Array of load addresses
+ // of binaries added/removed
DynamicLoaderMacOS *dyld_instance = (DynamicLoaderMacOS *)baton;
@@ -328,8 +328,8 @@ void DynamicLoaderMacOS::AddBinaries(
}
}
-// Dump the _dyld_all_image_infos members and all current image infos
-// that we have parsed to the file handle provided.
+// Dump the _dyld_all_image_infos members and all current image infos that we
+// have parsed to the file handle provided.
//----------------------------------------------------------------------
void DynamicLoaderMacOS::PutToLog(Log *log) const {
if (log == NULL)
@@ -432,9 +432,9 @@ Status DynamicLoaderMacOS::CanLoadImage() {
}
}
- // Default assumption is that it is OK to load images.
- // Only say that we cannot load images if we find the symbol in libdyld and it
- // indicates that we cannot.
+ // Default assumption is that it is OK to load images. Only say that we
+ // cannot load images if we find the symbol in libdyld and it indicates that
+ // we cannot.
if (symbol_address != LLDB_INVALID_ADDRESS) {
{
@@ -445,11 +445,11 @@ Status DynamicLoaderMacOS::CanLoadImage() {
}
}
} else {
- // If we were unable to find _dyld_global_lock_held in any modules, or it is
- // not loaded into memory yet, we may be at process startup (sitting
- // at _dyld_start) - so we should not allow dlopen calls.
- // But if we found more than one module then we are clearly past _dyld_start
- // so in that case we'll default to "it's safe".
+ // If we were unable to find _dyld_global_lock_held in any modules, or it
+ // is not loaded into memory yet, we may be at process startup (sitting at
+ // _dyld_start) - so we should not allow dlopen calls. But if we found more
+ // than one module then we are clearly past _dyld_start so in that case
+ // we'll default to "it's safe".
if (num_modules <= 1)
error.SetErrorString("could not find the dyld library or "
"the dyld lock symbol");
@@ -472,7 +472,9 @@ bool DynamicLoaderMacOS::GetSharedCacheInformation(
info_dict = info->GetAsDictionary();
}
- // {"shared_cache_base_address":140735683125248,"shared_cache_uuid":"DDB8D70C-C9A2-3561-B2C8-BE48A4F33F96","no_shared_cache":false,"shared_cache_private_cache":false}
+ // {"shared_cache_base_address":140735683125248,"shared_cache_uuid
+ // ":"DDB8D70C-
+ // C9A2-3561-B2C8-BE48A4F33F96","no_shared_cache":false,"shared_cache_private_cache":false}
if (info_dict && info_dict->HasKey("shared_cache_uuid") &&
info_dict->HasKey("no_shared_cache") &&
@@ -482,7 +484,7 @@ bool DynamicLoaderMacOS::GetSharedCacheInformation(
std::string uuid_str =
info_dict->GetValueForKey("shared_cache_uuid")->GetStringValue();
if (!uuid_str.empty())
- uuid.SetFromCString(uuid_str.c_str());
+ uuid.SetFromStringRef(uuid_str);
if (info_dict->GetValueForKey("no_shared_cache")->GetBooleanValue() ==
false)
using_shared_cache = eLazyBoolYes;
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
index e0def58f41c1..265f19d0ca06 100644
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
@@ -49,9 +49,9 @@ using namespace lldb;
using namespace lldb_private;
//----------------------------------------------------------------------
-// Create an instance of this class. This function is filled into
-// the plugin info class that gets handed out by the plugin factory and
-// allows the lldb to instantiate an instance of this class.
+// Create an instance of this class. This function is filled into the plugin
+// info class that gets handed out by the plugin factory and allows the lldb to
+// instantiate an instance of this class.
//----------------------------------------------------------------------
DynamicLoader *DynamicLoaderMacOSXDYLD::CreateInstance(Process *process,
bool force) {
@@ -123,17 +123,18 @@ bool DynamicLoaderMacOSXDYLD::ProcessDidExec() {
const addr_t shlib_addr = m_process->GetImageInfoAddress();
if (m_process_image_addr_is_all_images_infos == true &&
shlib_addr != m_dyld_all_image_infos_addr) {
- // The image info address from the process is the 'dyld_all_image_infos'
- // address and it has changed.
+ // The image info address from the process is the
+ // 'dyld_all_image_infos' address and it has changed.
did_exec = true;
} else if (m_process_image_addr_is_all_images_infos == false &&
shlib_addr == m_dyld.address) {
- // The image info address from the process is the mach_header
- // address for dyld and it has changed.
+ // The image info address from the process is the mach_header address
+ // for dyld and it has changed.
did_exec = true;
} else {
// ASLR might be disabled and dyld could have ended up in the same
- // location. We should try and detect if we are stopped at '_dyld_start'
+ // location. We should try and detect if we are stopped at
+ // '_dyld_start'
ThreadSP thread_sp(m_process->GetThreadList().GetThreadAtIndex(0));
if (thread_sp) {
lldb::StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex(0));
@@ -185,16 +186,15 @@ void DynamicLoaderMacOSXDYLD::ClearNotificationBreakpoint() {
}
//----------------------------------------------------------------------
-// Try and figure out where dyld is by first asking the Process
-// if it knows (which currently calls down in the lldb::Process
-// to get the DYLD info (available on SnowLeopard only). If that fails,
-// then check in the default addresses.
+// Try and figure out where dyld is by first asking the Process if it knows
+// (which currently calls down in the lldb::Process to get the DYLD info
+// (available on SnowLeopard only). If that fails, then check in the default
+// addresses.
//----------------------------------------------------------------------
void DynamicLoaderMacOSXDYLD::DoInitialImageFetch() {
if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS) {
- // Check the image info addr as it might point to the
- // mach header for dyld, or it might point to the
- // dyld_all_image_infos struct
+ // Check the image info addr as it might point to the mach header for dyld,
+ // or it might point to the dyld_all_image_infos struct
const addr_t shlib_addr = m_process->GetImageInfoAddress();
if (shlib_addr != LLDB_INVALID_ADDRESS) {
ByteOrder byte_order =
@@ -255,8 +255,7 @@ void DynamicLoaderMacOSXDYLD::DoInitialImageFetch() {
}
//----------------------------------------------------------------------
-// Assume that dyld is in memory at ADDR and try to parse it's load
-// commands
+// Assume that dyld is in memory at ADDR and try to parse it's load commands
//----------------------------------------------------------------------
bool DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(
lldb::addr_t addr) {
@@ -287,10 +286,10 @@ bool DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(
// Update all image infos
InitializeFromAllImageInfos();
- // If we didn't have an executable before, but now we do, then the
- // dyld module shared pointer might be unique and we may need to add
- // it again (since Target::SetExecutableModule() will clear the
- // images). So append the dyld module back to the list if it is
+ // If we didn't have an executable before, but now we do, then the dyld
+ // module shared pointer might be unique and we may need to add it again
+ // (since Target::SetExecutableModule() will clear the images). So append
+ // the dyld module back to the list if it is
/// unique!
if (dyld_module_sp) {
target.GetImages().AppendIfNeeded(dyld_module_sp);
@@ -315,18 +314,18 @@ bool DynamicLoaderMacOSXDYLD::NeedToDoInitialImageFetch() {
//----------------------------------------------------------------------
// Static callback function that gets called when our DYLD notification
-// breakpoint gets hit. We update all of our image infos and then
-// let our super class DynamicLoader class decide if we should stop
-// or not (based on global preference).
+// breakpoint gets hit. We update all of our image infos and then let our super
+// class DynamicLoader class decide if we should stop or not (based on global
+// preference).
//----------------------------------------------------------------------
bool DynamicLoaderMacOSXDYLD::NotifyBreakpointHit(
void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id,
lldb::user_id_t break_loc_id) {
// Let the event know that the images have changed
// DYLD passes three arguments to the notification breakpoint.
- // Arg1: enum dyld_image_mode mode - 0 = adding, 1 = removing
- // Arg2: uint32_t infoCount - Number of shared libraries added
- // Arg3: dyld_image_info info[] - Array of structs of the form:
+ // Arg1: enum dyld_image_mode mode - 0 = adding, 1 = removing Arg2: uint32_t
+ // infoCount - Number of shared libraries added Arg3: dyld_image_info
+ // info[] - Array of structs of the form:
// const struct mach_header
// *imageLoadAddress
// const char *imageFilePath
@@ -335,11 +334,10 @@ bool DynamicLoaderMacOSXDYLD::NotifyBreakpointHit(
DynamicLoaderMacOSXDYLD *dyld_instance = (DynamicLoaderMacOSXDYLD *)baton;
// First step is to see if we've already initialized the all image infos. If
- // we haven't then this function
- // will do so and return true. In the course of initializing the
- // all_image_infos it will read the complete
- // current state, so we don't need to figure out what has changed from the
- // data passed in to us.
+ // we haven't then this function will do so and return true. In the course
+ // of initializing the all_image_infos it will read the complete current
+ // state, so we don't need to figure out what has changed from the data
+ // passed in to us.
ExecutionContext exe_ctx(context->exe_ctx_ref);
Process *process = exe_ctx.GetProcessPtr();
@@ -388,11 +386,9 @@ bool DynamicLoaderMacOSXDYLD::NotifyBreakpointHit(
argument_values.GetValueAtIndex(1)->GetScalar().UInt(-1);
if (image_infos_count != static_cast<uint32_t>(-1)) {
// Got the number added, now go through the array of added elements,
- // putting out the mach header
- // address, and adding the image.
- // Note, I'm not putting in logging here, since the AddModules &
- // RemoveModules functions do
- // all the logging internally.
+ // putting out the mach header address, and adding the image. Note,
+ // I'm not putting in logging here, since the AddModules &
+ // RemoveModules functions do all the logging internally.
lldb::addr_t image_infos_addr =
argument_values.GetValueAtIndex(2)->GetScalar().ULongLong();
@@ -467,12 +463,12 @@ bool DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure() {
if (m_process->ReadMemory(m_dyld_all_image_infos_addr, buf, 4, error) ==
4) {
m_dyld_all_image_infos.version = data.GetU32(&offset);
- // If anything in the high byte is set, we probably got the byte
- // order incorrect (the process might not have it set correctly
- // yet due to attaching to a program without a specified file).
+ // If anything in the high byte is set, we probably got the byte order
+ // incorrect (the process might not have it set correctly yet due to
+ // attaching to a program without a specified file).
if (m_dyld_all_image_infos.version & 0xff000000) {
- // We have guessed the wrong byte order. Swap it and try
- // reading the version again.
+ // We have guessed the wrong byte order. Swap it and try reading the
+ // version again.
if (byte_order == eByteOrderLittle)
byte_order = eByteOrderBig;
else
@@ -508,21 +504,17 @@ bool DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure() {
uint64_t dyld_all_image_infos_addr = data.GetPointer(&offset);
// When we started, we were given the actual address of the
- // all_image_infos
- // struct (probably via TASK_DYLD_INFO) in memory - this address is
- // stored in
- // m_dyld_all_image_infos_addr and is the most accurate address we have.
+ // all_image_infos struct (probably via TASK_DYLD_INFO) in memory -
+ // this address is stored in m_dyld_all_image_infos_addr and is the
+ // most accurate address we have.
// We read the dyld_all_image_infos struct from memory; it contains its
- // own address.
- // If the address in the struct does not match the actual address,
- // the dyld we're looking at has been loaded at a different location
- // (slid) from
- // where it intended to load. The addresses in the dyld_all_image_infos
- // struct
- // are the original, non-slid addresses, and need to be adjusted. Most
- // importantly
- // the address of dyld and the notification address need to be adjusted.
+ // own address. If the address in the struct does not match the actual
+ // address, the dyld we're looking at has been loaded at a different
+ // location (slid) from where it intended to load. The addresses in
+ // the dyld_all_image_infos struct are the original, non-slid
+ // addresses, and need to be adjusted. Most importantly the address of
+ // dyld and the notification address need to be adjusted.
if (dyld_all_image_infos_addr != m_dyld_all_image_infos_addr) {
uint64_t image_infos_offset =
@@ -615,14 +607,13 @@ bool DynamicLoaderMacOSXDYLD::RemoveModulesUsingImageInfosAddress(
image_infos[idx].PutToLog(log);
}
- // Remove this image_infos from the m_all_image_infos. We do the comparison
- // by address
- // rather than by file spec because we can have many modules with the same
- // "file spec" in the
- // case that they are modules loaded from memory.
+ // Remove this image_infos from the m_all_image_infos. We do the
+ // comparison by address rather than by file spec because we can have many
+ // modules with the same "file spec" in the case that they are modules
+ // loaded from memory.
//
- // Also copy over the uuid from the old entry to the removed entry so we can
- // use it to lookup the module in the module list.
+ // Also copy over the uuid from the old entry to the removed entry so we
+ // can use it to lookup the module in the module list.
ImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
for (pos = m_dyld_image_infos.begin(); pos != end; pos++) {
@@ -630,8 +621,7 @@ bool DynamicLoaderMacOSXDYLD::RemoveModulesUsingImageInfosAddress(
image_infos[idx].uuid = (*pos).uuid;
// Add the module from this image_info to the "unloaded_module_list".
- // We'll remove them all at
- // one go later on.
+ // We'll remove them all at one go later on.
ModuleSP unload_image_module_sp(
FindTargetModuleForImageInfo(image_infos[idx], false, NULL));
@@ -703,7 +693,8 @@ bool DynamicLoaderMacOSXDYLD::ReadImageInfos(
// don't resolve the path
if (error.Success()) {
const bool resolve_path = false;
- image_infos[i].file_spec.SetFile(raw_path, resolve_path);
+ image_infos[i].file_spec.SetFile(raw_path, resolve_path,
+ FileSpec::Style::native);
}
}
return true;
@@ -713,11 +704,10 @@ bool DynamicLoaderMacOSXDYLD::ReadImageInfos(
}
//----------------------------------------------------------------------
-// If we have found where the "_dyld_all_image_infos" lives in memory,
-// read the current info from it, and then update all image load
-// addresses (or lack thereof). Only do this if this is the first time
-// we're reading the dyld infos. Return true if we actually read anything,
-// and false otherwise.
+// If we have found where the "_dyld_all_image_infos" lives in memory, read the
+// current info from it, and then update all image load addresses (or lack
+// thereof). Only do this if this is the first time we're reading the dyld
+// infos. Return true if we actually read anything, and false otherwise.
//----------------------------------------------------------------------
bool DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos() {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
@@ -748,14 +738,11 @@ bool DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos() {
}
// Now we have one more bit of business. If there is a library left in the
- // images for our target that
- // doesn't have a load address, then it must be something that we were
- // expecting to load (for instance we
- // read a load command for it) but it didn't in fact load - probably because
- // DYLD_*_PATH pointed
- // to an equivalent version. We don't want it to stay in the target's
- // module list or it will confuse
- // us, so unload it here.
+ // images for our target that doesn't have a load address, then it must be
+ // something that we were expecting to load (for instance we read a load
+ // command for it) but it didn't in fact load - probably because
+ // DYLD_*_PATH pointed to an equivalent version. We don't want it to stay
+ // in the target's module list or it will confuse us, so unload it here.
Target &target = m_process->GetTarget();
const ModuleList &target_modules = target.GetImages();
ModuleList not_loaded_modules;
@@ -784,8 +771,8 @@ bool DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos() {
}
//----------------------------------------------------------------------
-// Read a mach_header at ADDR into HEADER, and also fill in the load
-// command data into LOAD_COMMAND_DATA if it is non-NULL.
+// Read a mach_header at ADDR into HEADER, and also fill in the load command
+// data into LOAD_COMMAND_DATA if it is non-NULL.
//
// Returns true if we succeed, false if we fail for any reason.
//----------------------------------------------------------------------
@@ -840,8 +827,8 @@ bool DynamicLoaderMacOSXDYLD::ReadMachHeader(lldb::addr_t addr,
load_cmd_data_sp->GetByteSize(), error);
if (load_cmd_bytes_read == header->sizeofcmds) {
- // Set the load command data and also set the correct endian
- // swap settings and the correct address size
+ // Set the load command data and also set the correct endian swap
+ // settings and the correct address size
load_command_data->SetData(load_cmd_data_sp, 0, header->sizeofcmds);
load_command_data->SetByteOrder(data.GetByteOrder());
load_command_data->SetAddressByteSize(data.GetAddressByteSize());
@@ -867,8 +854,8 @@ uint32_t DynamicLoaderMacOSXDYLD::ParseLoadCommands(const DataExtractor &data,
dylib_info.Clear(true);
for (cmd_idx = 0; cmd_idx < dylib_info.header.ncmds; cmd_idx++) {
- // Clear out any load command specific data from DYLIB_INFO since
- // we are about to read it.
+ // Clear out any load command specific data from DYLIB_INFO since we are
+ // about to read it.
if (data.ValidOffsetForDataOfSize(offset,
sizeof(llvm::MachO::load_command))) {
@@ -880,8 +867,8 @@ uint32_t DynamicLoaderMacOSXDYLD::ParseLoadCommands(const DataExtractor &data,
case llvm::MachO::LC_SEGMENT: {
segment.name.SetTrimmedCStringWithLength(
(const char *)data.GetData(&offset, 16), 16);
- // We are putting 4 uint32_t values 4 uint64_t values so
- // we have to use multiple 32 bit gets below.
+ // We are putting 4 uint32_t values 4 uint64_t values so we have to use
+ // multiple 32 bit gets below.
segment.vmaddr = data.GetU32(&offset);
segment.vmsize = data.GetU32(&offset);
segment.fileoff = data.GetU32(&offset);
@@ -906,12 +893,12 @@ uint32_t DynamicLoaderMacOSXDYLD::ParseLoadCommands(const DataExtractor &data,
const lldb::offset_t name_offset =
load_cmd_offset + data.GetU32(&offset);
const char *path = data.PeekCStr(name_offset);
- lc_id_dylinker->SetFile(path, true);
+ lc_id_dylinker->SetFile(path, true, FileSpec::Style::native);
}
break;
case llvm::MachO::LC_UUID:
- dylib_info.uuid.SetBytes(data.GetData(&offset, 16));
+ dylib_info.uuid = UUID::fromOptionalData(data.GetData(&offset, 16), 16);
break;
default:
@@ -922,24 +909,21 @@ uint32_t DynamicLoaderMacOSXDYLD::ParseLoadCommands(const DataExtractor &data,
}
}
- // All sections listed in the dyld image info structure will all
- // either be fixed up already, or they will all be off by a single
- // slide amount that is determined by finding the first segment
- // that is at file offset zero which also has bytes (a file size
- // that is greater than zero) in the object file.
+ // All sections listed in the dyld image info structure will all either be
+ // fixed up already, or they will all be off by a single slide amount that is
+ // determined by finding the first segment that is at file offset zero which
+ // also has bytes (a file size that is greater than zero) in the object file.
// Determine the slide amount (if any)
const size_t num_sections = dylib_info.segments.size();
for (size_t i = 0; i < num_sections; ++i) {
- // Iterate through the object file sections to find the
- // first section that starts of file offset zero and that
- // has bytes in the file...
+ // Iterate through the object file sections to find the first section that
+ // starts of file offset zero and that has bytes in the file...
if ((dylib_info.segments[i].fileoff == 0 &&
dylib_info.segments[i].filesize > 0) ||
(dylib_info.segments[i].name == ConstString("__TEXT"))) {
dylib_info.slide = dylib_info.address - dylib_info.segments[i].vmaddr;
- // We have found the slide amount, so we can exit
- // this for loop.
+ // We have found the slide amount, so we can exit this for loop.
break;
}
}
@@ -984,11 +968,11 @@ void DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(
// Don't load dependent images since we are in dyld where we will know
// and find out about all images that are loaded. Also when setting the
// executable module, it will clear the targets module list, and if we
- // have an in memory dyld module, it will get removed from the list
- // so we will need to add it back after setting the executable module,
- // so we first try and see if we already have a weak pointer to the
- // dyld module, make it into a shared pointer, then add the executable,
- // then re-add it back to make sure it is always in the list.
+ // have an in memory dyld module, it will get removed from the list so
+ // we will need to add it back after setting the executable module, so
+ // we first try and see if we already have a weak pointer to the dyld
+ // module, make it into a shared pointer, then add the executable, then
+ // re-add it back to make sure it is always in the list.
ModuleSP dyld_module_sp(GetDYLDModule());
const bool get_dependent_images = false;
@@ -1009,8 +993,8 @@ void DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(
}
//----------------------------------------------------------------------
-// Dump the _dyld_all_image_infos members and all current image infos
-// that we have parsed to the file handle provided.
+// Dump the _dyld_all_image_infos members and all current image infos that we
+// have parsed to the file handle provided.
//----------------------------------------------------------------------
void DynamicLoaderMacOSXDYLD::PutToLog(Log *log) const {
if (log == NULL)
@@ -1039,10 +1023,9 @@ bool DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint() {
if (m_break_id == LLDB_INVALID_BREAK_ID) {
if (m_dyld_all_image_infos.notification != LLDB_INVALID_ADDRESS) {
Address so_addr;
- // Set the notification breakpoint and install a breakpoint
- // callback function that will get called each time the
- // breakpoint gets hit. We will use this to track when shared
- // libraries get loaded/unloaded.
+ // Set the notification breakpoint and install a breakpoint callback
+ // function that will get called each time the breakpoint gets hit. We
+ // will use this to track when shared libraries get loaded/unloaded.
bool resolved = m_process->GetTarget().ResolveLoadAddress(
m_dyld_all_image_infos.notification, so_addr);
if (!resolved) {
@@ -1071,9 +1054,9 @@ bool DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint() {
Status DynamicLoaderMacOSXDYLD::CanLoadImage() {
Status error;
- // In order for us to tell if we can load a shared library we verify that
- // the dylib_info_addr isn't zero (which means no shared libraries have
- // been set yet, or dyld is currently mucking with the shared library list).
+ // In order for us to tell if we can load a shared library we verify that the
+ // dylib_info_addr isn't zero (which means no shared libraries have been set
+ // yet, or dyld is currently mucking with the shared library list).
if (ReadAllImageInfosStructure()) {
// TODO: also check the _dyld_global_lock_held variable in
// libSystem.B.dylib?
@@ -1099,13 +1082,10 @@ bool DynamicLoaderMacOSXDYLD::GetSharedCacheInformation(
addr_t all_image_infos = m_process->GetImageInfoAddress();
// The address returned by GetImageInfoAddress may be the address of dyld
- // (don't want)
- // or it may be the address of the dyld_all_image_infos structure (want).
- // The first four
- // bytes will be either the version field (all_image_infos) or a Mach-O file
- // magic constant.
- // Version 13 and higher of dyld_all_image_infos is required to get the
- // sharedCacheUUID field.
+ // (don't want) or it may be the address of the dyld_all_image_infos
+ // structure (want). The first four bytes will be either the version field
+ // (all_image_infos) or a Mach-O file magic constant. Version 13 and higher
+ // of dyld_all_image_infos is required to get the sharedCacheUUID field.
Status err;
uint32_t version_or_magic =
@@ -1130,7 +1110,7 @@ bool DynamicLoaderMacOSXDYLD::GetSharedCacheInformation(
uuid_t shared_cache_uuid;
if (m_process->ReadMemory(sharedCacheUUID_address, shared_cache_uuid,
sizeof(uuid_t), err) == sizeof(uuid_t)) {
- uuid.SetBytes(shared_cache_uuid);
+ uuid = UUID::fromOptionalData(shared_cache_uuid, 16);
if (uuid.IsValid()) {
using_shared_cache = eLazyBoolYes;
}
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h b/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h
index cf9da0808357..3b06fe18f0c6 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h
@@ -22,12 +22,12 @@ class DataExtractor;
}
/// @class AuxVector
-/// @brief Represents a processes auxiliary vector.
+/// Represents a processes auxiliary vector.
///
/// When a process is loaded on Linux a vector of values is placed onto the
-/// stack communicating operating system specific information. On construction
-/// this class locates and parses this information and provides a simple
-/// read-only interface to the entries found.
+/// stack communicating operating system specific information. On
+/// construction this class locates and parses this information and provides a
+/// simple read-only interface to the entries found.
class AuxVector {
public:
@@ -41,8 +41,9 @@ public:
};
/// Constants describing the type of entry.
- /// On Linux, running "LD_SHOW_AUXV=1 ./executable" will spew AUX information.
- /// Added AUXV prefix to avoid potential conflicts with system-defined macros
+ /// On Linux, running "LD_SHOW_AUXV=1 ./executable" will spew AUX
+ /// information. Added AUXV prefix to avoid potential conflicts with system-
+ /// defined macros
enum EntryType {
AUXV_AT_NULL = 0, ///< End of auxv.
AUXV_AT_IGNORE = 1, ///< Ignore entry.
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
index e601d64f0d8d..b1513b51a90a 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
@@ -45,8 +45,8 @@ static addr_t ResolveRendezvousAddress(Process *process) {
if (log)
log->Printf("%s info_location = 0x%" PRIx64, __FUNCTION__, info_location);
- // If the process fails to return an address, fall back to seeing if the local
- // object file can help us find it.
+ // If the process fails to return an address, fall back to seeing if the
+ // local object file can help us find it.
if (info_location == LLDB_INVALID_ADDRESS) {
Target *target = &process->GetTarget();
if (target) {
@@ -190,8 +190,8 @@ bool DYLDRendezvous::UpdateSOEntries(bool fromRemote) {
if (!fromRemote && m_current.map_addr == 0)
return false;
- // When the previous and current states are consistent this is the first
- // time we have been asked to update. Just take a snapshot of the currently
+ // When the previous and current states are consistent this is the first time
+ // we have been asked to update. Just take a snapshot of the currently
// loaded modules.
if (m_previous.state == eConsistent && m_current.state == eConsistent)
return fromRemote ? SaveSOEntriesFromRemote(module_list)
@@ -200,9 +200,9 @@ bool DYLDRendezvous::UpdateSOEntries(bool fromRemote) {
// If we are about to add or remove a shared object clear out the current
// state and take a snapshot of the currently loaded images.
if (m_current.state == eAdd || m_current.state == eDelete) {
- // Some versions of the android dynamic linker might send two
- // notifications with state == eAdd back to back. Ignore them
- // until we get an eConsistent notification.
+ // Some versions of the android dynamic linker might send two notifications
+ // with state == eAdd back to back. Ignore them until we get an eConsistent
+ // notification.
if (!(m_previous.state == eConsistent ||
(m_previous.state == eAdd && m_current.state == eDelete)))
return false;
@@ -243,7 +243,7 @@ bool DYLDRendezvous::FillSOEntryFromModuleInfo(
entry.base_addr = base_addr;
entry.dyn_addr = dyn_addr;
- entry.file_spec.SetFile(name, false);
+ entry.file_spec.SetFile(name, false, FileSpec::Style::native);
UpdateBaseAddrIfNecessary(entry, name);
@@ -449,16 +449,13 @@ std::string DYLDRendezvous::ReadStringFromMemory(addr_t addr) {
}
// Returns true if the load bias reported by the linker is incorrect for the
-// given entry. This
-// function is used to handle cases where we want to work around a bug in the
-// system linker.
+// given entry. This function is used to handle cases where we want to work
+// around a bug in the system linker.
static bool isLoadBiasIncorrect(Target &target, const std::string &file_path) {
// On Android L (API 21, 22) the load address of the "/system/bin/linker"
- // isn't filled in
- // correctly.
- uint32_t os_major = 0, os_minor = 0, os_update = 0;
+ // isn't filled in correctly.
+ unsigned os_major = target.GetPlatform()->GetOSVersion().getMajor();
if (target.GetArchitecture().GetTriple().isAndroid() &&
- target.GetPlatform()->GetOSVersion(os_major, os_minor, os_update) &&
(os_major == 21 || os_major == 22) &&
(file_path == "/system/bin/linker" ||
file_path == "/system/bin/linker64")) {
@@ -471,8 +468,7 @@ static bool isLoadBiasIncorrect(Target &target, const std::string &file_path) {
void DYLDRendezvous::UpdateBaseAddrIfNecessary(SOEntry &entry,
std::string const &file_path) {
// If the load bias reported by the linker is incorrect then fetch the load
- // address of the file
- // from the proc file system.
+ // address of the file from the proc file system.
if (isLoadBiasIncorrect(m_process->GetTarget(), file_path)) {
lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
bool is_loaded = false;
@@ -491,8 +487,8 @@ bool DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry) {
if (!(addr = ReadPointer(addr, &entry.base_addr)))
return false;
- // mips adds an extra load offset field to the link map struct on
- // FreeBSD and NetBSD (need to validate other OSes).
+ // mips adds an extra load offset field to the link map struct on FreeBSD and
+ // NetBSD (need to validate other OSes).
// http://svnweb.freebsd.org/base/head/sys/sys/link_elf.h?revision=217153&view=markup#l57
const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
if ((arch.GetTriple().getOS() == llvm::Triple::FreeBSD ||
@@ -521,7 +517,7 @@ bool DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry) {
return false;
std::string file_path = ReadStringFromMemory(entry.path_addr);
- entry.file_spec.SetFile(file_path, false);
+ entry.file_spec.SetFile(file_path, false, FileSpec::Style::native);
UpdateBaseAddrIfNecessary(entry, file_path);
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
index 295ae55e1b85..a7071801f569 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
@@ -29,12 +29,12 @@ class Process;
}
/// @class DYLDRendezvous
-/// @brief Interface to the runtime linker.
+/// Interface to the runtime linker.
///
/// A structure is present in a processes memory space which is updated by the
-/// runtime liker each time a module is loaded or unloaded. This class provides
-/// an interface to this structure and maintains a consistent snapshot of the
-/// currently loaded modules.
+/// runtime liker each time a module is loaded or unloaded. This class
+/// provides an interface to this structure and maintains a consistent
+/// snapshot of the currently loaded modules.
class DYLDRendezvous {
// This structure is used to hold the contents of the debug rendezvous
@@ -119,13 +119,13 @@ public:
void DumpToLog(lldb_private::Log *log) const;
- /// @brief Constants describing the state of the rendezvous.
+ /// Constants describing the state of the rendezvous.
///
/// @see GetState().
enum RendezvousState { eConsistent, eAdd, eDelete };
- /// @brief Structure representing the shared objects currently loaded into
- /// the inferior process.
+ /// Structure representing the shared objects currently loaded into the
+ /// inferior process.
///
/// This object is a rough analogue to the struct link_map object which
/// actually lives in the inferiors memory.
@@ -194,7 +194,8 @@ protected:
/// List of SOEntry objects corresponding to the current link map state.
SOEntryList m_soentries;
- /// List of SOEntry's added to the link map since the last call to Resolve().
+ /// List of SOEntry's added to the link map since the last call to
+ /// Resolve().
SOEntryList m_added_soentries;
/// List of SOEntry's removed from the link map since the last call to
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
index a7afeb6d68c3..26825d879f04 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -79,7 +79,8 @@ DynamicLoaderPOSIXDYLD::DynamicLoaderPOSIXDYLD(Process *process)
: DynamicLoader(process), m_rendezvous(process),
m_load_offset(LLDB_INVALID_ADDRESS), m_entry_point(LLDB_INVALID_ADDRESS),
m_auxv(), m_dyld_bid(LLDB_INVALID_BREAK_ID),
- m_vdso_base(LLDB_INVALID_ADDRESS) {}
+ m_vdso_base(LLDB_INVALID_ADDRESS),
+ m_interpreter_base(LLDB_INVALID_ADDRESS) {}
DynamicLoaderPOSIXDYLD::~DynamicLoaderPOSIXDYLD() {
if (m_dyld_bid != LLDB_INVALID_BREAK_ID) {
@@ -117,7 +118,7 @@ void DynamicLoaderPOSIXDYLD::DidAttach() {
: "<null executable>",
load_offset);
- EvalVdsoStatus();
+ EvalSpecialModulesStatus();
// if we dont have a load address we cant re-base
bool rebase_exec = (load_offset == LLDB_INVALID_ADDRESS) ? false : true;
@@ -152,31 +153,10 @@ void DynamicLoaderPOSIXDYLD::DidAttach() {
UpdateLoadedSections(executable_sp, LLDB_INVALID_ADDRESS, load_offset,
true);
- // When attaching to a target, there are two possible states:
- // (1) We already crossed the entry point and therefore the rendezvous
- // structure is ready to be used and we can load the list of modules
- // and place the rendezvous breakpoint.
- // (2) We didn't cross the entry point yet, so these structures are not
- // ready; we should behave as if we just launched the target and
- // call ProbeEntry(). This will place a breakpoint on the entry
- // point which itself will be hit after the rendezvous structure is
- // set up and will perform actions described in (1).
- if (m_rendezvous.Resolve()) {
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64
- " rendezvous could resolve: attach assuming dynamic loader "
- "info is available now",
- __FUNCTION__,
- m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
- LoadAllCurrentModules();
- SetRendezvousBreakpoint();
- } else {
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64
- " rendezvous could not yet resolve: adding breakpoint to "
- "catch future rendezvous setup",
- __FUNCTION__,
- m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+ LoadAllCurrentModules();
+ if (!SetRendezvousBreakpoint()) {
+ // If we cannot establish rendezvous breakpoint right now we'll try again
+ // at entry point.
ProbeEntry();
}
@@ -207,7 +187,7 @@ void DynamicLoaderPOSIXDYLD::DidLaunch() {
executable = GetTargetExecutable();
load_offset = ComputeLoadOffset();
- EvalVdsoStatus();
+ EvalSpecialModulesStatus();
if (executable.get() && load_offset != LLDB_INVALID_ADDRESS) {
ModuleList module_list;
@@ -217,8 +197,14 @@ void DynamicLoaderPOSIXDYLD::DidLaunch() {
if (log)
log->Printf("DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()",
__FUNCTION__);
- ProbeEntry();
+ if (!SetRendezvousBreakpoint()) {
+ // If we cannot establish rendezvous breakpoint right now we'll try again
+ // at entry point.
+ ProbeEntry();
+ }
+
+ LoadVDSO();
m_process->GetTarget().ModulesDidLoad(module_list);
}
}
@@ -273,11 +259,11 @@ void DynamicLoaderPOSIXDYLD::ProbeEntry() {
}
// The runtime linker has run and initialized the rendezvous structure once the
-// process has hit its entry point. When we hit the corresponding breakpoint we
-// interrogate the rendezvous structure to get the load addresses of all
+// process has hit its entry point. When we hit the corresponding breakpoint
+// we interrogate the rendezvous structure to get the load addresses of all
// dependent modules for the process. Similarly, we can discover the runtime
-// linker function and setup a breakpoint to notify us of any dynamically loaded
-// modules (via dlopen).
+// linker function and setup a breakpoint to notify us of any dynamically
+// loaded modules (via dlopen).
bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit(
void *baton, StoppointCallbackContext *context, user_id_t break_id,
user_id_t break_loc_id) {
@@ -295,13 +281,11 @@ bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit(
: LLDB_INVALID_PROCESS_ID);
// Disable the breakpoint --- if a stop happens right after this, which we've
- // seen on occasion, we don't
- // want the breakpoint stepping thread-plan logic to show a breakpoint
- // instruction at the disassembled
- // entry point to the program. Disabling it prevents it. (One-shot is not
- // enough - one-shot removal logic
- // only happens after the breakpoint goes public, which wasn't happening in
- // our scenario).
+ // seen on occasion, we don't want the breakpoint stepping thread-plan logic
+ // to show a breakpoint instruction at the disassembled entry point to the
+ // program. Disabling it prevents it. (One-shot is not enough - one-shot
+ // removal logic only happens after the breakpoint goes public, which wasn't
+ // happening in our scenario).
if (dyld_instance->m_process) {
BreakpointSP breakpoint_sp =
dyld_instance->m_process->GetTarget().GetBreakpointByID(break_id);
@@ -329,38 +313,77 @@ bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit(
return false; // Continue running.
}
-void DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() {
+bool DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (m_dyld_bid != LLDB_INVALID_BREAK_ID) {
+ LLDB_LOG(log,
+ "Rendezvous breakpoint breakpoint id {0} for pid {1}"
+ "is already set.",
+ m_dyld_bid,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+ return true;
+ }
- addr_t break_addr = m_rendezvous.GetBreakAddress();
+ addr_t break_addr;
Target &target = m_process->GetTarget();
-
- if (m_dyld_bid == LLDB_INVALID_BREAK_ID) {
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
- " setting rendezvous break address at 0x%" PRIx64,
- __FUNCTION__,
- m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
- break_addr);
- Breakpoint *dyld_break =
- target.CreateBreakpoint(break_addr, true, false).get();
- dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
- dyld_break->SetBreakpointKind("shared-library-event");
- m_dyld_bid = dyld_break->GetID();
+ BreakpointSP dyld_break;
+ if (m_rendezvous.IsValid()) {
+ break_addr = m_rendezvous.GetBreakAddress();
+ LLDB_LOG(log, "Setting rendezvous break address for pid {0} at {1:x}",
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
+ break_addr);
+ dyld_break = target.CreateBreakpoint(break_addr, true, false);
} else {
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
- " reusing break id %" PRIu32 ", address at 0x%" PRIx64,
- __FUNCTION__,
- m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
- m_dyld_bid, break_addr);
+ LLDB_LOG(log, "Rendezvous structure is not set up yet. "
+ "Trying to locate rendezvous breakpoint in the interpreter "
+ "by symbol name.");
+ ModuleSP interpreter = LoadInterpreterModule();
+ if (!interpreter) {
+ LLDB_LOG(log, "Can't find interpreter, rendezvous breakpoint isn't set.");
+ return false;
+ }
+
+ // Function names from different dynamic loaders that are known to be used
+ // as rendezvous between the loader and debuggers.
+ static std::vector<std::string> DebugStateCandidates{
+ "_dl_debug_state", "rtld_db_dlactivity", "__dl_rtld_db_dlactivity",
+ "r_debug_state", "_r_debug_state", "_rtld_debug_state",
+ };
+
+ FileSpecList containingModules;
+ containingModules.Append(interpreter->GetFileSpec());
+ dyld_break = target.CreateBreakpoint(
+ &containingModules, nullptr /* containingSourceFiles */,
+ DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC,
+ 0, /* offset */
+ eLazyBoolNo, /* skip_prologue */
+ true, /* internal */
+ false /* request_hardware */);
+ }
+
+ if (dyld_break->GetNumResolvedLocations() != 1) {
+ LLDB_LOG(
+ log,
+ "Rendezvous breakpoint has abnormal number of"
+ " resolved locations ({0}) in pid {1}. It's supposed to be exactly 1.",
+ dyld_break->GetNumResolvedLocations(),
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+
+ target.RemoveBreakpointByID(dyld_break->GetID());
+ return false;
}
- // Make sure our breakpoint is at the right address.
- assert(target.GetBreakpointByID(m_dyld_bid)
- ->FindLocationByAddress(break_addr)
- ->GetBreakpoint()
- .GetID() == m_dyld_bid);
+ BreakpointLocationSP location = dyld_break->GetLocationAtIndex(0);
+ LLDB_LOG(log,
+ "Successfully set rendezvous breakpoint at address {0:x} "
+ "for pid {1}",
+ location->GetLoadAddress(),
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+
+ dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
+ dyld_break->SetBreakpointKind("shared-library-event");
+ m_dyld_bid = dyld_break->GetID();
+ return true;
}
bool DynamicLoaderPOSIXDYLD::RendezvousBreakpointHit(
@@ -485,7 +508,7 @@ DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread,
return thread_plan_sp;
}
-void DynamicLoaderPOSIXDYLD::LoadVDSO(ModuleList &modules) {
+void DynamicLoaderPOSIXDYLD::LoadVDSO() {
if (m_vdso_base == LLDB_INVALID_ADDRESS)
return;
@@ -506,13 +529,40 @@ void DynamicLoaderPOSIXDYLD::LoadVDSO(ModuleList &modules) {
}
}
+ModuleSP DynamicLoaderPOSIXDYLD::LoadInterpreterModule() {
+ if (m_interpreter_base == LLDB_INVALID_ADDRESS)
+ return nullptr;
+
+ MemoryRegionInfo info;
+ Target &target = m_process->GetTarget();
+ Status status = m_process->GetMemoryRegionInfo(m_interpreter_base, info);
+ if (status.Fail() || info.GetMapped() != MemoryRegionInfo::eYes ||
+ info.GetName().IsEmpty()) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ LLDB_LOG(log, "Failed to get interpreter region info: {0}", status);
+ return nullptr;
+ }
+
+ FileSpec file(info.GetName().GetCString(), false);
+ ModuleSpec module_spec(file, target.GetArchitecture());
+
+ if (ModuleSP module_sp = target.GetSharedModule(module_spec)) {
+ UpdateLoadedSections(module_sp, LLDB_INVALID_ADDRESS, m_interpreter_base,
+ false);
+ return module_sp;
+ }
+ return nullptr;
+}
+
void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() {
DYLDRendezvous::iterator I;
DYLDRendezvous::iterator E;
ModuleList module_list;
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+
+ LoadVDSO();
if (!m_rendezvous.Resolve()) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
if (log)
log->Printf("DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD "
"rendezvous address",
@@ -520,11 +570,10 @@ void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() {
return;
}
- // The rendezvous class doesn't enumerate the main module, so track
- // that ourselves here.
+ // The rendezvous class doesn't enumerate the main module, so track that
+ // ourselves here.
ModuleSP executable = GetTargetExecutable();
m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress();
- LoadVDSO(module_list);
std::vector<FileSpec> module_names;
for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I)
@@ -536,6 +585,8 @@ void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() {
ModuleSP module_sp =
LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
if (module_sp.get()) {
+ LLDB_LOG(log, "LoadAllCurrentModules loading module: {0}",
+ I->file_spec.GetFilename());
module_list.Append(module_sp);
} else {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
@@ -575,11 +626,14 @@ addr_t DynamicLoaderPOSIXDYLD::ComputeLoadOffset() {
return m_load_offset;
}
-void DynamicLoaderPOSIXDYLD::EvalVdsoStatus() {
- AuxVector::iterator I = m_auxv->FindEntry(AuxVector::AUXV_AT_SYSINFO_EHDR);
-
- if (I != m_auxv->end())
+void DynamicLoaderPOSIXDYLD::EvalSpecialModulesStatus() {
+ auto I = m_auxv->FindEntry(AuxVector::AUXV_AT_SYSINFO_EHDR);
+ if (I != m_auxv->end() && I->value != 0)
m_vdso_base = I->value;
+
+ I = m_auxv->FindEntry(AuxVector::AUXV_AT_BASE);
+ if (I != m_auxv->end() && I->value != 0)
+ m_interpreter_base = I->value;
}
addr_t DynamicLoaderPOSIXDYLD::GetEntryPoint() {
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
index 2e9670587e66..0456baf4a658 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
@@ -85,13 +85,17 @@ protected:
/// mapped to the address space
lldb::addr_t m_vdso_base;
+ /// Contains AT_BASE, which means a dynamic loader has been
+ /// mapped to the address space
+ lldb::addr_t m_interpreter_base;
+
/// Loaded module list. (link map for each module)
std::map<lldb::ModuleWP, lldb::addr_t, std::owner_less<lldb::ModuleWP>>
m_loaded_modules;
- /// Enables a breakpoint on a function called by the runtime
+ /// If possible sets a breakpoint on a function called by the runtime
/// linker each time a module is loaded or unloaded.
- virtual void SetRendezvousBreakpoint();
+ bool SetRendezvousBreakpoint();
/// Callback routine which updates the current list of loaded modules based
/// on the information supplied by the runtime linker.
@@ -138,7 +142,11 @@ protected:
/// of all dependent modules.
virtual void LoadAllCurrentModules();
- void LoadVDSO(lldb_private::ModuleList &modules);
+ void LoadVDSO();
+
+ // Loading an interpreter module (if present) assumming m_interpreter_base
+ // already points to its base address.
+ lldb::ModuleSP LoadInterpreterModule();
/// Computes a value for m_load_offset returning the computed address on
/// success and LLDB_INVALID_ADDRESS on failure.
@@ -148,9 +156,10 @@ protected:
/// success and LLDB_INVALID_ADDRESS on failure.
lldb::addr_t GetEntryPoint();
- /// Evaluate if Aux vectors contain vDSO information
+ /// Evaluate if Aux vectors contain vDSO and LD information
/// in case they do, read and assign the address to m_vdso_base
- void EvalVdsoStatus();
+ /// and m_interpreter_base.
+ void EvalSpecialModulesStatus();
/// Loads Module from inferior process.
void ResolveExecutableModule(lldb::ModuleSP &module_sp);
diff --git a/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp b/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
index 291695cb68c1..2960e3939461 100644
--- a/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
+++ b/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
@@ -19,9 +19,9 @@ using namespace lldb;
using namespace lldb_private;
//----------------------------------------------------------------------
-// Create an instance of this class. This function is filled into
-// the plugin info class that gets handed out by the plugin factory and
-// allows the lldb to instantiate an instance of this class.
+// Create an instance of this class. This function is filled into the plugin
+// info class that gets handed out by the plugin factory and allows the lldb to
+// instantiate an instance of this class.
//----------------------------------------------------------------------
DynamicLoader *DynamicLoaderStatic::CreateInstance(Process *process,
bool force) {
@@ -97,17 +97,17 @@ void DynamicLoaderStatic::LoadAllImagesAtFileAddresses() {
if (section_list) {
// All sections listed in the dyld image info structure will all
// either be fixed up already, or they will all be off by a single
- // slide amount that is determined by finding the first segment
- // that is at file offset zero which also has bytes (a file size
- // that is greater than zero) in the object file.
+ // slide amount that is determined by finding the first segment that
+ // is at file offset zero which also has bytes (a file size that is
+ // greater than zero) in the object file.
// Determine the slide amount (if any)
const size_t num_sections = section_list->GetSize();
size_t sect_idx = 0;
for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
- // Iterate through the object file sections to find the
- // first section that starts of file offset zero and that
- // has bytes in the file...
+ // Iterate through the object file sections to find the first
+ // section that starts of file offset zero and that has bytes in
+ // the file...
SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
if (section_sp) {
if (m_process->GetTarget().SetSectionLoadAddress(
diff --git a/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp b/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
index 9e6a2f3acafe..fa49a51f32a6 100644
--- a/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
@@ -226,8 +226,7 @@ bool ASTResultSynthesizer::SynthesizeBodyResult(CompoundStmt *Body,
return true;
// In C++11, last_expr can be a LValueToRvalue implicit cast. Strip that off
- // if that's the
- // case.
+ // if that's the case.
do {
ImplicitCastExpr *implicit_cast = dyn_cast<ImplicitCastExpr>(last_expr);
@@ -242,8 +241,8 @@ bool ASTResultSynthesizer::SynthesizeBodyResult(CompoundStmt *Body,
} while (0);
// is_lvalue is used to record whether the expression returns an assignable
- // Lvalue or an
- // Rvalue. This is relevant because they are handled differently.
+ // Lvalue or an Rvalue. This is relevant because they are handled
+ // differently.
//
// For Lvalues
//
@@ -293,9 +292,8 @@ bool ASTResultSynthesizer::SynthesizeBodyResult(CompoundStmt *Body,
//
// - During dematerialization, $0 is ignored.
- bool is_lvalue = (last_expr->getValueKind() == VK_LValue ||
- last_expr->getValueKind() == VK_XValue) &&
- (last_expr->getObjectKind() == OK_Ordinary);
+ bool is_lvalue = last_expr->getValueKind() == VK_LValue &&
+ last_expr->getObjectKind() == OK_Ordinary;
QualType expr_qual_type = last_expr->getType();
const clang::Type *expr_type = expr_qual_type.getTypePtr();
diff --git a/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h b/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h
index c0e6c0358a23..859a1dfa5f73 100644
--- a/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h
+++ b/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h
@@ -18,18 +18,17 @@ namespace lldb_private {
//----------------------------------------------------------------------
/// @class ASTResultSynthesizer ASTResultSynthesizer.h
-/// "lldb/Expression/ASTResultSynthesizer.h"
-/// @brief Adds a result variable declaration to the ASTs for an expression.
+/// "lldb/Expression/ASTResultSynthesizer.h" Adds a result variable
+/// declaration to the ASTs for an expression.
///
/// Users expect the expression "i + 3" to return a result, even if a result
/// variable wasn't specifically declared. To fulfil this requirement, LLDB
-/// adds
-/// a result variable to the expression, transforming it to
-/// "int $__lldb_expr_result = i + 3." The IR transformers ensure that the
+/// adds a result variable to the expression, transforming it to "int
+/// $__lldb_expr_result = i + 3." The IR transformers ensure that the
/// resulting variable is mapped to the right piece of memory.
-/// ASTResultSynthesizer's job is to add the variable and its initialization to
-/// the ASTs for the expression, and it does so by acting as a SemaConsumer for
-/// Clang.
+/// ASTResultSynthesizer's job is to add the variable and its initialization
+/// to the ASTs for the expression, and it does so by acting as a SemaConsumer
+/// for Clang.
//----------------------------------------------------------------------
class ASTResultSynthesizer : public clang::SemaConsumer {
public:
@@ -68,8 +67,8 @@ public:
void Initialize(clang::ASTContext &Context) override;
//----------------------------------------------------------------------
- /// Examine a list of Decls to find the function $__lldb_expr and
- /// transform its code
+ /// Examine a list of Decls to find the function $__lldb_expr and transform
+ /// its code
///
/// @param[in] D
/// The list of Decls to search. These may contain LinkageSpecDecls,
@@ -124,8 +123,8 @@ public:
private:
//----------------------------------------------------------------------
- /// Hunt the given Decl for FunctionDecls named $__lldb_expr, recursing
- /// as necessary through LinkageSpecDecls, and calling SynthesizeResult on
+ /// Hunt the given Decl for FunctionDecls named $__lldb_expr, recursing as
+ /// necessary through LinkageSpecDecls, and calling SynthesizeResult on
/// anything that was found
///
/// @param[in] D
@@ -164,8 +163,8 @@ private:
bool SynthesizeBodyResult(clang::CompoundStmt *Body, clang::DeclContext *DC);
//----------------------------------------------------------------------
- /// Given a DeclContext for a function or method, find all types
- /// declared in the context and record any persistent types found.
+ /// Given a DeclContext for a function or method, find all types declared in
+ /// the context and record any persistent types found.
///
/// @param[in] FunDeclCtx
/// The context for the function to process.
@@ -173,8 +172,8 @@ private:
void RecordPersistentTypes(clang::DeclContext *FunDeclCtx);
//----------------------------------------------------------------------
- /// Given a TypeDecl, if it declares a type whose name starts with a
- /// dollar sign, register it as a pointer type in the target's scratch
+ /// Given a TypeDecl, if it declares a type whose name starts with a dollar
+ /// sign, register it as a pointer type in the target's scratch
/// AST context.
///
/// @param[in] Body
diff --git a/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h b/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h
index 63e3161cae85..65f4b00a8651 100644
--- a/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h
+++ b/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h
@@ -20,20 +20,19 @@ namespace lldb_private {
//----------------------------------------------------------------------
/// @class ASTStructExtractor ASTStructExtractor.h
-/// "lldb/Expression/ASTStructExtractor.h"
-/// @brief Extracts and describes the argument structure for a wrapped function.
+/// "lldb/Expression/ASTStructExtractor.h" Extracts and describes the argument
+/// structure for a wrapped function.
///
/// This pass integrates with ClangFunctionCaller, which calls functions with
-/// custom
-/// sets of arguments. To avoid having to implement the full calling convention
-/// for the target's architecture, ClangFunctionCaller writes a simple wrapper
-/// function that takes a pointer to an argument structure that contains room
-/// for the address of the function to be called, the values of all its
-/// arguments, and room for the function's return value.
+/// custom sets of arguments. To avoid having to implement the full calling
+/// convention for the target's architecture, ClangFunctionCaller writes a
+/// simple wrapper function that takes a pointer to an argument structure that
+/// contains room for the address of the function to be called, the values of
+/// all its arguments, and room for the function's return value.
///
-/// 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 function and finds the struct.
+/// 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 function and finds the struct.
//----------------------------------------------------------------------
class ASTStructExtractor : public clang::SemaConsumer {
public:
@@ -73,8 +72,8 @@ public:
void Initialize(clang::ASTContext &Context) override;
//----------------------------------------------------------------------
- /// Examine a list of Decls to find the function $__lldb_expr and
- /// transform its code
+ /// Examine a list of Decls to find the function $__lldb_expr and transform
+ /// its code
///
/// @param[in] D
/// The list of Decls to search. These may contain LinkageSpecDecls,
diff --git a/source/Plugins/ExpressionParser/Clang/CMakeLists.txt b/source/Plugins/ExpressionParser/Clang/CMakeLists.txt
index a780e7d597b1..ec4f6d5674e1 100644
--- a/source/Plugins/ExpressionParser/Clang/CMakeLists.txt
+++ b/source/Plugins/ExpressionParser/Clang/CMakeLists.txt
@@ -11,6 +11,7 @@ add_lldb_library(lldbPluginExpressionParserClang PLUGIN
ClangExpressionParser.cpp
ClangExpressionVariable.cpp
ClangFunctionCaller.cpp
+ ClangHost.cpp
ClangModulesDeclVendor.cpp
ClangPersistentVariables.cpp
ClangUserExpression.cpp
@@ -23,6 +24,7 @@ add_lldb_library(lldbPluginExpressionParserClang PLUGIN
LINK_LIBS
clangAST
clangCodeGen
+ clangDriver
clangEdit
clangFrontend
clangLex
diff --git a/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
index 7f031356b3c3..d98a2b25fbb7 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
@@ -33,8 +33,8 @@ using namespace clang;
using namespace lldb_private;
//------------------------------------------------------------------
-// Scoped class that will remove an active lexical decl from the set
-// when it goes out of scope.
+// Scoped class that will remove an active lexical decl from the set when it
+// goes out of scope.
//------------------------------------------------------------------
namespace {
class ScopedLexicalDeclEraser {
@@ -141,8 +141,8 @@ ClangASTSource::~ClangASTSource() {
m_ast_importer_sp->ForgetDestination(m_ast_context);
// We are in the process of destruction, don't create clang ast context on
- // demand
- // by passing false to Target::GetScratchClangASTContext(create_on_demand).
+ // demand by passing false to
+ // Target::GetScratchClangASTContext(create_on_demand).
ClangASTContext *scratch_clang_ast_context =
m_target->GetScratchClangASTContext(false);
@@ -231,8 +231,8 @@ bool ClangASTSource::FindExternalVisibleDeclsByName(
}
if (!GetLookupsEnabled()) {
- // Wait until we see a '$' at the start of a name before we start doing
- // any lookups so we can avoid lookup up all of the builtin types.
+ // Wait until we see a '$' at the start of a name before we start doing any
+ // lookups so we can avoid lookup up all of the builtin types.
if (!decl_name.empty() && decl_name[0] == '$') {
SetLookupsEnabled(true);
} else {
@@ -297,8 +297,8 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) {
}
if (!m_ast_importer_sp->CompleteTagDecl(tag_decl)) {
- // We couldn't complete the type. Maybe there's a definition
- // somewhere else that can be completed.
+ // We couldn't complete the type. Maybe there's a definition somewhere
+ // else that can be completed.
if (log)
log->Printf(" CTD[%u] Type could not be completed in the module in "
@@ -398,8 +398,8 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) {
const_cast<TagDecl *>(tag_type->getDecl());
// We have found a type by basename and we need to make sure the decl
- // contexts
- // are the same before we can try to complete this type with another
+ // contexts are the same before we can try to complete this type with
+ // another
if (!ClangASTContext::DeclsAreEquivalent(tag_decl, candidate_tag_decl))
continue;
@@ -861,13 +861,16 @@ void ClangASTSource::FindExternalVisibleDecls(
TypeList types;
SymbolContext null_sc;
- const bool exact_match = false;
+ const bool exact_match = true;
llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
if (module_sp && namespace_decl)
module_sp->FindTypesInNamespace(null_sc, name, &namespace_decl, 1, types);
- else
- m_target->GetImages().FindTypes(null_sc, name, exact_match, 1,
+ else {
+ SymbolContext sc;
+ sc.module_sp = module_sp;
+ m_target->GetImages().FindTypes(sc, name, exact_match, 1,
searched_symbol_files, types);
+ }
if (size_t num_types = types.GetSize()) {
for (size_t ti = 0; ti < num_types; ++ti) {
@@ -1243,8 +1246,8 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
break;
// Fall back and check for methods in categories. If we find methods this
- // way, we need to check that they're actually in
- // categories on the desired class.
+ // way, we need to check that they're actually in categories on the desired
+ // class.
SymbolContextList candidate_sc_list;
@@ -1591,8 +1594,7 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
do {
// Check the runtime only if the debug information didn't have a complete
- // interface
- // and nothing was in the modules.
+ // interface and nothing was in the modules.
lldb::ProcessSP process(m_target->GetProcessSP());
@@ -1645,12 +1647,9 @@ static bool ImportOffsetMap(llvm::DenseMap<const D *, O> &destination_map,
ClangASTSource &source) {
// When importing fields into a new record, clang has a hard requirement that
// fields be imported in field offset order. Since they are stored in a
- // DenseMap
- // with a pointer as the key type, this means we cannot simply iterate over
- // the
- // map, as the order will be non-deterministic. Instead we have to sort by
- // the offset
- // and then insert in sorted order.
+ // DenseMap with a pointer as the key type, this means we cannot simply
+ // iterate over the map, as the order will be non-deterministic. Instead we
+ // have to sort by the offset and then insert in sorted order.
typedef llvm::DenseMap<const D *, O> MapType;
typedef typename MapType::value_type PairType;
std::vector<PairType> sorted_items;
@@ -2051,9 +2050,8 @@ CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) {
if (copied_qual_type.getAsOpaquePtr() &&
copied_qual_type->getCanonicalTypeInternal().isNull())
- // this shouldn't happen, but we're hardening because the AST importer seems
- // to be generating bad types
- // on occasion.
+ // this shouldn't happen, but we're hardening because the AST importer
+ // seems to be generating bad types on occasion.
return CompilerType();
return CompilerType(m_ast_context, copied_qual_type);
@@ -2156,6 +2154,18 @@ clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type,
log->Printf("Function type wasn't a FunctionProtoType");
}
+ // If this is an operator (e.g. operator new or operator==), only insert the
+ // declaration we inferred from the symbol if we can provide the correct
+ // number of arguments. We shouldn't really inject random decl(s) for
+ // functions that are analyzed semantically in a special way, otherwise we
+ // will crash in clang.
+ clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
+ if (func_proto_type &&
+ ClangASTContext::IsOperator(decl_name.getAsString().c_str(), op_kind)) {
+ if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount(
+ false, op_kind, func_proto_type->getNumParams()))
+ return NULL;
+ }
m_decls.push_back(func_decl);
return func_decl;
diff --git a/source/Plugins/ExpressionParser/Clang/ClangASTSource.h b/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
index 6f72ad92dc8c..a42422b0f97f 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
@@ -25,14 +25,13 @@ namespace lldb_private {
//----------------------------------------------------------------------
/// @class ClangASTSource ClangASTSource.h "lldb/Expression/ClangASTSource.h"
-/// @brief Provider for named objects defined in the debug info for Clang
+/// Provider for named objects defined in the debug info for Clang
///
-/// As Clang parses an expression, it may encounter names that are not
-/// defined inside the expression, including variables, functions, and
-/// types. Clang knows the name it is looking for, but nothing else.
-/// The ExternalSemaSource class provides Decls (VarDecl, FunDecl, TypeDecl)
-/// to Clang for these names, consulting the ClangExpressionDeclMap to do
-/// the actual lookups.
+/// As Clang parses an expression, it may encounter names that are not defined
+/// inside the expression, including variables, functions, and types. Clang
+/// knows the name it is looking for, but nothing else. The ExternalSemaSource
+/// class provides Decls (VarDecl, FunDecl, TypeDecl) to Clang for these
+/// names, consulting the ClangExpressionDeclMap to do the actual lookups.
//----------------------------------------------------------------------
class ClangASTSource : public ClangExternalASTSourceCommon,
public ClangASTImporter::MapCompleter {
@@ -78,8 +77,8 @@ public:
//------------------------------------------------------------------
/// Look up all Decls that match a particular name. Only handles
/// Identifiers and DeclContexts that are either NamespaceDecls or
- /// TranslationUnitDecls. Calls SetExternalVisibleDeclsForName with
- /// the result.
+ /// TranslationUnitDecls. Calls SetExternalVisibleDeclsForName with the
+ /// result.
///
/// The work for this function is done by
/// void FindExternalVisibleDecls (NameSearchContext &);
@@ -173,8 +172,8 @@ public:
//------------------------------------------------------------------
/// Called on entering a translation unit. Tells Clang by calling
- /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage()
- /// that this object has something to say about undefined names.
+ /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage() that
+ /// this object has something to say about undefined names.
///
/// @param[in] ASTConsumer
/// Unused.
@@ -186,8 +185,8 @@ public:
//
//------------------------------------------------------------------
- /// Look up the modules containing a given namespace and put the
- /// appropriate entries in the namespace map.
+ /// Look up the modules containing a given namespace and put the appropriate
+ /// entries in the namespace map.
///
/// @param[in] namespace_map
/// The map to be completed.
@@ -231,11 +230,10 @@ public:
//----------------------------------------------------------------------
/// @class ClangASTSourceProxy ClangASTSource.h
- /// "lldb/Expression/ClangASTSource.h"
- /// @brief Proxy for ClangASTSource
+ /// "lldb/Expression/ClangASTSource.h" Proxy for ClangASTSource
///
- /// Clang AST contexts like to own their AST sources, so this is a
- /// state-free proxy object.
+ /// Clang AST contexts like to own their AST sources, so this is a state-
+ /// free proxy object.
//----------------------------------------------------------------------
class ClangASTSourceProxy : public ClangExternalASTSourceCommon {
public:
@@ -298,8 +296,8 @@ public:
protected:
//------------------------------------------------------------------
- /// Look for the complete version of an Objective-C interface, and
- /// return it if found.
+ /// Look for the complete version of an Objective-C interface, and return it
+ /// if found.
///
/// @param[in] interface_decl
/// An ObjCInterfaceDecl that may not be the complete one.
@@ -312,8 +310,8 @@ protected:
GetCompleteObjCInterface(const clang::ObjCInterfaceDecl *interface_decl);
//------------------------------------------------------------------
- /// Find all entities matching a given name in a given module,
- /// using a NameSearchContext to make Decls for them.
+ /// Find all entities matching a given name in a given module, using a
+ /// NameSearchContext to make Decls for them.
///
/// @param[in] context
/// The NameSearchContext that can construct Decls for this name.
@@ -474,8 +472,9 @@ protected:
};
//----------------------------------------------------------------------
-/// @class NameSearchContext ClangASTSource.h "lldb/Expression/ClangASTSource.h"
-/// @brief Container for all objects relevant to a single name lookup
+/// @class NameSearchContext ClangASTSource.h
+/// "lldb/Expression/ClangASTSource.h" Container for all objects relevant to a
+/// single name lookup
///
/// LLDB needs to create Decls for entities it finds. This class communicates
/// what name is being searched for and provides helper functions to construct
@@ -532,8 +531,8 @@ struct NameSearchContext {
}
//------------------------------------------------------------------
- /// Create a VarDecl with the name being searched for and the provided
- /// type and register it in the right places.
+ /// Create a VarDecl with the name being searched for and the provided type
+ /// and register it in the right places.
///
/// @param[in] type
/// The opaque QualType for the VarDecl being registered.
@@ -541,8 +540,8 @@ struct NameSearchContext {
clang::NamedDecl *AddVarDecl(const CompilerType &type);
//------------------------------------------------------------------
- /// Create a FunDecl with the name being searched for and the provided
- /// type and register it in the right places.
+ /// Create a FunDecl with the name being searched for and the provided type
+ /// and register it in the right places.
///
/// @param[in] type
/// The opaque QualType for the FunDecl being registered.
@@ -553,15 +552,14 @@ struct NameSearchContext {
clang::NamedDecl *AddFunDecl(const CompilerType &type, bool extern_c = false);
//------------------------------------------------------------------
- /// Create a FunDecl with the name being searched for and generic
- /// type (i.e. intptr_t NAME_GOES_HERE(...)) and register it in the
- /// right places.
+ /// Create a FunDecl with the name being searched for and generic type (i.e.
+ /// intptr_t NAME_GOES_HERE(...)) and register it in the right places.
//------------------------------------------------------------------
clang::NamedDecl *AddGenericFunDecl();
//------------------------------------------------------------------
- /// Create a TypeDecl with the name being searched for and the provided
- /// type and register it in the right places.
+ /// Create a TypeDecl with the name being searched for and the provided type
+ /// and register it in the right places.
///
/// @param[in] compiler_type
/// The opaque QualType for the TypeDecl being registered.
@@ -569,8 +567,8 @@ struct NameSearchContext {
clang::NamedDecl *AddTypeDecl(const CompilerType &compiler_type);
//------------------------------------------------------------------
- /// Add Decls from the provided DeclContextLookupResult to the list
- /// of results.
+ /// Add Decls from the provided DeclContextLookupResult to the list of
+ /// results.
///
/// @param[in] result
/// The DeclContextLookupResult, usually returned as the result
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index 07ff2e97aac7..0811a7999920 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -213,8 +213,8 @@ private:
m_exporter.getFromContext().getSourceManager().getFileID(loc);
if (file != m_file)
return false;
- // We are assuming the Decl was parsed in this very expression, so it should
- // not have external storage.
+ // We are assuming the Decl was parsed in this very expression, so it
+ // should not have external storage.
lldbassert(!llvm::cast<DeclContext>(decl)->hasExternalLexicalStorage());
return true;
}
@@ -591,8 +591,8 @@ bool ClangExpressionDeclMap::GetFunctionInfo(const NamedDecl *decl,
if (!entity)
return false;
- // We know m_parser_vars is valid since we searched for the variable by
- // its NamedDecl
+ // We know m_parser_vars is valid since we searched for the variable by its
+ // NamedDecl
ClangExpressionVariable::ParserVars *parser_vars =
entity->GetParserVars(GetParserID());
@@ -720,9 +720,9 @@ lldb::VariableSP ClangExpressionDeclMap::FindGlobalVariable(
VariableList vars;
if (module && namespace_decl)
- module->FindGlobalVariables(name, namespace_decl, true, -1, vars);
+ module->FindGlobalVariables(name, namespace_decl, -1, vars);
else
- target.GetImages().FindGlobalVariables(name, true, -1, vars);
+ target.GetImages().FindGlobalVariables(name, -1, vars);
if (vars.GetSize()) {
if (type) {
@@ -867,8 +867,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
if (IgnoreName(name, false))
return;
- // Only look for functions by name out in our symbols if the function
- // doesn't start with our phony prefix of '$'
+ // Only look for functions by name out in our symbols if the function doesn't
+ // start with our phony prefix of '$'
Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
SymbolContext sym_ctx;
@@ -977,13 +977,11 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
m_struct_vars->m_object_pointer_type = self_user_type;
}
} else {
- // This branch will get hit if we are executing code in the context of a
- // function that
- // claims to have an object pointer (through DW_AT_object_pointer?) but
- // is not formally a
- // method of the class. In that case, just look up the "this" variable
- // in the current
- // scope and use its type.
+ // This branch will get hit if we are executing code in the context of
+ // a function that claims to have an object pointer (through
+ // DW_AT_object_pointer?) but is not formally a method of the class.
+ // In that case, just look up the "this" variable in the current scope
+ // and use its type.
// FIXME: This code is formally correct, but clang doesn't currently
// emit DW_AT_object_pointer
// for C++ so it hasn't actually been tested.
@@ -1093,13 +1091,11 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
return;
} else {
- // This branch will get hit if we are executing code in the context of a
- // function that
- // claims to have an object pointer (through DW_AT_object_pointer?) but
- // is not formally a
- // method of the class. In that case, just look up the "self" variable
- // in the current
- // scope and use its type.
+ // This branch will get hit if we are executing code in the context of
+ // a function that claims to have an object pointer (through
+ // DW_AT_object_pointer?) but is not formally a method of the class.
+ // In that case, just look up the "self" variable in the current scope
+ // and use its type.
VariableList *vars = frame->GetVariableList(false);
@@ -1217,9 +1213,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
vars->GetVariableAtIndex(i)->GetDecl();
// Search for declarations matching the name. Do not include imported
- // decls
- // in the search if we are looking for decls in the artificial namespace
- // $__lldb_local_vars.
+ // decls in the search if we are looking for decls in the artificial
+ // namespace $__lldb_local_vars.
std::vector<CompilerDecl> found_decls =
compiler_decl_context.FindDeclByName(name,
namespace_decl.IsValid());
@@ -1285,15 +1280,15 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
append, sc_list);
}
- // If we found more than one function, see if we can use the
- // frame's decl context to remove functions that are shadowed
- // by other functions which match in type but are nearer in scope.
+ // If we found more than one function, see if we can use the frame's decl
+ // context to remove functions that are shadowed by other functions which
+ // match in type but are nearer in scope.
//
// AddOneFunction will not add a function whose type has already been
- // added, so if there's another function in the list with a matching
- // type, check to see if their decl context is a parent of the current
- // frame's or was imported via a and using statement, and pick the
- // best match according to lookup rules.
+ // added, so if there's another function in the list with a matching type,
+ // check to see if their decl context is a parent of the current frame's or
+ // was imported via a and using statement, and pick the best match
+ // according to lookup rules.
if (sc_list.GetSize() > 1) {
// Collect some info about our frame's context.
StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
@@ -1321,11 +1316,10 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
SymbolContext m_sym_ctx;
};
- // First, symplify things by looping through the symbol contexts
- // to remove unwanted functions and separate out the functions we
- // want to compare and prune into a separate list.
- // Cache the info needed about the function declarations in a
- // vector for efficiency.
+ // First, symplify things by looping through the symbol contexts to
+ // remove unwanted functions and separate out the functions we want to
+ // compare and prune into a separate list. Cache the info needed about
+ // the function declarations in a vector for efficiency.
SymbolContextList sc_sym_list;
uint32_t num_indices = sc_list.GetSize();
std::vector<FuncDeclInfo> fdi_cache;
@@ -1335,16 +1329,16 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
SymbolContext sym_ctx;
sc_list.GetContextAtIndex(index, sym_ctx);
- // We don't know enough about symbols to compare them,
- // but we should keep them in the list.
+ // We don't know enough about symbols to compare them, but we should
+ // keep them in the list.
Function *function = sym_ctx.function;
if (!function) {
sc_sym_list.Append(sym_ctx);
continue;
}
// Filter out functions without declaration contexts, as well as
- // class/instance methods, since they'll be skipped in the
- // code that follows anyway.
+ // class/instance methods, since they'll be skipped in the code that
+ // follows anyway.
CompilerDeclContext func_decl_context = function->GetDeclContext();
if (!func_decl_context ||
func_decl_context.IsClassMethod(nullptr, nullptr, nullptr))
@@ -1363,11 +1357,10 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
fdi.m_copied_type = copied_func_type;
fdi.m_decl_lvl = LLDB_INVALID_DECL_LEVEL;
if (fdi.m_copied_type && func_decl_context) {
- // Call CountDeclLevels to get the number of parent scopes we
- // have to look through before we find the function declaration.
- // When comparing functions of the same type, the one with a
- // lower count will be closer to us in the lookup scope and
- // shadows the other.
+ // Call CountDeclLevels to get the number of parent scopes we have
+ // to look through before we find the function declaration. When
+ // comparing functions of the same type, the one with a lower count
+ // will be closer to us in the lookup scope and shadows the other.
clang::DeclContext *func_decl_ctx =
(clang::DeclContext *)func_decl_context.GetOpaqueDeclContext();
fdi.m_decl_lvl = ast->CountDeclLevels(
@@ -1536,9 +1529,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
}
if (target && !context.m_found.variable && !namespace_decl) {
- // We couldn't find a non-symbol variable for this. Now we'll hunt for
- // a generic
- // data symbol, and -- if it is found -- treat it as a variable.
+ // We couldn't find a non-symbol variable for this. Now we'll hunt for a
+ // generic data symbol, and -- if it is found -- treat it as a variable.
Status error;
const Symbol *data_symbol =
@@ -2116,7 +2108,8 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
parser_vars->m_llvm_value = NULL;
if (log) {
- ASTDumper ast_dumper(function_decl);
+ std::string function_str =
+ function_decl ? ASTDumper(function_decl).GetCString() : "nullptr";
StreamString ss;
@@ -2127,7 +2120,7 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
log->Printf(
" CEDM::FEVD[%u] Found %s function %s (description %s), returned %s",
current_id, (function ? "specific" : "generic"), decl_name.c_str(),
- ss.GetData(), ast_dumper.GetCString());
+ ss.GetData(), function_str.c_str());
}
}
@@ -2165,7 +2158,7 @@ void ClangExpressionDeclMap::AddThisType(NameSearchContext &context,
CXXMethodDecl *method_decl =
ClangASTContext::GetASTContext(m_ast_context)
->AddMethodToCXXRecordType(
- copied_clang_type.GetOpaqueQualType(), "$__lldb_expr",
+ copied_clang_type.GetOpaqueQualType(), "$__lldb_expr", NULL,
method_type, lldb::eAccessPublic, is_virtual, is_static,
is_inline, is_explicit, is_attr_used, is_artificial);
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
index d163ad4f7e29..b67387930190 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
@@ -36,29 +36,28 @@ namespace lldb_private {
//----------------------------------------------------------------------
/// @class ClangExpressionDeclMap ClangExpressionDeclMap.h
-/// "lldb/Expression/ClangExpressionDeclMap.h"
-/// @brief Manages named entities that are defined in LLDB's debug information.
+/// "lldb/Expression/ClangExpressionDeclMap.h" Manages named entities that are
+/// defined in LLDB's debug information.
///
/// The Clang parser uses the ClangASTSource as an interface to request named
/// entities from outside an expression. The ClangASTSource reports back,
-/// listing
-/// all possible objects corresponding to a particular name. But it in turn
-/// relies on ClangExpressionDeclMap, which performs several important
+/// listing all possible objects corresponding to a particular name. But it
+/// in turn relies on ClangExpressionDeclMap, which performs several important
/// functions.
///
-/// First, it records what variables and functions were looked up and what Decls
-/// were returned for them.
+/// First, it records what variables and functions were looked up and what
+/// Decls were returned for them.
///
/// Second, it constructs a struct on behalf of IRForTarget, recording which
-/// variables should be placed where and relaying this information back so that
-/// IRForTarget can generate context-independent code.
+/// variables should be placed where and relaying this information back so
+/// that IRForTarget can generate context-independent code.
///
/// Third, it "materializes" this struct on behalf of the expression command,
/// finding the current values of each variable and placing them into the
/// struct so that it can be passed to the JITted version of the IR.
///
-/// Fourth and finally, it "dematerializes" the struct after the JITted code has
-/// has executed, placing the new values back where it found the old ones.
+/// Fourth and finally, it "dematerializes" the struct after the JITted code
+/// has has executed, placing the new values back where it found the old ones.
//----------------------------------------------------------------------
class ClangExpressionDeclMap : public ClangASTSource {
public:
@@ -169,8 +168,8 @@ public:
lldb::offset_t alignment);
//------------------------------------------------------------------
- /// [Used by IRForTarget] Finalize the struct, laying out the position
- /// of each object in it.
+ /// [Used by IRForTarget] Finalize the struct, laying out the position of
+ /// each object in it.
///
/// @return
/// True on success; false otherwise.
@@ -178,8 +177,8 @@ public:
bool DoStructLayout();
//------------------------------------------------------------------
- /// [Used by IRForTarget] Get general information about the laid-out
- /// struct after DoStructLayout() has been called.
+ /// [Used by IRForTarget] Get general information about the laid-out struct
+ /// after DoStructLayout() has been called.
///
/// @param[out] num_elements
/// The number of elements in the struct.
@@ -197,8 +196,8 @@ public:
lldb::offset_t &alignment);
//------------------------------------------------------------------
- /// [Used by IRForTarget] Get specific information about one field
- /// of the laid-out struct after DoStructLayout() has been called.
+ /// [Used by IRForTarget] Get specific information about one field of the
+ /// laid-out struct after DoStructLayout() has been called.
///
/// @param[out] decl
/// The parsed Decl for the field, as generated by ClangASTSource
@@ -232,8 +231,7 @@ public:
uint32_t index);
//------------------------------------------------------------------
- /// [Used by IRForTarget] Get information about a function given its
- /// Decl.
+ /// [Used by IRForTarget] Get information about a function given its Decl.
///
/// @param[in] decl
/// The parsed Decl for the Function, as generated by ClangASTSource
@@ -248,8 +246,8 @@ public:
bool GetFunctionInfo(const clang::NamedDecl *decl, uint64_t &ptr);
//------------------------------------------------------------------
- /// [Used by IRForTarget] Get the address of a symbol given nothing
- /// but its name.
+ /// [Used by IRForTarget] Get the address of a symbol given nothing but its
+ /// name.
///
/// @param[in] target
/// The target to find the symbol in. If not provided,
@@ -303,8 +301,8 @@ public:
TargetInfo GetTargetInfo();
//------------------------------------------------------------------
- /// [Used by ClangASTSource] Find all entities matching a given name,
- /// using a NameSearchContext to make Decls for them.
+ /// [Used by ClangASTSource] Find all entities matching a given name, using
+ /// a NameSearchContext to make Decls for them.
///
/// @param[in] context
/// The NameSearchContext that can construct Decls for this name.
@@ -442,14 +440,13 @@ private:
void DisableStructVars() { m_struct_vars.reset(); }
//----------------------------------------------------------------------
- /// Get this parser's ID for use in extracting parser- and JIT-specific
- /// data from persistent variables.
+ /// Get this parser's ID for use in extracting parser- and JIT-specific data
+ /// from persistent variables.
//----------------------------------------------------------------------
uint64_t GetParserID() { return (uint64_t) this; }
//------------------------------------------------------------------
- /// Given a target, find a variable that matches the given name and
- /// type.
+ /// Given a target, find a variable that matches the given name and type.
///
/// @param[in] target
/// The target to use as a basis for finding the variable.
@@ -477,8 +474,8 @@ private:
TypeFromUser *type = NULL);
//------------------------------------------------------------------
- /// Get the value of a variable in a given execution context and return
- /// the associated Types if needed.
+ /// Get the value of a variable in a given execution context and return the
+ /// associated Types if needed.
///
/// @param[in] var
/// The variable to evaluate.
@@ -524,8 +521,8 @@ private:
lldb::ValueObjectSP valobj, unsigned int current_id);
//------------------------------------------------------------------
- /// Use the NameSearchContext to generate a Decl for the given
- /// persistent variable, and put it in the list of found entities.
+ /// Use the NameSearchContext to generate a Decl for the given persistent
+ /// variable, and put it in the list of found entities.
///
/// @param[in] context
/// The NameSearchContext to use when constructing the Decl.
@@ -542,9 +539,8 @@ private:
unsigned int current_id);
//------------------------------------------------------------------
- /// Use the NameSearchContext to generate a Decl for the given LLDB
- /// symbol (treated as a variable), and put it in the list of found
- /// entities.
+ /// Use the NameSearchContext to generate a Decl for the given LLDB symbol
+ /// (treated as a variable), and put it in the list of found entities.
///
/// @param[in] context
/// The NameSearchContext to use when constructing the Decl.
@@ -556,9 +552,9 @@ private:
unsigned int current_id);
//------------------------------------------------------------------
- /// Use the NameSearchContext to generate a Decl for the given
- /// function. (Functions are not placed in the Tuple list.) Can
- /// handle both fully typed functions and generic functions.
+ /// Use the NameSearchContext to generate a Decl for the given function.
+ /// (Functions are not placed in the Tuple list.) Can handle both fully
+ /// typed functions and generic functions.
///
/// @param[in] context
/// The NameSearchContext to use when constructing the Decl.
@@ -575,8 +571,7 @@ private:
unsigned int current_id);
//------------------------------------------------------------------
- /// Use the NameSearchContext to generate a Decl for the given
- /// register.
+ /// Use the NameSearchContext to generate a Decl for the given register.
///
/// @param[in] context
/// The NameSearchContext to use when constructing the Decl.
@@ -588,8 +583,8 @@ private:
unsigned int current_id);
//------------------------------------------------------------------
- /// Use the NameSearchContext to generate a Decl for the given
- /// type. (Types are not placed in the Tuple list.)
+ /// Use the NameSearchContext to generate a Decl for the given type. (Types
+ /// are not placed in the Tuple list.)
///
/// @param[in] context
/// The NameSearchContext to use when constructing the Decl.
@@ -601,8 +596,8 @@ private:
unsigned int current_id);
//------------------------------------------------------------------
- /// Generate a Decl for "*this" and add a member function declaration
- /// to it for the expression, then report it.
+ /// Generate a Decl for "*this" and add a member function declaration to it
+ /// for the expression, then report it.
///
/// @param[in] context
/// The NameSearchContext to use when constructing the Decl.
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index d9e53074b3fb..c5406fcc3340 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -182,8 +182,7 @@ public:
m_manager->AddDiagnostic(new_diagnostic);
// Don't store away warning fixits, since the compiler doesn't have
- // enough
- // context in an expression for the warning to be useful.
+ // enough context in an expression for the warning to be useful.
// FIXME: Should we try to filter out FixIts that apply to our generated
// code, and not the user's expression?
if (severity == eDiagnosticSeverityError) {
@@ -226,10 +225,9 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope,
m_code_generator(), m_pp_callbacks(nullptr) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- // We can't compile expressions without a target. So if the exe_scope is null
- // or doesn't have a target,
- // then we just need to get out of here. I'll lldb_assert and not make any of
- // the compiler objects since
+ // We can't compile expressions without a target. So if the exe_scope is
+ // null or doesn't have a target, then we just need to get out of here. I'll
+ // lldb_assert and not make any of the compiler objects since
// I can't return errors directly from the constructor. Further calls will
// check if the compiler was made and
// bag out if it wasn't.
@@ -262,14 +260,14 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope,
const auto target_machine = target_arch.GetMachine();
- // If the expression is being evaluated in the context of an existing
- // stack frame, we introspect to see if the language runtime is available.
+ // If the expression is being evaluated in the context of an existing stack
+ // frame, we introspect to see if the language runtime is available.
lldb::StackFrameSP frame_sp = exe_scope->CalculateStackFrame();
lldb::ProcessSP process_sp = exe_scope->CalculateProcess();
- // Make sure the user hasn't provided a preferred execution language
- // with `expression --language X -- ...`
+ // Make sure the user hasn't provided a preferred execution language with
+ // `expression --language X -- ...`
if (frame_sp && frame_lang == lldb::eLanguageTypeUnknown)
frame_lang = frame_sp->GetLanguage();
@@ -281,8 +279,7 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope,
}
// 2. Configure the compiler with a set of default options that are
- // appropriate
- // for most situations.
+ // appropriate for most situations.
if (target_arch.IsValid()) {
std::string triple = target_arch.GetTriple().str();
m_compiler->getTargetOpts().Triple = triple;
@@ -292,19 +289,17 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope,
} else {
// If we get here we don't have a valid target and just have to guess.
// Sometimes this will be ok to just use the host target triple (when we
- // evaluate say "2+3", but other
- // expressions like breakpoint conditions and other things that _are_ target
- // specific really shouldn't just be
- // using the host triple. In such a case the language runtime should expose
- // an overridden options set (3),
- // below.
+ // evaluate say "2+3", but other expressions like breakpoint conditions and
+ // other things that _are_ target specific really shouldn't just be using
+ // the host triple. In such a case the language runtime should expose an
+ // overridden options set (3), below.
m_compiler->getTargetOpts().Triple = llvm::sys::getDefaultTargetTriple();
if (log)
log->Printf("Using default target triple of %s",
m_compiler->getTargetOpts().Triple.c_str());
}
- // Now add some special fixes for known architectures:
- // Any arm32 iOS environment, but not on arm64
+ // Now add some special fixes for known architectures: Any arm32 iOS
+ // environment, but not on arm64
if (m_compiler->getTargetOpts().Triple.find("arm64") == std::string::npos &&
m_compiler->getTargetOpts().Triple.find("arm") != std::string::npos &&
m_compiler->getTargetOpts().Triple.find("ios") != std::string::npos) {
@@ -317,8 +312,8 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope,
m_compiler->getTargetOpts().Features.push_back("+sse2");
}
- // Set the target CPU to generate code for.
- // This will be empty for any CPU that doesn't really need to make a special
+ // Set the target CPU to generate code for. This will be empty for any CPU
+ // that doesn't really need to make a special
// CPU string.
m_compiler->getTargetOpts().CPU = target_arch.GetClangTargetCPU();
@@ -328,11 +323,9 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope,
m_compiler->getTargetOpts().ABI = abi;
// 3. Now allow the runtime to provide custom configuration options for the
- // target.
- // In this case, a specialized language runtime is available and we can query
- // it for extra options.
- // For 99% of use cases, this will not be needed and should be provided when
- // basic platform detection is not enough.
+ // target. In this case, a specialized language runtime is available and we
+ // can query it for extra options. For 99% of use cases, this will not be
+ // needed and should be provided when basic platform detection is not enough.
if (lang_rt)
overridden_target_opts =
lang_rt->GetOverrideExprOptions(m_compiler->getTargetOpts());
@@ -378,9 +371,9 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope,
case lldb::eLanguageTypeC11:
// FIXME: the following language option is a temporary workaround,
// to "ask for C, get C++."
- // For now, the expression parser must use C++ anytime the
- // language is a C family language, because the expression parser
- // uses features of C++ to capture values.
+ // For now, the expression parser must use C++ anytime the language is a C
+ // family language, because the expression parser uses features of C++ to
+ // capture values.
m_compiler->getLangOpts().CPlusPlus = true;
break;
case lldb::eLanguageTypeObjC:
@@ -392,10 +385,10 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope,
// Clang now sets as default C++14 as the default standard (with
// GNU extensions), so we do the same here to avoid mismatches that
- // cause compiler error when evaluating expressions (e.g. nullptr
- // not found as it's a C++11 feature). Currently lldb evaluates
- // C++14 as C++11 (see two lines below) so we decide to be consistent
- // with that, but this could be re-evaluated in the future.
+ // cause compiler error when evaluating expressions (e.g. nullptr not found
+ // as it's a C++11 feature). Currently lldb evaluates C++14 as C++11 (see
+ // two lines below) so we decide to be consistent with that, but this could
+ // be re-evaluated in the future.
m_compiler->getLangOpts().CPlusPlus11 = true;
break;
case lldb::eLanguageTypeC_plus_plus:
@@ -407,8 +400,8 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope,
case lldb::eLanguageTypeC_plus_plus_03:
m_compiler->getLangOpts().CPlusPlus = true;
// FIXME: the following language option is a temporary workaround,
- // to "ask for C++, get ObjC++". Apple hopes to remove this requirement
- // on non-Apple platforms, but for now it is needed.
+ // to "ask for C++, get ObjC++". Apple hopes to remove this requirement on
+ // non-Apple platforms, but for now it is needed.
m_compiler->getLangOpts().ObjC1 = true;
break;
case lldb::eLanguageTypeObjC_plus_plus:
@@ -434,10 +427,9 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope,
ArchSpec(m_compiler->getTargetOpts().Triple.c_str())
.CharIsSignedByDefault();
- // Spell checking is a nice feature, but it ends up completing a
- // lot of types that we didn't strictly speaking need to complete.
- // As a result, we spend a long time parsing and importing debug
- // information.
+ // Spell checking is a nice feature, but it ends up completing a lot of types
+ // that we didn't strictly speaking need to complete. As a result, we spend a
+ // long time parsing and importing debug information.
m_compiler->getLangOpts().SpellChecking = false;
if (process_sp && m_compiler->getLangOpts().ObjC1) {
@@ -513,8 +505,8 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope,
m_compiler->getPreprocessor().addPPCallbacks(std::move(pp_callbacks));
}
- // 8. Most of this we get from the CompilerInstance, but we
- // also want to give the context an ExternalASTSource.
+ // 8. Most of this we get from the CompilerInstance, but we also want to give
+ // the context an ExternalASTSource.
m_selector_table.reset(new SelectorTable());
m_builtin_context.reset(new Builtin::Context());
@@ -569,9 +561,7 @@ unsigned ClangExpressionParser::Parse(DiagnosticManager &diagnostic_manager) {
codegenoptions::FullDebugInfo) {
int temp_fd = -1;
llvm::SmallString<PATH_MAX> result_path;
- FileSpec tmpdir_file_spec;
- if (HostInfo::GetLLDBPath(lldb::ePathTypeLLDBTempSystemDir,
- tmpdir_file_spec)) {
+ if (FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir()) {
tmpdir_file_spec.AppendPathComponent("lldb-%%%%%%.expr");
std::string temp_source_path = tmpdir_file_spec.GetPath();
llvm::sys::fs::createUniqueFile(temp_source_path, temp_fd, result_path);
@@ -811,7 +801,7 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution(
{
auto lang = m_expr.Language();
if (log)
- log->Printf("%s - Currrent expression language is %s\n", __FUNCTION__,
+ log->Printf("%s - Current expression language is %s\n", __FUNCTION__,
Language::GetNameForLanguageType(lang));
lldb::ProcessSP process_sp = exe_ctx.GetProcessSP();
if (process_sp && lang != lldb::eLanguageTypeUnknown) {
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
index 41f290f2e127..4058ec1270b3 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
@@ -26,14 +26,14 @@ class IRExecutionUnit;
//----------------------------------------------------------------------
/// @class ClangExpressionParser ClangExpressionParser.h
-/// "lldb/Expression/ClangExpressionParser.h"
-/// @brief Encapsulates an instance of Clang that can parse expressions.
+/// "lldb/Expression/ClangExpressionParser.h" Encapsulates an instance of
+/// Clang that can parse expressions.
///
/// ClangExpressionParser is responsible for preparing an instance of
/// ClangExpression for execution. ClangExpressionParser uses ClangExpression
/// as a glorified parameter list, performing the required parsing and
-/// conversion to formats (DWARF bytecode, or JIT compiled machine code)
-/// that can be executed.
+/// conversion to formats (DWARF bytecode, or JIT compiled machine code) that
+/// can be executed.
//----------------------------------------------------------------------
class ClangExpressionParser : public ExpressionParser {
public:
@@ -59,8 +59,8 @@ public:
~ClangExpressionParser() override;
//------------------------------------------------------------------
- /// Parse a single expression and convert it to IR using Clang. Don't
- /// wrap the expression in anything at all.
+ /// Parse a single expression and convert it to IR using Clang. Don't wrap
+ /// the expression in anything at all.
///
/// @param[in] diagnostic_manager
/// The diagnostic manager to report errors to.
@@ -74,8 +74,8 @@ public:
bool RewriteExpression(DiagnosticManager &diagnostic_manager) override;
//------------------------------------------------------------------
- /// Ready an already-parsed expression for execution, possibly
- /// evaluating it statically.
+ /// Ready an already-parsed expression for execution, possibly evaluating it
+ /// statically.
///
/// @param[out] func_addr
/// The address to which the function has been written.
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
index baa80d7ba0d4..7d5ced5b4705 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
@@ -41,27 +41,25 @@ class ValueObjectConstResult;
//----------------------------------------------------------------------
/// @class ClangExpressionVariable ClangExpressionVariable.h
-/// "lldb/Expression/ClangExpressionVariable.h"
-/// @brief Encapsulates one variable for the expression parser.
+/// "lldb/Expression/ClangExpressionVariable.h" Encapsulates one variable for
+/// the expression parser.
///
/// The expression parser uses variables in three different contexts:
///
-/// First, it stores persistent variables along with the process for use
-/// in expressions. These persistent variables contain their own data
-/// and are typed.
+/// First, it stores persistent variables along with the process for use in
+/// expressions. These persistent variables contain their own data and are
+/// typed.
///
-/// Second, in an interpreted expression, it stores the local variables
-/// for the expression along with the expression. These variables
-/// contain their own data and are typed.
+/// Second, in an interpreted expression, it stores the local variables for
+/// the expression along with the expression. These variables contain their
+/// own data and are typed.
///
-/// Third, in a JIT-compiled expression, it stores the variables that
-/// the expression needs to have materialized and dematerialized at each
-/// execution. These do not contain their own data but are named and
-/// typed.
+/// Third, in a JIT-compiled expression, it stores the variables that the
+/// expression needs to have materialized and dematerialized at each
+/// execution. These do not contain their own data but are named and typed.
///
-/// This class supports all of these use cases using simple type
-/// polymorphism, and provides necessary support methods. Its interface
-/// is RTTI-neutral.
+/// This class supports all of these use cases using simple type polymorphism,
+/// and provides necessary support methods. Its interface is RTTI-neutral.
//----------------------------------------------------------------------
class ClangExpressionVariable : public ExpressionVariable {
public:
@@ -79,8 +77,8 @@ public:
lldb::ByteOrder byte_order, uint32_t addr_byte_size);
//----------------------------------------------------------------------
- /// Utility functions for dealing with ExpressionVariableLists in
- /// Clang-specific ways
+ /// Utility functions for dealing with ExpressionVariableLists in Clang-
+ /// specific ways
//----------------------------------------------------------------------
//----------------------------------------------------------------------
@@ -112,9 +110,9 @@ public:
}
//----------------------------------------------------------------------
- /// If the variable contains its own data, make a Value point at it.
- /// If \a exe_ctx in not NULL, the value will be resolved in with
- /// that execution context.
+ /// If the variable contains its own data, make a Value point at it. If \a
+ /// exe_ctx in not NULL, the value will be resolved in with that execution
+ /// context.
///
/// @param[in] value
/// The value to point at the data.
@@ -156,8 +154,8 @@ private:
public:
//----------------------------------------------------------------------
- /// Make this variable usable by the parser by allocating space for
- /// parser-specific variables
+ /// Make this variable usable by the parser by allocating space for parser-
+ /// specific variables
//----------------------------------------------------------------------
void EnableParserVars(uint64_t parser_id) {
m_parser_vars.insert(std::make_pair(parser_id, ParserVars()));
diff --git a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
index a26ceda82d5f..e3e0ed49181e 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
@@ -101,14 +101,12 @@ ClangFunctionCaller::CompileFunction(lldb::ThreadSP thread_to_use_sp,
m_wrapper_function_text.append(" (*fn_ptr) (");
// Get the number of arguments. If we have a function type and it is
- // prototyped,
- // trust that, otherwise use the values we were given.
+ // prototyped, trust that, otherwise use the values we were given.
// FIXME: This will need to be extended to handle Variadic functions. We'll
// need
// to pull the defined arguments out of the function, then add the types from
- // the
- // arguments list for the variable arguments.
+ // the arguments list for the variable arguments.
uint32_t num_args = UINT32_MAX;
bool trust_function = false;
diff --git a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
index 0596d8fde7b9..438cf0c713da 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
@@ -31,8 +31,8 @@ class ClangExpressionParser;
//----------------------------------------------------------------------
/// @class ClangFunctionCaller ClangFunctionCaller.h
-/// "lldb/Expression/ClangFunctionCaller.h"
-/// @brief Encapsulates a function that can be called.
+/// "lldb/Expression/ClangFunctionCaller.h" Encapsulates a function that can
+/// be called.
///
/// A given ClangFunctionCaller object can handle a single function signature.
/// Once constructed, it can set up any number of concurrent calls to
@@ -56,8 +56,8 @@ class ClangExpressionParser;
/// If you need to call the function on the thread plan stack, you can also
/// call InsertFunction() followed by GetThreadPlanToCallFunction().
///
-/// Any of the methods that take arg_addr_ptr or arg_addr_ref can be passed
-/// a pointer set to LLDB_INVALID_ADDRESS and new structure will be allocated
+/// Any of the methods that take arg_addr_ptr or arg_addr_ref can be passed a
+/// pointer set to LLDB_INVALID_ADDRESS and new structure will be allocated
/// and its address returned in that variable.
///
/// Any of the methods that take arg_addr_ptr can be passed NULL, and the
@@ -79,8 +79,8 @@ class ClangFunctionCaller : public FunctionCaller {
ClangExpressionDeclMap *DeclMap() override { return NULL; }
//------------------------------------------------------------------
- /// Return the object that the parser should allow to access ASTs.
- /// May be NULL if the ASTs do not need to be transformed.
+ /// Return the object that the parser should allow to access ASTs. May be
+ /// NULL if the ASTs do not need to be transformed.
///
/// @param[in] passthrough
/// The ASTConsumer that the returned transformer should send
diff --git a/source/Plugins/ExpressionParser/Clang/ClangHost.cpp b/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
new file mode 100644
index 000000000000..4251d2ee75b9
--- /dev/null
+++ b/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
@@ -0,0 +1,142 @@
+//===-- ClangHost.cpp -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClangHost.h"
+
+#include "clang/Basic/Version.h"
+#include "clang/Config/config.h"
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Threading.h"
+
+// Project includes
+#include "lldb/Host/HostInfo.h"
+#if !defined(_WIN32)
+#include "lldb/Host/posix/HostInfoPosix.h"
+#endif
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Log.h"
+
+#include <string>
+
+using namespace lldb_private;
+
+#if defined(_WIN32)
+static bool ComputeClangDirectory(FileSpec &file_spec) { return false; }
+#else
+static bool DefaultComputeClangDirectory(FileSpec &file_spec) {
+ return HostInfoPosix::ComputePathRelativeToLibrary(
+ file_spec, (llvm::Twine("/lib") + CLANG_LIBDIR_SUFFIX + "/clang/" +
+ CLANG_VERSION_STRING)
+ .str());
+}
+
+#if defined(__APPLE__)
+
+static bool VerifyClangPath(const llvm::Twine &clang_path) {
+ if (llvm::sys::fs::is_directory(clang_path))
+ return true;
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ if (log)
+ log->Printf("VerifyClangPath(): "
+ "failed to stat clang resource directory at \"%s\"",
+ clang_path.str().c_str());
+ return false;
+}
+
+bool lldb_private::ComputeClangDirectory(FileSpec &lldb_shlib_spec,
+ FileSpec &file_spec, bool verify) {
+ std::string raw_path = lldb_shlib_spec.GetPath();
+
+ auto rev_it = llvm::sys::path::rbegin(raw_path);
+ auto r_end = llvm::sys::path::rend(raw_path);
+
+ // Check for a Posix-style build of LLDB.
+ while (rev_it != r_end) {
+ if (*rev_it == "LLDB.framework")
+ break;
+ ++rev_it;
+ }
+
+ if (rev_it == r_end)
+ return DefaultComputeClangDirectory(file_spec);
+
+ // Inside Xcode and in Xcode toolchains LLDB is always in lockstep
+ // with the Swift compiler, so it can reuse its Clang resource
+ // directory. This allows LLDB and the Swift compiler to share the
+ // same Clang module cache.
+ llvm::SmallString<256> clang_path;
+ const char *swift_clang_resource_dir = "usr/lib/swift/clang";
+ auto parent = std::next(rev_it);
+ if (parent != r_end && *parent == "SharedFrameworks") {
+ // This is the top-level LLDB in the Xcode.app bundle.
+ // E.g., "Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A"
+ raw_path.resize(parent - r_end);
+ llvm::sys::path::append(clang_path, raw_path,
+ "Developer/Toolchains/XcodeDefault.xctoolchain",
+ swift_clang_resource_dir);
+ if (!verify || VerifyClangPath(clang_path)) {
+ file_spec.SetFile(clang_path.c_str(), true, FileSpec::Style::native);
+ return true;
+ }
+ } else if (parent != r_end && *parent == "PrivateFrameworks" &&
+ std::distance(parent, r_end) > 2) {
+ ++parent;
+ ++parent;
+ if (*parent == "System") {
+ // This is LLDB inside an Xcode toolchain.
+ // E.g., "Xcode.app/Contents/Developer/Toolchains/" \
+ // "My.xctoolchain/System/Library/PrivateFrameworks/LLDB.framework"
+ raw_path.resize(parent - r_end);
+ llvm::sys::path::append(clang_path, raw_path, swift_clang_resource_dir);
+ if (!verify || VerifyClangPath(clang_path)) {
+ file_spec.SetFile(clang_path.c_str(), true, FileSpec::Style::native);
+ return true;
+ }
+ raw_path = lldb_shlib_spec.GetPath();
+ }
+ raw_path.resize(rev_it - r_end);
+ } else {
+ raw_path.resize(rev_it - r_end);
+ }
+
+ // Fall back to the Clang resource directory inside the framework.
+ raw_path.append("LLDB.framework/Resources/Clang");
+ file_spec.SetFile(raw_path.c_str(), true, FileSpec::Style::native);
+ return true;
+}
+
+static bool ComputeClangDirectory(FileSpec &file_spec) {
+ if (FileSpec lldb_file_spec = HostInfo::GetShlibDir())
+ return ComputeClangDirectory(lldb_file_spec, file_spec, true);
+ return false;
+}
+#else // __APPLE__
+
+// All non-Apple posix systems.
+static bool ComputeClangDirectory(FileSpec &file_spec) {
+ return DefaultComputeClangDirectory(file_spec);
+}
+#endif // __APPLE__
+#endif // _WIN32
+
+FileSpec lldb_private::GetClangResourceDir() {
+ static FileSpec g_cached_resource_dir;
+ static llvm::once_flag g_once_flag;
+ llvm::call_once(g_once_flag, []() {
+ ::ComputeClangDirectory(g_cached_resource_dir);
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ if (log)
+ log->Printf("GetClangResourceDir() => '%s'",
+ g_cached_resource_dir.GetPath().c_str());
+ });
+ return g_cached_resource_dir;
+}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangHost.h b/source/Plugins/ExpressionParser/Clang/ClangHost.h
new file mode 100644
index 000000000000..4fe423adb1a5
--- /dev/null
+++ b/source/Plugins/ExpressionParser/Clang/ClangHost.h
@@ -0,0 +1,26 @@
+//===-- ClangHost.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGHOST_H
+#define LLDB_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGHOST_H
+
+namespace lldb_private {
+
+class FileSpec;
+
+#if defined(__APPLE__)
+bool ComputeClangDirectory(FileSpec &lldb_shlib_spec, FileSpec &file_spec,
+ bool verify);
+#endif
+
+FileSpec GetClangResourceDir();
+
+} // namespace lldb_private
+
+#endif
diff --git a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
index b42ceb9afee8..665195f01774 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
@@ -25,8 +25,10 @@
#include "llvm/Support/Threading.h"
// Project includes
+#include "ClangHost.h"
#include "ClangModulesDeclVendor.h"
+#include "lldb/Core/ModuleList.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/CompileUnit.h"
@@ -39,9 +41,9 @@
using namespace lldb_private;
namespace {
-// Any Clang compiler requires a consumer for diagnostics. This one stores them
-// as strings
-// so we can provide them to the user in case a module failed to load.
+// Any Clang compiler requires a consumer for diagnostics. This one stores
+// them as strings so we can provide them to the user in case a module failed
+// to load.
class StoringDiagnosticConsumer : public clang::DiagnosticConsumer {
public:
StoringDiagnosticConsumer();
@@ -61,8 +63,7 @@ private:
};
// The private implementation of our ClangModulesDeclVendor. Contains all the
-// Clang state required
-// to load modules.
+// Clang state required to load modules.
class ClangModulesDeclVendorImpl : public ClangModulesDeclVendor {
public:
ClangModulesDeclVendorImpl(
@@ -144,18 +145,6 @@ void StoringDiagnosticConsumer::DumpDiagnostics(Stream &error_stream) {
}
}
-static FileSpec GetResourceDir() {
- static FileSpec g_cached_resource_dir;
-
- static llvm::once_flag g_once_flag;
-
- llvm::call_once(g_once_flag, []() {
- HostInfo::GetLLDBPath(lldb::ePathTypeClangDir, g_cached_resource_dir);
- });
-
- return g_cached_resource_dir;
-}
-
ClangModulesDeclVendor::ClangModulesDeclVendor() {}
ClangModulesDeclVendor::~ClangModulesDeclVendor() {}
@@ -168,7 +157,7 @@ ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl(
: m_diagnostics_engine(std::move(diagnostics_engine)),
m_compiler_invocation(std::move(compiler_invocation)),
m_compiler_instance(std::move(compiler_instance)),
- m_parser(std::move(parser)) {}
+ m_parser(std::move(parser)), m_origin_map() {}
void ClangModulesDeclVendorImpl::ReportModuleExportsHelper(
std::set<ClangModulesDeclVendor::ModuleID> &exports,
@@ -590,14 +579,11 @@ ClangModulesDeclVendor::Create(Target &target) {
// Add additional search paths with { "-I", path } or { "-F", path } here.
{
- llvm::SmallString<128> DefaultModuleCache;
- const bool erased_on_reboot = false;
- llvm::sys::path::system_temp_directory(erased_on_reboot,
- DefaultModuleCache);
- llvm::sys::path::append(DefaultModuleCache, "org.llvm.clang");
- llvm::sys::path::append(DefaultModuleCache, "ModuleCache");
+ llvm::SmallString<128> path;
+ auto props = ModuleList::GetGlobalModuleListProperties();
+ props.GetClangModulesCachePath().GetPath(path);
std::string module_cache_argument("-fmodules-cache-path=");
- module_cache_argument.append(DefaultModuleCache.str().str());
+ module_cache_argument.append(path.str());
compiler_invocation_arguments.push_back(module_cache_argument);
}
@@ -613,7 +599,7 @@ ClangModulesDeclVendor::Create(Target &target) {
}
{
- FileSpec clang_resource_dir = GetResourceDir();
+ FileSpec clang_resource_dir = GetClangResourceDir();
if (llvm::sys::fs::is_directory(clang_resource_dir.GetPath())) {
compiler_invocation_arguments.push_back("-resource-dir");
diff --git a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
index 8ebf78409a03..bb73d55a9a41 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
@@ -10,6 +10,7 @@
#include "ClangPersistentVariables.h"
#include "lldb/Core/Value.h"
+#include "lldb/Target/Target.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"
@@ -52,14 +53,6 @@ void ClangPersistentVariables::RemovePersistentVariable(
m_next_persistent_variable_id--;
}
-ConstString ClangPersistentVariables::GetNextPersistentVariableName() {
- char name_cstr[256];
- ::snprintf(name_cstr, sizeof(name_cstr), "$%u",
- m_next_persistent_variable_id++);
- ConstString name(name_cstr);
- return name;
-}
-
void ClangPersistentVariables::RegisterPersistentDecl(const ConstString &name,
clang::NamedDecl *decl) {
m_persistent_decls.insert(
diff --git a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
index 16981a7fe14a..59126974616d 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
@@ -25,9 +25,8 @@ namespace lldb_private {
//----------------------------------------------------------------------
/// @class ClangPersistentVariables ClangPersistentVariables.h
-/// "lldb/Expression/ClangPersistentVariables.h"
-/// @brief Manages persistent values that need to be preserved between
-/// expression invocations.
+/// "lldb/Expression/ClangPersistentVariables.h" Manages persistent values
+/// that need to be preserved between expression invocations.
///
/// A list of variables that can be accessed and updated by any expression. See
/// ClangPersistentVariable for more discussion. Also provides an increasing,
@@ -54,16 +53,11 @@ public:
const CompilerType &compiler_type, lldb::ByteOrder byte_order,
uint32_t addr_byte_size) override;
- //----------------------------------------------------------------------
- /// Return the next entry in the sequence of strings "$0", "$1", ... for
- /// use naming persistent expression convenience variables.
- ///
- /// @return
- /// A string that contains the next persistent variable name.
- //----------------------------------------------------------------------
- ConstString GetNextPersistentVariableName() override;
-
void RemovePersistentVariable(lldb::ExpressionVariableSP variable) override;
+ llvm::StringRef
+ GetPersistentVariablePrefix(bool is_error) const override {
+ return "$";
+ }
void RegisterPersistentDecl(const ConstString &name, clang::NamedDecl *decl);
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
index 18fe8b49227b..2e61f704127a 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
@@ -65,7 +65,8 @@ ClangUserExpression::ClangUserExpression(
options),
m_type_system_helper(*m_target_wp.lock().get(),
options.GetExecutionPolicy() ==
- eExecutionPolicyTopLevel) {
+ eExecutionPolicyTopLevel),
+ m_result_delegate(exe_scope.CalculateTarget()) {
switch (m_language) {
case lldb::eLanguageTypeC_plus_plus:
m_allow_cxx = true;
@@ -195,12 +196,10 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
} else if (clang::FunctionDecl *function_decl =
ClangASTContext::DeclContextGetAsFunctionDecl(decl_context)) {
// We might also have a function that said in the debug information that it
- // captured an
- // object pointer. The best way to deal with getting to the ivars at
- // present is by pretending
- // that this is a method of a class in whatever runtime the debug info says
- // the object pointer
- // belongs to. Do that here.
+ // captured an object pointer. The best way to deal with getting to the
+ // ivars at present is by pretending that this is a method of a class in
+ // whatever runtime the debug info says the object pointer belongs to. Do
+ // that here.
ClangASTMetadata *metadata =
ClangASTContext::DeclContextGetMetaData(decl_context, function_decl);
@@ -290,10 +289,10 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
}
}
-// This is a really nasty hack, meant to fix Objective-C expressions of the form
-// (int)[myArray count]. Right now, because the type information for count is
-// not available, [myArray count] returns id, which can't be directly cast to
-// int without causing a clang error.
+// This is a really nasty hack, meant to fix Objective-C expressions of the
+// form (int)[myArray count]. Right now, because the type information for
+// count is not available, [myArray count] returns id, which can't be directly
+// cast to int without causing a clang error.
static void ApplyObjcCastHack(std::string &expr) {
#define OBJC_CAST_HACK_FROM "(int)["
#define OBJC_CAST_HACK_TO "(int)(long long)["
@@ -308,17 +307,23 @@ static void ApplyObjcCastHack(std::string &expr) {
#undef OBJC_CAST_HACK_FROM
}
-bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
- ExecutionContext &exe_ctx,
- lldb_private::ExecutionPolicy execution_policy,
- bool keep_result_in_memory,
- bool generate_debug_info) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+namespace {
+// Utility guard that calls a callback when going out of scope.
+class OnExit {
+public:
+ typedef std::function<void(void)> Callback;
- Status err;
+ OnExit(Callback const &callback) : m_callback(callback) {}
- InstallContext(exe_ctx);
+ ~OnExit() { m_callback(); }
+
+private:
+ Callback m_callback;
+};
+} // namespace
+bool ClangUserExpression::SetupPersistentState(DiagnosticManager &diagnostic_manager,
+ ExecutionContext &exe_ctx) {
if (Target *target = exe_ctx.GetTargetPtr()) {
if (PersistentExpressionState *persistent_state =
target->GetPersistentExpressionStateForLanguage(
@@ -335,26 +340,15 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
"error: couldn't start parsing (no target)");
return false;
}
+ return true;
+}
- ScanContext(exe_ctx, err);
-
- if (!err.Success()) {
- diagnostic_manager.PutString(eDiagnosticSeverityWarning, err.AsCString());
- }
-
- ////////////////////////////////////
- // Generate the expression
- //
-
- ApplyObjcCastHack(m_expr_text);
-
- std::string prefix = m_expr_prefix;
-
+static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target) {
if (ClangModulesDeclVendor *decl_vendor =
- m_target->GetClangModulesDeclVendor()) {
+ target->GetClangModulesDeclVendor()) {
const ClangModulesDeclVendor::ModuleVector &hand_imported_modules =
llvm::cast<ClangPersistentVariables>(
- m_target->GetPersistentExpressionStateForLanguage(
+ target->GetPersistentExpressionStateForLanguage(
lldb::eLanguageTypeC))
->GetHandLoadedClangModules();
ClangModulesDeclVendor::ModuleVector modules_for_macros;
@@ -363,7 +357,7 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
modules_for_macros.push_back(module);
}
- if (m_target->GetEnableAutoImportClangModules()) {
+ if (target->GetEnableAutoImportClangModules()) {
if (StackFrame *frame = exe_ctx.GetFramePtr()) {
if (Block *block = frame->GetFrameBlock()) {
SymbolContext sc;
@@ -380,8 +374,13 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
}
}
}
+}
- lldb::LanguageType lang_type = lldb::eLanguageTypeUnknown;
+llvm::Optional<lldb::LanguageType> ClangUserExpression::GetLanguageForExpr(
+ DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) {
+ lldb::LanguageType lang_type = lldb::LanguageType::eLanguageTypeUnknown;
+
+ std::string prefix = m_expr_prefix;
if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) {
m_transformed_text = m_expr_text;
@@ -401,9 +400,50 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
exe_ctx)) {
diagnostic_manager.PutString(eDiagnosticSeverityError,
"couldn't construct expression body");
- return false;
+ return llvm::Optional<lldb::LanguageType>();
}
}
+ return lang_type;
+}
+
+bool ClangUserExpression::PrepareForParsing(
+ DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) {
+ InstallContext(exe_ctx);
+
+ if (!SetupPersistentState(diagnostic_manager, exe_ctx))
+ return false;
+
+ Status err;
+ ScanContext(exe_ctx, err);
+
+ if (!err.Success()) {
+ diagnostic_manager.PutString(eDiagnosticSeverityWarning, err.AsCString());
+ }
+
+ ////////////////////////////////////
+ // Generate the expression
+ //
+
+ ApplyObjcCastHack(m_expr_text);
+
+ SetupDeclVendor(exe_ctx, m_target);
+ return true;
+}
+
+bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
+ ExecutionContext &exe_ctx,
+ lldb_private::ExecutionPolicy execution_policy,
+ bool keep_result_in_memory,
+ bool generate_debug_info) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ if (!PrepareForParsing(diagnostic_manager, exe_ctx))
+ return false;
+
+ lldb::LanguageType lang_type = lldb::LanguageType::eLanguageTypeUnknown;
+ if (auto new_lang = GetLanguageForExpr(diagnostic_manager, exe_ctx)) {
+ lang_type = new_lang.getValue();
+ }
if (log)
log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
@@ -427,28 +467,12 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
ResetDeclMap(exe_ctx, m_result_delegate, keep_result_in_memory);
- class OnExit {
- public:
- typedef std::function<void(void)> Callback;
-
- OnExit(Callback const &callback) : m_callback(callback) {}
-
- ~OnExit() { m_callback(); }
-
- private:
- Callback m_callback;
- };
-
OnExit on_exit([this]() { ResetDeclMap(); });
if (!DeclMap()->WillParse(exe_ctx, m_materializer_ap.get())) {
diagnostic_manager.PutString(
eDiagnosticSeverityError,
"current process state is unsuitable for expression parsing");
-
- ResetDeclMap(); // We are being careful here in the case of breakpoint
- // conditions.
-
return false;
}
@@ -463,17 +487,15 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
exe_scope = exe_ctx.GetTargetPtr();
// We use a shared pointer here so we can use the original parser - if it
- // succeeds
- // or the rewrite parser we might make if it fails. But the parser_sp will
- // never be empty.
+ // succeeds or the rewrite parser we might make if it fails. But the
+ // parser_sp will never be empty.
ClangExpressionParser parser(exe_scope, *this, generate_debug_info);
unsigned num_errors = parser.Parse(diagnostic_manager);
// Check here for FixItHints. If there are any try to apply the fixits and
- // set the fixed text in m_fixed_text
- // before returning an error.
+ // set the fixed text in m_fixed_text before returning an error.
if (num_errors) {
if (diagnostic_manager.HasFixIts()) {
if (parser.RewriteExpression(diagnostic_manager)) {
@@ -487,16 +509,12 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
fixed_expression.substr(fixed_start, fixed_end - fixed_start);
}
}
-
- ResetDeclMap(); // We are being careful here in the case of breakpoint
- // conditions.
-
return false;
}
//////////////////////////////////////////////////////////////////////////////////////////
- // Prepare the output of the parser for execution, evaluating it statically if
- // possible
+ // Prepare the output of the parser for execution, evaluating it statically
+ // if possible
//
{
@@ -539,9 +557,9 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
register_execution_unit = true;
}
- // If there is more than one external function in the execution
- // unit, it needs to keep living even if it's not top level, because
- // the result could refer to that function.
+ // If there is more than one external function in the execution unit, it
+ // needs to keep living even if it's not top level, because the result
+ // could refer to that function.
if (m_execution_unit_sp->GetJittedFunctions().size() > 1) {
register_execution_unit = true;
@@ -568,10 +586,6 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
}
}
- ResetDeclMap(); // Make this go away since we don't need any of its state
- // after parsing. This also gets rid of any
- // ClangASTImporter::Minions.
-
if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
return true;
@@ -667,10 +681,10 @@ void ClangUserExpression::ClangUserExpressionHelper::CommitPersistentDecls() {
}
}
-ClangUserExpression::ResultDelegate::ResultDelegate() {}
-
ConstString ClangUserExpression::ResultDelegate::GetName() {
- return m_persistent_state->GetNextPersistentVariableName();
+ auto prefix = m_persistent_state->GetPersistentVariablePrefix();
+ return m_persistent_state->GetNextPersistentVariableName(*m_target_sp,
+ prefix);
}
void ClangUserExpression::ResultDelegate::DidDematerialize(
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
index 88a78798b657..ac363bf91747 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
@@ -35,13 +35,13 @@ namespace lldb_private {
//----------------------------------------------------------------------
/// @class ClangUserExpression ClangUserExpression.h
-/// "lldb/Expression/ClangUserExpression.h"
-/// @brief Encapsulates a single expression for use with Clang
+/// "lldb/Expression/ClangUserExpression.h" Encapsulates a single expression
+/// for use with Clang
///
/// LLDB uses expressions for various purposes, notably to call functions
/// and as a backend for the expr command. ClangUserExpression encapsulates
-/// the objects needed to parse and interpret or JIT an expression. It
-/// uses the Clang parser to produce LLVM IR from the expression.
+/// the objects needed to parse and interpret or JIT an expression. It uses
+/// the Clang parser to produce LLVM IR from the expression.
//----------------------------------------------------------------------
class ClangUserExpression : public LLVMUserExpression {
public:
@@ -69,8 +69,8 @@ public:
bool keep_result_in_memory);
//------------------------------------------------------------------
- /// Return the object that the parser should allow to access ASTs.
- /// May be NULL if the ASTs do not need to be transformed.
+ /// Return the object that the parser should allow to access ASTs. May be
+ /// NULL if the ASTs do not need to be transformed.
///
/// @param[in] passthrough
/// The ASTConsumer that the returned transformer should send
@@ -174,11 +174,18 @@ private:
lldb::addr_t struct_address,
DiagnosticManager &diagnostic_manager) override;
+ llvm::Optional<lldb::LanguageType> GetLanguageForExpr(
+ DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx);
+ bool SetupPersistentState(DiagnosticManager &diagnostic_manager,
+ ExecutionContext &exe_ctx);
+ bool PrepareForParsing(DiagnosticManager &diagnostic_manager,
+ ExecutionContext &exe_ctx);
+
ClangUserExpressionHelper m_type_system_helper;
class ResultDelegate : public Materializer::PersistentVariableDelegate {
public:
- ResultDelegate();
+ ResultDelegate(lldb::TargetSP target) : m_target_sp(target) {}
ConstString GetName() override;
void DidDematerialize(lldb::ExpressionVariableSP &variable) override;
@@ -188,6 +195,7 @@ private:
private:
PersistentExpressionState *m_persistent_state;
lldb::ExpressionVariableSP m_variable;
+ lldb::TargetSP m_target_sp;
};
ResultDelegate m_result_delegate;
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
index 80577199b818..a897a2b17087 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
@@ -29,15 +29,15 @@ namespace lldb_private {
//----------------------------------------------------------------------
/// @class ClangUtilityFunction ClangUtilityFunction.h
-/// "lldb/Expression/ClangUtilityFunction.h"
-/// @brief Encapsulates a single expression for use with Clang
+/// "lldb/Expression/ClangUtilityFunction.h" Encapsulates a single expression
+/// for use with Clang
///
/// LLDB uses expressions for various purposes, notably to call functions
/// and as a backend for the expr command. ClangUtilityFunction encapsulates
/// a self-contained function meant to be used from other code. Utility
/// functions can perform error-checking for ClangUserExpressions, or can
-/// simply provide a way to push a function into the target for the debugger to
-/// call later on.
+/// simply provide a way to push a function into the target for the debugger
+/// to call later on.
//----------------------------------------------------------------------
class ClangUtilityFunction : public UtilityFunction {
public:
@@ -60,8 +60,8 @@ public:
void ResetDeclMap(ExecutionContext &exe_ctx, bool keep_result_in_memory);
//------------------------------------------------------------------
- /// Return the object that the parser should allow to access ASTs.
- /// May be NULL if the ASTs do not need to be transformed.
+ /// Return the object that the parser should allow to access ASTs. May be
+ /// NULL if the ASTs do not need to be transformed.
///
/// @param[in] passthrough
/// The ASTConsumer that the returned transformer should send
diff --git a/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
index 13f5657eedd8..e51c9ee07b9f 100644
--- a/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
+++ b/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
@@ -263,8 +263,7 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
}
// Get the next available result name from m_decl_map and create the
- // persistent
- // variable for it
+ // persistent variable for it
// If the result is an Lvalue, it is emitted as a pointer; see
// ASTResultSynthesizer::SynthesizeBodyResult.
@@ -345,9 +344,9 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
GlobalValue::ExternalLinkage, NULL, /* no initializer */
m_result_name.GetCString());
- // It's too late in compilation to create a new VarDecl for this, but we don't
- // need to. We point the metadata at the old VarDecl. This creates an odd
- // anomaly: a variable with a Value whose name is something like $0 and a
+ // It's too late in compilation to create a new VarDecl for this, but we
+ // don't need to. We point the metadata at the old VarDecl. This creates an
+ // odd anomaly: a variable with a Value whose name is something like $0 and a
// Decl whose name is $__lldb_expr_result. This condition is handled in
// ClangExpressionDeclMap::DoMaterialize, and the name of the variable is
// fixed up.
@@ -464,9 +463,7 @@ bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str,
// CFAllocatorRef -> i8*
// UInt8 * -> i8*
// CFIndex -> long (i32 or i64, as appropriate; we ask the module for its
- // pointer size for now)
- // CFStringEncoding -> i32
- // Boolean -> i8
+ // pointer size for now) CFStringEncoding -> i32 Boolean -> i8
Type *arg_type_array[5];
@@ -801,9 +798,8 @@ bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) {
// Unpack the message name from the selector. In LLVM IR, an objc_msgSend
// gets represented as
//
- // %tmp = load i8** @"OBJC_SELECTOR_REFERENCES_" ; <i8*>
- // %call = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %obj, i8* %tmp, ...)
- // ; <i8*>
+ // %tmp = load i8** @"OBJC_SELECTOR_REFERENCES_" ; <i8*> %call = call
+ // i8* (i8*, i8*, ...)* @objc_msgSend(i8* %obj, i8* %tmp, ...) ; <i8*>
//
// where %obj is the object pointer and %tmp is the selector.
//
@@ -870,7 +866,8 @@ bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) {
log->Printf("Found sel_registerName at 0x%" PRIx64,
sel_registerName_addr);
- // Build the function type: struct objc_selector *sel_registerName(uint8_t*)
+ // Build the function type: struct objc_selector
+ // *sel_registerName(uint8_t*)
// The below code would be "more correct," but in actuality what's required
// is uint8_t*
@@ -980,11 +977,10 @@ bool IRForTarget::RewriteObjCClassReference(Instruction *class_load) {
// %struct._objc_class** @OBJC_CLASS_REFERENCES_, align 4
//
// @"OBJC_CLASS_REFERENCES_ is a bitcast of a character array called
- // @OBJC_CLASS_NAME_.
- // @OBJC_CLASS_NAME contains the string.
+ // @OBJC_CLASS_NAME_. @OBJC_CLASS_NAME contains the string.
- // Find the pointer's initializer (a ConstantExpr with opcode BitCast)
- // and get the string from its target
+ // Find the pointer's initializer (a ConstantExpr with opcode BitCast) and
+ // get the string from its target
GlobalVariable *_objc_class_references_ =
dyn_cast<GlobalVariable>(load->getPointerOperand());
@@ -1159,8 +1155,8 @@ bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) {
GlobalValue::ExternalLinkage, NULL, /* no initializer */
alloc->getName().str());
- // What we're going to do here is make believe this was a regular old external
- // variable. That means we need to make the metadata valid.
+ // What we're going to do here is make believe this was a regular old
+ // external variable. That means we need to make the metadata valid.
NamedMDNode *named_metadata =
m_module->getOrInsertNamedMetadata("clang.global.decl.ptrs");
@@ -1175,8 +1171,7 @@ bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) {
named_metadata->addOperand(persistent_global_md);
// Now, since the variable is a pointer variable, we will drop in a load of
- // that
- // pointer variable.
+ // that pointer variable.
LoadInst *persistent_load = new LoadInst(persistent_global, "", alloc);
@@ -1366,16 +1361,13 @@ bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
if (name[0] == '$') {
// The $__lldb_expr_result name indicates the return value has allocated
- // as
- // a static variable. Per the comment at
- // ASTResultSynthesizer::SynthesizeBodyResult,
- // accesses to this static variable need to be redirected to the result of
- // dereferencing
- // a pointer that is passed in as one of the arguments.
+ // as a static variable. Per the comment at
+ // ASTResultSynthesizer::SynthesizeBodyResult, accesses to this static
+ // variable need to be redirected to the result of dereferencing a
+ // pointer that is passed in as one of the arguments.
//
// Consequently, when reporting the size of the type, we report a pointer
- // type pointing
- // to the type of $__lldb_expr_result, not the type itself.
+ // type pointing to the type of $__lldb_expr_result, not the type itself.
//
// We also do this for any user-declared persistent variables.
compiler_type = compiler_type.GetPointerType();
@@ -1965,12 +1957,11 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) {
FunctionValueCache body_result_maker(
[this, name, offset_type, offset, argument,
value](llvm::Function *function) -> llvm::Value * {
- // Per the comment at ASTResultSynthesizer::SynthesizeBodyResult, in
- // cases where the result
- // variable is an rvalue, we have to synthesize a dereference of the
- // appropriate structure
- // entry in order to produce the static variable that the AST thinks
- // it is accessing.
+ // Per the comment at ASTResultSynthesizer::SynthesizeBodyResult,
+ // in cases where the result variable is an rvalue, we have to
+ // synthesize a dereference of the appropriate structure entry in
+ // order to produce the static variable that the AST thinks it is
+ // accessing.
llvm::Instruction *entry_instruction = llvm::cast<Instruction>(
m_entry_instruction_finder.GetValue(function));
@@ -2194,7 +2185,8 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
if (log)
log->Printf("RewriteObjCSelectors() failed");
- // RewriteObjCSelectors() reports its own errors, so we don't do so here
+ // RewriteObjCSelectors() reports its own errors, so we don't do so
+ // here
return false;
}
diff --git a/source/Plugins/ExpressionParser/Clang/IRForTarget.h b/source/Plugins/ExpressionParser/Clang/IRForTarget.h
index 93ce8aa44eb2..c6c44b46023c 100644
--- a/source/Plugins/ExpressionParser/Clang/IRForTarget.h
+++ b/source/Plugins/ExpressionParser/Clang/IRForTarget.h
@@ -47,12 +47,11 @@ class IRMemoryMap;
//----------------------------------------------------------------------
/// @class IRForTarget IRForTarget.h "lldb/Expression/IRForTarget.h"
-/// @brief Transforms the IR for a function to run in the target
+/// Transforms the IR for a function to run in the target
///
-/// Once an expression has been parsed and converted to IR, it can run
-/// in two contexts: interpreted by LLDB as a DWARF location expression,
-/// or compiled by the JIT and inserted into the target process for
-/// execution.
+/// Once an expression has been parsed and converted to IR, it can run in two
+/// contexts: interpreted by LLDB as a DWARF location expression, or compiled
+/// by the JIT and inserted into the target process for execution.
///
/// IRForTarget makes the second possible, by applying a series of
/// transformations to the IR which make it relocatable. These
@@ -126,8 +125,7 @@ public:
//------------------------------------------------------------------
/// Interface stub
///
- /// Implementation of the llvm::ModulePass::assignPassManager()
- /// function.
+ /// Implementation of the llvm::ModulePass::assignPassManager() function.
//------------------------------------------------------------------
void assignPassManager(llvm::PMStack &pass_mgr_stack,
llvm::PassManagerType pass_mgr_type =
@@ -179,8 +177,8 @@ private:
//------------------------------------------------------------------
//------------------------------------------------------------------
- /// Get the address of a function, and a location to put the complete
- /// Value of the function if one is available.
+ /// Get the address of a function, and a location to put the complete Value
+ /// of the function if one is available.
///
/// @param[in] function
/// The function to find the location of.
@@ -204,13 +202,13 @@ private:
//------------------------------------------------------------------
/// A function-level pass to take the generated global value
- /// $__lldb_expr_result and make it into a persistent variable.
- /// Also see ASTResultSynthesizer.
+ /// $__lldb_expr_result and make it into a persistent variable. Also see
+ /// ASTResultSynthesizer.
//------------------------------------------------------------------
//------------------------------------------------------------------
- /// Find the NamedDecl corresponding to a Value. This interface is
- /// exposed for the IR interpreter.
+ /// Find the NamedDecl corresponding to a Value. This interface is exposed
+ /// for the IR interpreter.
///
/// @param[in] module
/// The module containing metadata to search
@@ -230,8 +228,8 @@ private:
//------------------------------------------------------------------
/// Set the constant result variable m_const_result to the provided
- /// constant, assuming it can be evaluated. The result variable
- /// will be reset to NULL later if the expression has side effects.
+ /// constant, assuming it can be evaluated. The result variable will be
+ /// reset to NULL later if the expression has side effects.
///
/// @param[in] initializer
/// The constant initializer for the variable.
@@ -247,8 +245,8 @@ private:
lldb_private::TypeFromParser type);
//------------------------------------------------------------------
- /// If the IR represents a cast of a variable, set m_const_result
- /// to the result of the cast. The result variable will be reset to
+ /// If the IR represents a cast of a variable, set m_const_result to the
+ /// result of the cast. The result variable will be reset to
/// NULL latger if the expression has side effects.
///
/// @param[in] type
@@ -301,10 +299,9 @@ private:
/// rewrite them to use sel_registerName instead of statically allocated
/// selectors. The reason is that the selectors are created on the
/// assumption that the Objective-C runtime will scan the appropriate
- /// section and prepare them. This doesn't happen when code is copied
- /// into the target, though, and there's no easy way to induce the
- /// runtime to scan them. So instead we get our selectors from
- /// sel_registerName.
+ /// section and prepare them. This doesn't happen when code is copied into
+ /// the target, though, and there's no easy way to induce the runtime to
+ /// scan them. So instead we get our selectors from sel_registerName.
//------------------------------------------------------------------
//------------------------------------------------------------------
@@ -359,13 +356,12 @@ private:
//------------------------------------------------------------------
/// A basic block-level pass to find all newly-declared persistent
- /// variables and register them with the ClangExprDeclMap. This
- /// allows them to be materialized and dematerialized like normal
- /// external variables. Before transformation, these persistent
- /// variables look like normal locals, so they have an allocation.
- /// This pass excises these allocations and makes references look
- /// like external references where they will be resolved -- like all
- /// other external references -- by ResolveExternals().
+ /// variables and register them with the ClangExprDeclMap. This allows them
+ /// to be materialized and dematerialized like normal external variables.
+ /// Before transformation, these persistent variables look like normal
+ /// locals, so they have an allocation. This pass excises these allocations
+ /// and makes references look like external references where they will be
+ /// resolved -- like all other external references -- by ResolveExternals().
//------------------------------------------------------------------
//------------------------------------------------------------------
@@ -389,15 +385,14 @@ private:
//------------------------------------------------------------------
/// A function-level pass to find all external variables and functions
- /// used in the IR. Each found external variable is added to the
- /// struct, and each external function is resolved in place, its call
- /// replaced with a call to a function pointer whose value is the
- /// address of the function in the target process.
+ /// used in the IR. Each found external variable is added to the struct,
+ /// and each external function is resolved in place, its call replaced with
+ /// a call to a function pointer whose value is the address of the function
+ /// in the target process.
//------------------------------------------------------------------
//------------------------------------------------------------------
- /// Write an initializer to a memory array of assumed sufficient
- /// size.
+ /// Write an initializer to a memory array of assumed sufficient size.
///
/// @param[in] data
/// A pointer to the data to write to.
@@ -504,8 +499,8 @@ private:
//------------------------------------------------------------------
/// A basic block-level pass to excise guard variables from the code.
/// The result for the function is passed through Clang as a static
- /// variable. Static variables normally have guard variables to
- /// ensure that they are only initialized once.
+ /// variable. Static variables normally have guard variables to ensure that
+ /// they are only initialized once.
//------------------------------------------------------------------
//------------------------------------------------------------------
@@ -529,9 +524,9 @@ private:
//------------------------------------------------------------------
/// A function-level pass to make all external variable references
- /// point at the correct offsets from the void* passed into the
- /// function. ClangExpressionDeclMap::DoStructLayout() must be called
- /// beforehand, so that the offsets are valid.
+ /// point at the correct offsets from the void* passed into the function.
+ /// ClangExpressionDeclMap::DoStructLayout() must be called beforehand, so
+ /// that the offsets are valid.
//------------------------------------------------------------------
//------------------------------------------------------------------
@@ -583,7 +578,8 @@ private:
llvm::StoreInst *m_result_store; ///< If non-NULL, the store instruction that
///writes to the result variable. If
- /// m_has_side_effects is true, this is NULL.
+ /// m_has_side_effects is true, this is
+ /// NULL.
bool m_result_is_pointer; ///< True if the function's result in the AST is a
///pointer (see comments in
/// ASTResultSynthesizer::SynthesizeBodyResult)
@@ -594,18 +590,17 @@ private:
/// location of the static allocation.
//------------------------------------------------------------------
- /// UnfoldConstant operates on a constant [Old] which has just been
- /// replaced with a value [New]. We assume that new_value has
- /// been properly placed early in the function, in front of the
- /// first instruction in the entry basic block
- /// [FirstEntryInstruction].
+ /// UnfoldConstant operates on a constant [Old] which has just been replaced
+ /// with a value [New]. We assume that new_value has been properly placed
+ /// early in the function, in front of the first instruction in the entry
+ /// basic block [FirstEntryInstruction].
///
- /// UnfoldConstant reads through the uses of Old and replaces Old
- /// in those uses with New. Where those uses are constants, the
- /// function generates new instructions to compute the result of the
- /// new, non-constant expression and places them before
- /// FirstEntryInstruction. These instructions replace the constant
- /// uses, so UnfoldConstant calls itself recursively for those.
+ /// UnfoldConstant reads through the uses of Old and replaces Old in those
+ /// uses with New. Where those uses are constants, the function generates
+ /// new instructions to compute the result of the new, non-constant
+ /// expression and places them before FirstEntryInstruction. These
+ /// instructions replace the constant uses, so UnfoldConstant calls itself
+ /// recursively for those.
///
/// @param[in] llvm_function
/// The function currently being processed.
@@ -637,8 +632,8 @@ private:
lldb_private::Stream &error_stream);
//------------------------------------------------------------------
- /// Construct a reference to m_reloc_placeholder with a given type
- /// and offset. This typically happens after inserting data into
+ /// Construct a reference to m_reloc_placeholder with a given type and
+ /// offset. This typically happens after inserting data into
/// m_data_allocator.
///
/// @param[in] type
@@ -653,8 +648,8 @@ private:
llvm::Constant *BuildRelocation(llvm::Type *type, uint64_t offset);
//------------------------------------------------------------------
- /// Commit the allocation in m_data_allocator and use its final
- /// location to replace m_reloc_placeholder.
+ /// Commit the allocation in m_data_allocator and use its final location to
+ /// replace m_reloc_placeholder.
///
/// @param[in] module
/// The module that m_data_allocator resides in
diff --git a/source/Plugins/ExpressionParser/Go/GoParser.cpp b/source/Plugins/ExpressionParser/Go/GoParser.cpp
index 538bd05e25f8..9c845d02bca0 100644
--- a/source/Plugins/ExpressionParser/Go/GoParser.cpp
+++ b/source/Plugins/ExpressionParser/Go/GoParser.cpp
@@ -67,7 +67,9 @@ private:
size_t m_pos;
};
-GoParser::GoParser(const char *src) : m_lexer(src), m_pos(0), m_failed(false) {}
+GoParser::GoParser(const char *src)
+ : m_lexer(src), m_pos(0), m_last_tok(GoLexer::TOK_INVALID),
+ m_failed(false) {}
GoASTStmt *GoParser::Statement() {
Rule r("Statement", this);
@@ -437,8 +439,10 @@ GoASTExpr *GoParser::CompositeLit() {
if (!type)
return r.error();
GoASTCompositeLit *lit = LiteralValue();
- if (!lit)
+ if (!lit) {
+ delete type;
return r.error();
+ }
lit->SetType(type);
return lit;
}
@@ -546,6 +550,7 @@ GoASTExpr *GoParser::Arguments(GoASTExpr *e) {
GoASTExpr *GoParser::Conversion() {
Rule r("Conversion", this);
if (GoASTExpr *t = Type2()) {
+ std::unique_ptr<GoASTExpr> owner(t);
if (match(GoLexer::OP_LPAREN)) {
GoASTExpr *v = Expression();
if (!v)
@@ -555,6 +560,7 @@ GoASTExpr *GoParser::Conversion() {
return r.error();
GoASTCallExpr *call = new GoASTCallExpr(false);
call->SetFun(t);
+ owner.release();
call->AddArgs(v);
return call;
}
diff --git a/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp b/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp
index f4b8cfbe03d4..3a10a1dc767a 100644
--- a/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp
+++ b/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp
@@ -171,12 +171,11 @@ private:
VariableSP FindGlobalVariable(TargetSP target, llvm::Twine name) {
ConstString fullname(name.str());
VariableList variable_list;
- const bool append = true;
if (!target) {
return nullptr;
}
- const uint32_t match_count = target->GetImages().FindGlobalVariables(
- fullname, append, 1, variable_list);
+ const uint32_t match_count =
+ target->GetImages().FindGlobalVariables(fullname, 1, variable_list);
if (match_count == 1) {
return variable_list.GetVariableAtIndex(0);
}
@@ -272,7 +271,8 @@ GoUserExpression::DoExecute(DiagnosticManager &diagnostic_manager,
PersistentExpressionState *pv =
target->GetPersistentExpressionStateForLanguage(eLanguageTypeGo);
if (pv != nullptr) {
- result->SetName(pv->GetNextPersistentVariableName());
+ result->SetName(pv->GetNextPersistentVariableName(
+ *target, pv->GetPersistentVariablePrefix()));
pv->AddVariable(result);
}
return lldb::eExpressionCompleted;
@@ -400,8 +400,7 @@ ValueObjectSP GoUserExpression::GoInterpreter::VisitIdent(const GoASTIdent *e) {
val = m_frame->GetValueObjectForFrameVariable(var_sp, m_use_dynamic);
else {
// When a variable is on the heap instead of the stack, go records a
- // variable
- // '&x' instead of 'x'.
+ // variable '&x' instead of 'x'.
var_sp = var_list_sp->FindVariable(ConstString("&" + varname));
if (var_sp) {
val = m_frame->GetValueObjectForFrameVariable(var_sp, m_use_dynamic);
@@ -651,15 +650,6 @@ ValueObjectSP GoUserExpression::GoInterpreter::VisitCallExpr(
GoPersistentExpressionState::GoPersistentExpressionState()
: PersistentExpressionState(eKindGo) {}
-ConstString GoPersistentExpressionState::GetNextPersistentVariableName() {
- char name_cstr[256];
- // We can't use the same variable format as clang.
- ::snprintf(name_cstr, sizeof(name_cstr), "$go%u",
- m_next_persistent_variable_id++);
- ConstString name(name_cstr);
- return name;
-}
-
void GoPersistentExpressionState::RemovePersistentVariable(
lldb::ExpressionVariableSP variable) {
RemoveVariable(variable);
diff --git a/source/Plugins/ExpressionParser/Go/GoUserExpression.h b/source/Plugins/ExpressionParser/Go/GoUserExpression.h
index 03ceb76b8431..e2839da9bfdd 100644
--- a/source/Plugins/ExpressionParser/Go/GoUserExpression.h
+++ b/source/Plugins/ExpressionParser/Go/GoUserExpression.h
@@ -29,8 +29,10 @@ class GoPersistentExpressionState : public PersistentExpressionState {
public:
GoPersistentExpressionState();
- ConstString GetNextPersistentVariableName() override;
-
+ llvm::StringRef
+ GetPersistentVariablePrefix(bool is_error) const override {
+ return "$go";
+ }
void RemovePersistentVariable(lldb::ExpressionVariableSP variable) override;
lldb::addr_t LookupSymbol(const ConstString &name) override {
@@ -48,12 +50,12 @@ private:
//----------------------------------------------------------------------
/// @class GoUserExpression GoUserExpression.h
-/// "lldb/Expression/GoUserExpression.h"
-/// @brief Encapsulates a single expression for use with Go
+/// "lldb/Expression/GoUserExpression.h" Encapsulates a single expression for
+/// use with Go
///
/// LLDB uses expressions for various purposes, notably to call functions
-/// and as a backend for the expr command. GoUserExpression encapsulates
-/// the objects needed to parse and interpret an expression.
+/// and as a backend for the expr command. GoUserExpression encapsulates the
+/// objects needed to parse and interpret an expression.
//----------------------------------------------------------------------
class GoUserExpression : public UserExpression {
public:
diff --git a/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
index 262a7914d249..86744520ad63 100644
--- a/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
+++ b/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
@@ -258,8 +258,8 @@ static bool GetARMDWARFRegisterInfo(unsigned reg_num, RegisterInfo &reg_info) {
reg_info.name = "f7";
break;
- // Intel wireless MMX general purpose registers 0 - 7
- // XScale accumulator register 0 - 7 (they do overlap with wCGR0 - wCGR7)
+ // Intel wireless MMX general purpose registers 0 - 7 XScale accumulator
+ // register 0 - 7 (they do overlap with wCGR0 - wCGR7)
case dwarf_wCGR0:
reg_info.name = "wCGR0/ACC0";
break;
@@ -901,7 +901,8 @@ uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const {
}
// Push Multiple Registers stores multiple registers to the stack, storing to
-// consecutive memory locations ending just below the address in SP, and updates
+// consecutive memory locations ending just below the address in SP, and
+// updates
// SP to point to the start of the stored data.
bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode,
const ARMEncoding encoding) {
@@ -1390,8 +1391,8 @@ bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode,
uint32_t imm32; // the immediate value to be written to Rd
uint32_t carry =
0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
- // for setflags == false, this value is a don't care
- // initialized to 0 to silence the static analyzer
+ // for setflags == false, this value is a don't care initialized to
+ // 0 to silence the static analyzer
bool setflags;
switch (encoding) {
case eEncodingT1:
@@ -1473,12 +1474,11 @@ bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode,
// MUL multiplies two register values. The least significant 32 bits of the
// result are written to the destination
// register. These 32 bits do not depend on whether the source register values
-// are considered to be signed values or
-// unsigned values.
+// are considered to be signed values or unsigned values.
//
// Optionally, it can update the condition flags based on the result. In the
-// Thumb instruction set, this option is
-// limited to only a few forms of the instruction.
+// Thumb instruction set, this option is limited to only a few forms of the
+// instruction.
bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -1606,8 +1606,8 @@ bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode,
}
// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to
-// the destination register.
-// It can optionally update the condition flags based on the value.
+// the destination register. It can optionally update the condition flags based
+// on the value.
bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -1666,8 +1666,8 @@ bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode,
}
// Bitwise NOT (register) writes the bitwise inverse of a register value to the
-// destination register.
-// It can optionally update the condition flags based on the result.
+// destination register. It can optionally update the condition flags based on
+// the result.
bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -2005,9 +2005,9 @@ bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode,
return true;
}
-// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
-// at a PC-relative address, and changes instruction set from ARM to Thumb, or
-// from Thumb to ARM.
+// Branch with Link and Exchange Instruction Sets (immediate) calls a
+// subroutine at a PC-relative address, and changes instruction set from ARM to
+// Thumb, or from Thumb to ARM.
// BLX (immediate)
bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode,
const ARMEncoding encoding) {
@@ -2110,8 +2110,8 @@ bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode,
return true;
}
-// Branch with Link and Exchange (register) calls a subroutine at an address and
-// instruction set specified by a register.
+// Branch with Link and Exchange (register) calls a subroutine at an address
+// and instruction set specified by a register.
// BLX (register)
bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode,
const ARMEncoding encoding) {
@@ -2220,9 +2220,8 @@ bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode,
}
// Branch and Exchange Jazelle attempts to change to Jazelle state. If the
-// attempt fails, it branches to an
-// address and instruction set specified by a register as though it were a BX
-// instruction.
+// attempt fails, it branches to an address and instruction set specified by a
+// register as though it were a BX instruction.
//
// TODO: Emulate Jazelle architecture?
// We currently assume that switching to Jazelle state fails, thus
@@ -2561,8 +2560,8 @@ bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode,
return true;
}
-// Vector Push stores multiple extension registers to the stack.
-// It also updates SP to point to the start of the stored data.
+// Vector Push stores multiple extension registers to the stack. It also
+// updates SP to point to the start of the stored data.
bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -2577,7 +2576,8 @@ bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode,
MemA[address,4] = S[d+r]; address = address+4;
else
for r = 0 to regs-1
- // Store as two word-aligned words in the correct order for current endianness.
+ // Store as two word-aligned words in the correct order for
+ // current endianness.
MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
address = address+8;
@@ -2653,8 +2653,8 @@ bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode,
return true;
}
-// Vector Pop loads multiple extension registers from the stack.
-// It also updates SP to point just above the loaded data.
+// Vector Pop loads multiple extension registers from the stack. It also
+// updates SP to point just above the loaded data.
bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -2670,7 +2670,8 @@ bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode,
else
for r = 0 to regs-1
word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
- // Combine the word-aligned words in the correct order for current endianness.
+ // Combine the word-aligned words in the correct order for
+ // current endianness.
D[d+r] = if BigEndian() then word1:word2 else word2:word1;
}
#endif
@@ -2892,10 +2893,8 @@ bool EmulateInstructionARM::EmulateB(const uint32_t opcode,
}
// Compare and Branch on Nonzero and Compare and Branch on Zero compare the
-// value in a register with
-// zero and conditionally branch forward a constant value. They do not affect
-// the condition flags.
-// CBNZ, CBZ
+// value in a register with zero and conditionally branch forward a constant
+// value. They do not affect the condition flags. CBNZ, CBZ
bool EmulateInstructionARM::EmulateCB(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -2938,8 +2937,8 @@ bool EmulateInstructionARM::EmulateCB(const uint32_t opcode,
return true;
}
-// Table Branch Byte causes a PC-relative forward branch using a table of single
-// byte offsets.
+// Table Branch Byte causes a PC-relative forward branch using a table of
+// single byte offsets.
// A base register provides a pointer to the table, and a second register
// supplies an index into the table.
// The branch length is twice the value of the byte returned from the table.
@@ -2948,8 +2947,8 @@ bool EmulateInstructionARM::EmulateCB(const uint32_t opcode,
// single halfword offsets.
// A base register provides a pointer to the table, and a second register
// supplies an index into the table.
-// The branch length is twice the value of the halfword returned from the table.
-// TBB, TBH
+// The branch length is twice the value of the halfword returned from the
+// table. TBB, TBH
bool EmulateInstructionARM::EmulateTB(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -2984,9 +2983,8 @@ bool EmulateInstructionARM::EmulateTB(const uint32_t opcode,
return false;
}
- // Read the address of the table from the operand register Rn.
- // The PC can be used, in which case the table immediately follows this
- // instruction.
+ // Read the address of the table from the operand register Rn. The PC can
+ // be used, in which case the table immediately follows this instruction.
uint32_t base = ReadCoreReg(Rn, &success);
if (!success)
return false;
@@ -3023,8 +3021,8 @@ bool EmulateInstructionARM::EmulateTB(const uint32_t opcode,
}
// This instruction adds an immediate value to a register value, and writes the
-// result to the destination register.
-// It can optionally update the condition flags based on the result.
+// result to the destination register. It can optionally update the condition
+// flags based on the result.
bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -3145,8 +3143,8 @@ bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode,
}
// This instruction adds an immediate value to a register value, and writes the
-// result to the destination
-// register. It can optionally update the condition flags based on the result.
+// result to the destination register. It can optionally update the condition
+// flags based on the result.
bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -3210,9 +3208,8 @@ bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode,
}
// This instruction adds a register value and an optionally-shifted register
-// value, and writes the result
-// to the destination register. It can optionally update the condition flags
-// based on the result.
+// value, and writes the result to the destination register. It can optionally
+// update the condition flags based on the result.
bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -3350,8 +3347,8 @@ bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode,
}
// Compare Negative (register) adds a register value and an optionally-shifted
-// register value.
-// It updates the condition flags based on the result, and discards the result.
+// register value. It updates the condition flags based on the result, and
+// discards the result.
bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -3419,8 +3416,8 @@ bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode,
return true;
}
-// Compare (immediate) subtracts an immediate value from a register value.
-// It updates the condition flags based on the result, and discards the result.
+// Compare (immediate) subtracts an immediate value from a register value. It
+// updates the condition flags based on the result, and discards the result.
bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -3473,8 +3470,8 @@ bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode,
}
// Compare (register) subtracts an optionally-shifted register value from a
-// register value.
-// It updates the condition flags based on the result, and discards the result.
+// register value. It updates the condition flags based on the result, and
+// discards the result.
bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -3552,10 +3549,9 @@ bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode,
}
// Arithmetic Shift Right (immediate) shifts a register value right by an
-// immediate number of bits,
-// shifting in copies of its sign bit, and writes the result to the destination
-// register. It can
-// optionally update the condition flags based on the result.
+// immediate number of bits, shifting in copies of its sign bit, and writes the
+// result to the destination register. It can optionally update the condition
+// flags based on the result.
bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -3577,13 +3573,11 @@ bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode,
return EmulateShiftImm(opcode, encoding, SRType_ASR);
}
-// Arithmetic Shift Right (register) shifts a register value right by a variable
-// number of bits,
-// shifting in copies of its sign bit, and writes the result to the destination
-// register.
-// The variable number of bits is read from the bottom byte of a register. It
-// can optionally update
-// the condition flags based on the result.
+// Arithmetic Shift Right (register) shifts a register value right by a
+// variable number of bits, shifting in copies of its sign bit, and writes the
+// result to the destination register. The variable number of bits is read from
+// the bottom byte of a register. It can optionally update the condition flags
+// based on the result.
bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -3604,10 +3598,8 @@ bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode,
}
// Logical Shift Left (immediate) shifts a register value left by an immediate
-// number of bits,
-// shifting in zeros, and writes the result to the destination register. It can
-// optionally
-// update the condition flags based on the result.
+// number of bits, shifting in zeros, and writes the result to the destination
+// register. It can optionally update the condition flags based on the result.
bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -3630,12 +3622,9 @@ bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode,
}
// Logical Shift Left (register) shifts a register value left by a variable
-// number of bits,
-// shifting in zeros, and writes the result to the destination register. The
-// variable number
-// of bits is read from the bottom byte of a register. It can optionally update
-// the condition
-// flags based on the result.
+// number of bits, shifting in zeros, and writes the result to the destination
+// register. The variable number of bits is read from the bottom byte of a
+// register. It can optionally update the condition flags based on the result.
bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -3655,11 +3644,10 @@ bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode,
return EmulateShiftReg(opcode, encoding, SRType_LSL);
}
-// Logical Shift Right (immediate) shifts a register value right by an immediate
-// number of bits,
-// shifting in zeros, and writes the result to the destination register. It can
-// optionally
-// update the condition flags based on the result.
+// Logical Shift Right (immediate) shifts a register value right by an
+// immediate number of bits, shifting in zeros, and writes the result to the
+// destination register. It can optionally update the condition flags based on
+// the result.
bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -3682,12 +3670,9 @@ bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode,
}
// Logical Shift Right (register) shifts a register value right by a variable
-// number of bits,
-// shifting in zeros, and writes the result to the destination register. The
-// variable number
-// of bits is read from the bottom byte of a register. It can optionally update
-// the condition
-// flags based on the result.
+// number of bits, shifting in zeros, and writes the result to the destination
+// register. The variable number of bits is read from the bottom byte of a
+// register. It can optionally update the condition flags based on the result.
bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -3708,10 +3693,9 @@ bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode,
}
// Rotate Right (immediate) provides the value of the contents of a register
-// rotated by a constant value.
-// The bits that are rotated off the right end are inserted into the vacated bit
-// positions on the left.
-// It can optionally update the condition flags based on the result.
+// rotated by a constant value. The bits that are rotated off the right end are
+// inserted into the vacated bit positions on the left. It can optionally
+// update the condition flags based on the result.
bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -3734,12 +3718,10 @@ bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode,
}
// Rotate Right (register) provides the value of the contents of a register
-// rotated by a variable number of bits.
-// The bits that are rotated off the right end are inserted into the vacated bit
-// positions on the left.
-// The variable number of bits is read from the bottom byte of a register. It
-// can optionally update the condition
-// flags based on the result.
+// rotated by a variable number of bits. The bits that are rotated off the
+// right end are inserted into the vacated bit positions on the left. The
+// variable number of bits is read from the bottom byte of a register. It can
+// optionally update the condition flags based on the result.
bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -3760,8 +3742,7 @@ bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode,
}
// Rotate Right with Extend provides the value of the contents of a register
-// shifted right by one place,
-// with the carry flag shifted into bit [31].
+// shifted right by one place, with the carry flag shifted into bit [31].
//
// RRX can optionally update the condition flags based on the result.
// In that case, bit [0] is shifted into the carry flag.
@@ -3808,10 +3789,9 @@ bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode,
// A8.6.139 ROR (immediate) -- Encoding T1
ARMEncoding use_encoding = encoding;
if (shift_type == SRType_ROR && use_encoding == eEncodingT1) {
- // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding
- // to
- // have the same decoding of bit fields as the other Thumb2 shift
- // operations.
+ // Morph the T1 encoding from the ARM Architecture Manual into T2
+ // encoding to have the same decoding of bit fields as the other Thumb2
+ // shift operations.
use_encoding = eEncodingT2;
}
@@ -3950,8 +3930,7 @@ bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode,
// LDM loads multiple registers from consecutive memory locations, using an
// address from a base register. Optionally the address just above the highest
-// of those locations
-// can be written back to the base register.
+// of those locations can be written back to the base register.
bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -4093,8 +4072,8 @@ bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode,
// LDMDA loads multiple registers from consecutive memory locations using an
// address from a base register.
// The consecutive memory locations end at this address and the address just
-// below the lowest of those locations
-// can optionally be written back to the base register.
+// below the lowest of those locations can optionally be written back to the
+// base register.
bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -4210,8 +4189,8 @@ bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode,
// LDMDB loads multiple registers from consecutive memory locations using an
// address from a base register. The
// consecutive memory locations end just below this address, and the address of
-// the lowest of those locations can
-// be optionally written back to the base register.
+// the lowest of those locations can be optionally written back to the base
+// register.
bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -4349,8 +4328,8 @@ bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode,
// LDMIB loads multiple registers from consecutive memory locations using an
// address from a base register. The
// consecutive memory locations start just above this address, and thea ddress
-// of the last of those locations can
-// optinoally be written back to the base register.
+// of the last of those locations can optinoally be written back to the base
+// register.
bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -4461,8 +4440,7 @@ bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode,
}
// Load Register (immediate) calculates an address from a base register value
-// and
-// an immediate offset, loads a word from memory, and writes to a register.
+// and an immediate offset, loads a word from memory, and writes to a register.
// LDR (immediate, Thumb)
bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode,
const ARMEncoding encoding) {
@@ -4625,8 +4603,8 @@ bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode,
// STM (Store Multiple Increment After) stores multiple registers to consecutive
// memory locations using an address
// from a base register. The consecutive memory locations start at this
-// address, and the address just above the last
-// of those locations can optionally be written back to the base register.
+// address, and the address just above the last of those locations can
+// optionally be written back to the base register.
bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -4775,10 +4753,10 @@ bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode,
}
// STMDA (Store Multiple Decrement After) stores multiple registers to
-// consecutive memory locations using an address
-// from a base register. The consecutive memory locations end at this address,
-// and the address just below the lowest
-// of those locations can optionally be written back to the base register.
+// consecutive memory locations using an address from a base register. The
+// consecutive memory locations end at this address, and the address just below
+// the lowest of those locations can optionally be written back to the base
+// register.
bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -4897,10 +4875,10 @@ bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode,
}
// STMDB (Store Multiple Decrement Before) stores multiple registers to
-// consecutive memory locations using an address
-// from a base register. The consecutive memory locations end just below this
-// address, and the address of the first of
-// those locations can optionally be written back to the base register.
+// consecutive memory locations using an address from a base register. The
+// consecutive memory locations end just below this address, and the address of
+// the first of those locations can optionally be written back to the base
+// register.
bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -5046,10 +5024,10 @@ bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode,
}
// STMIB (Store Multiple Increment Before) stores multiple registers to
-// consecutive memory locations using an address
-// from a base register. The consecutive memory locations start just above this
-// address, and the address of the last
-// of those locations can optionally be written back to the base register.
+// consecutive memory locations using an address from a base register. The
+// consecutive memory locations start just above this address, and the address
+// of the last of those locations can optionally be written back to the base
+// register.
bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -5337,8 +5315,8 @@ bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode,
// STR (Store Register) calculates an address from a base register value and an
// offset register value, stores a
-// word from a register to memory. The offset register value can optionally be
-// shifted.
+// word from a register to memory. The offset register value can optionally
+// be shifted.
bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -5423,7 +5401,7 @@ bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode,
n = Bits32(opcode, 19, 16);
m = Bits32(opcode, 3, 0);
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
// (W == '1');
index = BitIsSet(opcode, 24);
add = BitIsSet(opcode, 23);
@@ -5664,8 +5642,8 @@ bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode,
// STRH (register) calculates an address from a base register value and an
// offset register value, and stores a
-// halfword from a register to memory. The offset register value can be shifted
-// left by 0, 1, 2, or 3 bits.
+// halfword from a register to memory. The offset register value can be
+// shifted left by 0, 1, 2, or 3 bits.
bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -5745,7 +5723,7 @@ bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode,
n = Bits32(opcode, 19, 16);
m = Bits32(opcode, 3, 0);
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
// (W == '1');
index = BitIsSet(opcode, 24);
add = BitIsSet(opcode, 23);
@@ -5842,10 +5820,8 @@ bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode,
}
// Add with Carry (immediate) adds an immediate value and the carry flag value
-// to a register value,
-// and writes the result to the destination register. It can optionally update
-// the condition flags
-// based on the result.
+// to a register value, and writes the result to the destination register. It
+// can optionally update the condition flags based on the result.
bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -5911,11 +5887,10 @@ bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode,
return true;
}
-// Add with Carry (register) adds a register value, the carry flag value, and an
-// optionally-shifted
-// register value, and writes the result to the destination register. It can
-// optionally update the
-// condition flags based on the result.
+// Add with Carry (register) adds a register value, the carry flag value, and
+// an optionally-shifted register value, and writes the result to the
+// destination register. It can optionally update the condition flags based on
+// the result.
bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -5999,9 +5974,8 @@ bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode,
return true;
}
-// This instruction adds an immediate value to the PC value to form a
-// PC-relative address,
-// and writes the result to the destination register.
+// This instruction adds an immediate value to the PC value to form a PC-
+// relative address, and writes the result to the destination register.
bool EmulateInstructionARM::EmulateADR(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -6063,9 +6037,8 @@ bool EmulateInstructionARM::EmulateADR(const uint32_t opcode,
}
// This instruction performs a bitwise AND of a register value and an immediate
-// value, and writes the result
-// to the destination register. It can optionally update the condition flags
-// based on the result.
+// value, and writes the result to the destination register. It can optionally
+// update the condition flags based on the result.
bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -6139,10 +6112,8 @@ bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode,
}
// This instruction performs a bitwise AND of a register value and an
-// optionally-shifted register value,
-// and writes the result to the destination register. It can optionally update
-// the condition flags
-// based on the result.
+// optionally-shifted register value, and writes the result to the destination
+// register. It can optionally update the condition flags based on the result.
bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -6230,10 +6201,9 @@ bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode,
}
// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and
-// the complement of an
-// immediate value, and writes the result to the destination register. It can
-// optionally update the
-// condition flags based on the result.
+// the complement of an immediate value, and writes the result to the
+// destination register. It can optionally update the condition flags based on
+// the result.
bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -6306,10 +6276,9 @@ bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode,
}
// Bitwise Bit Clear (register) performs a bitwise AND of a register value and
-// the complement of an
-// optionally-shifted register value, and writes the result to the destination
-// register.
-// It can optionally update the condition flags based on the result.
+// the complement of an optionally-shifted register value, and writes the
+// result to the destination register. It can optionally update the condition
+// flags based on the result.
bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -6439,7 +6408,7 @@ bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode,
n = Bits32(opcode, 19, 16);
imm32 = Bits32(opcode, 11, 0);
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
// (W == '1');
index = BitIsSet(opcode, 24);
add = BitIsSet(opcode, 23);
@@ -6624,7 +6593,7 @@ bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode,
n = Bits32(opcode, 19, 16);
m = Bits32(opcode, 3, 0);
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
// (W == '1');
index = BitIsSet(opcode, 24);
add = BitIsSet(opcode, 23);
@@ -6661,8 +6630,8 @@ bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode,
addr_t offset_addr;
addr_t address;
- // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an
- // application level alias for the CPSR".
+ // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is
+ // an application level alias for the CPSR".
addr_t offset =
Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success);
if (!success)
@@ -6968,9 +6937,8 @@ bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode,
}
// LDRB (register) calculates an address from a base register value and an
-// offset rigister value, loads a byte from
-// memory, zero-extends it to form a 32-bit word, and writes it to a register.
-// The offset register value can
+// offset rigister value, loads a byte from memory, zero-extends it to form a
+// 32-bit word, and writes it to a register. The offset register value can
// optionally be shifted.
bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode,
const ARMEncoding encoding) {
@@ -7049,7 +7017,7 @@ bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode,
n = Bits32(opcode, 19, 16);
m = Bits32(opcode, 3, 0);
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
// (W == '1');
index = BitIsSet(opcode, 24);
add = BitIsSet(opcode, 23);
@@ -7132,9 +7100,8 @@ bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode,
// LDRH (immediate, Thumb) calculates an address from a base register value and
// an immediate offset, loads a
-// halfword from memory, zero-extends it to form a 32-bit word, and writes it to
-// a register. It can use offset,
-// post-indexed, or pre-indexed addressing.
+// halfword from memory, zero-extends it to form a 32-bit word, and writes it
+// to a register. It can use offset, post-indexed, or pre-indexed addressing.
bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -7384,8 +7351,8 @@ bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode,
// LDRH (literal) calculates an address from a base register value and an offset
// register value, loads a halfword
// from memory, zero-extends it to form a 32-bit word, and writes it to a
-// register. The offset register value can
-// be shifted left by 0, 1, 2, or 3 bits.
+// register. The offset register value can be shifted left by 0, 1, 2, or 3
+// bits.
bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -7464,7 +7431,7 @@ bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode,
n = Bits32(opcode, 19, 16);
m = Bits32(opcode, 3, 0);
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
// (W == '1');
index = BitIsSet(opcode, 24);
add = BitIsSet(opcode, 23);
@@ -7561,8 +7528,7 @@ bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode,
// LDRSB (immediate) calculates an address from a base register value and an
// immediate offset, loads a byte from
// memory, sign-extends it to form a 32-bit word, and writes it to a register.
-// It can use offset, post-indexed,
-// or pre-indexed addressing.
+// It can use offset, post-indexed, or pre-indexed addressing.
bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -7643,7 +7609,7 @@ bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode,
uint32_t imm4L = Bits32(opcode, 3, 0);
imm32 = (imm4H << 4) | imm4L;
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
// (W == '1');
index = BitIsSet(opcode, 24);
add = BitIsSet(opcode, 23);
@@ -7799,8 +7765,7 @@ bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode,
// LDRSB (register) calculates an address from a base register value and an
// offset register value, loadsa byte from
// memory, sign-extends it to form a 32-bit word, and writes it to a register.
-// The offset register value can be
-// shifted left by 0, 1, 2, or 3 bits.
+// The offset register value can be shifted left by 0, 1, 2, or 3 bits.
bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -7873,7 +7838,7 @@ bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode,
n = Bits32(opcode, 19, 16);
m = Bits32(opcode, 3, 0);
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
// (W == '1');
index = BitIsSet(opcode, 24);
add = BitIsSet(opcode, 23);
@@ -7960,8 +7925,7 @@ bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode,
// LDRSH (immediate) calculates an address from a base register value and an
// immediate offset, loads a halfword from
// memory, sign-extends it to form a 32-bit word, and writes it to a register.
-// It can use offset, post-indexed, or
-// pre-indexed addressing.
+// It can use offset, post-indexed, or pre-indexed addressing.
bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -8043,7 +8007,7 @@ bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode,
uint32_t imm4L = Bits32(opcode, 3, 0);
imm32 = (imm4H << 4) | imm4L;
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
// (W == '1');
index = BitIsSet(opcode, 24);
add = BitIsSet(opcode, 23);
@@ -8220,8 +8184,8 @@ bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode,
// LDRSH (register) calculates an address from a base register value and an
// offset register value, loads a halfword
// from memory, sign-extends it to form a 32-bit word, and writes it to a
-// register. The offset register value can be
-// shifted left by 0, 1, 2, or 3 bits.
+// register. The offset register value can be shifted left by 0, 1, 2, or 3
+// bits.
bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -8301,7 +8265,7 @@ bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode,
n = Bits32(opcode, 19, 16);
m = Bits32(opcode, 3, 0);
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
// (W == '1');
index = BitIsSet(opcode, 24);
add = BitIsSet(opcode, 23);
@@ -8879,9 +8843,8 @@ bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode,
}
// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a
-// register value and an immediate value,
-// and writes the result to the destination register. It can optionally update
-// the condition flags based on
+// register value and an immediate value, and writes the result to the
+// destination register. It can optionally update the condition flags based on
// the result.
bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode,
const ARMEncoding encoding) {
@@ -8957,11 +8920,10 @@ bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode,
return true;
}
-// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register
-// value and an
-// optionally-shifted register value, and writes the result to the destination
-// register.
-// It can optionally update the condition flags based on the result.
+// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a
+// register value and an optionally-shifted register value, and writes the
+// result to the destination register. It can optionally update the condition
+// flags based on the result.
bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -9051,10 +9013,8 @@ bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode,
}
// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value
-// and an immediate value, and
-// writes the result to the destination register. It can optionally update the
-// condition flags based
-// on the result.
+// and an immediate value, and writes the result to the destination register.
+// It can optionally update the condition flags based on the result.
bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -9128,10 +9088,9 @@ bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode,
}
// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value
-// and an optionally-shifted register
-// value, and writes the result to the destination register. It can optionally
-// update the condition flags based
-// on the result.
+// and an optionally-shifted register value, and writes the result to the
+// destination register. It can optionally update the condition flags based on
+// the result.
bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -9219,9 +9178,8 @@ bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode,
}
// Reverse Subtract (immediate) subtracts a register value from an immediate
-// value, and writes the result to
-// the destination register. It can optionally update the condition flags based
-// on the result.
+// value, and writes the result to the destination register. It can optionally
+// update the condition flags based on the result.
bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -9294,10 +9252,9 @@ bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode,
return true;
}
-// Reverse Subtract (register) subtracts a register value from an
-// optionally-shifted register value, and writes the
-// result to the destination register. It can optionally update the condition
-// flags based on the result.
+// Reverse Subtract (register) subtracts a register value from an optionally-
+// shifted register value, and writes the result to the destination register.
+// It can optionally update the condition flags based on the result.
bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -9377,10 +9334,9 @@ bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode,
}
// Reverse Subtract with Carry (immediate) subtracts a register value and the
-// value of NOT (Carry flag) from
-// an immediate value, and writes the result to the destination register. It can
-// optionally update the condition
-// flags based on the result.
+// value of NOT (Carry flag) from an immediate value, and writes the result to
+// the destination register. It can optionally update the condition flags based
+// on the result.
bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -9440,9 +9396,8 @@ bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode,
}
// Reverse Subtract with Carry (register) subtracts a register value and the
-// value of NOT (Carry flag) from an
-// optionally-shifted register value, and writes the result to the destination
-// register. It can optionally update the
+// value of NOT (Carry flag) from an optionally-shifted register value, and
+// writes the result to the destination register. It can optionally update the
// condition flags based on the result.
bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode,
const ARMEncoding encoding) {
@@ -9512,7 +9467,8 @@ bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode,
return true;
}
-// Subtract with Carry (immediate) subtracts an immediate value and the value of
+// Subtract with Carry (immediate) subtracts an immediate value and the value
+// of
// NOT (Carry flag) from a register value, and writes the result to the
// destination register.
// It can optionally update the condition flags based on the result.
@@ -9582,8 +9538,8 @@ bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode,
return true;
}
-// Subtract with Carry (register) subtracts an optionally-shifted register value
-// and the value of
+// Subtract with Carry (register) subtracts an optionally-shifted register
+// value and the value of
// NOT (Carry flag) from a register value, and writes the result to the
// destination register.
// It can optionally update the condition flags based on the result.
@@ -9672,9 +9628,8 @@ bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode,
}
// This instruction subtracts an immediate value from a register value, and
-// writes the result
-// to the destination register. It can optionally update the condition flags
-// based on the result.
+// writes the result to the destination register. It can optionally update the
+// condition flags based on the result.
bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -9766,9 +9721,8 @@ bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode,
}
// This instruction subtracts an immediate value from a register value, and
-// writes the result
-// to the destination register. It can optionally update the condition flags
-// based on the result.
+// writes the result to the destination register. It can optionally update the
+// condition flags based on the result.
bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -9844,9 +9798,8 @@ bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode,
}
// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a
-// register value and an
-// immediate value. It updates the condition flags based on the result, and
-// discards the result.
+// register value and an immediate value. It updates the condition flags based
+// on the result, and discards the result.
bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -9904,10 +9857,8 @@ bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode,
}
// Test Equivalence (register) performs a bitwise exclusive OR operation on a
-// register value and an
-// optionally-shifted register value. It updates the condition flags based on
-// the result, and discards
-// the result.
+// register value and an optionally-shifted register value. It updates the
+// condition flags based on the result, and discards the result.
bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -9972,8 +9923,8 @@ bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode,
}
// Test (immediate) performs a bitwise AND operation on a register value and an
-// immediate value.
-// It updates the condition flags based on the result, and discards the result.
+// immediate value. It updates the condition flags based on the result, and
+// discards the result.
bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -10031,8 +9982,8 @@ bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode,
}
// Test (register) performs a bitwise AND operation on a register value and an
-// optionally-shifted register value.
-// It updates the condition flags based on the result, and discards the result.
+// optionally-shifted register value. It updates the condition flags based on
+// the result, and discards the result.
bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -10403,9 +10354,8 @@ bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode,
AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1);
- // if d == 15 then // Can only occur for ARM encoding
- // ALUWritePC(result); // setflags is always FALSE here
- // else
+ // if d == 15 then // Can only occur for ARM encoding ALUWritePC(result);
+ // // setflags is always FALSE here else
// R[d] = result;
// if setflags then
// APSR.N = result<31>;
@@ -10429,10 +10379,9 @@ bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode,
}
// A8.6.202 STREX
-// Store Register Exclusive calculates an address from a base register value and
-// an immediate offset, and stores a
-// word from a register to memory if the executing processor has exclusive
-// access to the memory addressed.
+// Store Register Exclusive calculates an address from a base register value
+// and an immediate offset, and stores a word from a register to memory if the
+// executing processor has exclusive access to the memory addressed.
bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -10457,7 +10406,8 @@ bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode,
switch (encoding) {
case eEncodingT1:
- // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00',
+ // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 =
+ // ZeroExtend(imm8:'00',
// 32);
d = Bits32(opcode, 11, 8);
t = Bits32(opcode, 15, 12);
@@ -10511,9 +10461,9 @@ bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode,
context.type = eContextRegisterStore;
context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, imm32);
- // if ExclusiveMonitorsPass(address,4) then
- // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the
- // sake of emulation, we will say this
+ // if ExclusiveMonitorsPass(address,4) then if (ExclusiveMonitorsPass
+ // (address, addr_byte_size)) -- For now, for the sake of emulation, we
+ // will say this
// always return
// true.
if (true) {
@@ -10742,9 +10692,9 @@ bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode,
// A8.6.66 LDRD (immediate)
// Load Register Dual (immediate) calculates an address from a base register
-// value and an immediate offset, loads two
-// words from memory, and writes them to two registers. It can use offset,
-// post-indexed, or pre-indexed addressing.
+// value and an immediate offset, loads two words from memory, and writes them
+// to two registers. It can use offset, post-indexed, or pre-indexed
+// addressing.
bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -10891,9 +10841,8 @@ bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode,
// A8.6.68 LDRD (register)
// Load Register Dual (register) calculates an address from a base register
-// value and a register offset, loads two
-// words from memory, and writes them to two registers. It can use offset,
-// post-indexed or pre-indexed addressing.
+// value and a register offset, loads two words from memory, and writes them to
+// two registers. It can use offset, post-indexed or pre-indexed addressing.
bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -11021,9 +10970,8 @@ bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode,
// A8.6.200 STRD (immediate)
// Store Register Dual (immediate) calculates an address from a base register
-// value and an immediate offset, and
-// stores two words from two registers to memory. It can use offset,
-// post-indexed, or pre-indexed addressing.
+// value and an immediate offset, and stores two words from two registers to
+// memory. It can use offset, post-indexed, or pre-indexed addressing.
bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -11314,8 +11262,7 @@ bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode,
// A8.6.319 VLDM
// Vector Load Multiple loads multiple extension registers from consecutive
-// memory locations using an address from
-// an ARM core register.
+// memory locations using an address from an ARM core register.
bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -11328,7 +11275,8 @@ bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode,
S[d+r] = MemA[address,4]; address = address+4;
else
word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
- // Combine the word-aligned words in the correct order for current endianness.
+ // Combine the word-aligned words in the correct order for
+ // current endianness.
D[d+r] = if BigEndian() then word1:word2 else word2:word1;
#endif
@@ -11389,8 +11337,8 @@ bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode,
return false;
// // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
- // !), 101 (DB with !)
- // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d =
+ // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W
+ // == '1'); d =
// UInt(Vd:D); n = UInt(Rn);
single_regs = true;
add = BitIsSet(opcode, 23);
@@ -11519,7 +11467,8 @@ bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode,
if single_regs then
MemA[address,4] = S[d+r]; address = address+4;
else
- // Store as two word-aligned words in the correct order for current endianness.
+ // Store as two word-aligned words in the correct order for
+ // current endianness.
MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
address = address+8;
@@ -11582,8 +11531,8 @@ bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode,
return false;
// // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
- // !), 101 (DB with !)
- // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d =
+ // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W
+ // == '1'); d =
// UInt(Vd:D); n = UInt(Rn);
single_regs = true;
add = BitIsSet(opcode, 23);
@@ -11665,8 +11614,7 @@ bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode,
address = address + 4;
} else {
// // Store as two word-aligned words in the correct order for current
- // endianness.
- // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else
+ // endianness. MemA[address,4] = if BigEndian() then D[d+r]<63:32> else
// D[d+r]<31:0>;
// MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else
// D[d+r]<63:32>;
@@ -11712,8 +11660,7 @@ bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode,
// A8.6.320
// This instruction loads a single extension register from memory, using an
-// address from an ARM core register, with
-// an optional offset.
+// address from an ARM core register, with an optional offset.
bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode,
ARMEncoding encoding) {
#if 0
@@ -11725,7 +11672,8 @@ bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode,
S[d] = MemA[address,4];
else
word1 = MemA[address,4]; word2 = MemA[address+4,4];
- // Combine the word-aligned words in the correct order for current endianness.
+ // Combine the word-aligned words in the correct order for current
+ // endianness.
D[d] = if BigEndian() then word1:word2 else word2:word1;
#endif
@@ -11839,8 +11787,7 @@ bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode,
// A8.6.400 VSTR
// This instruction stores a signle extension register to memory, using an
-// address from an ARM core register, with an
-// optional offset.
+// address from an ARM core register, with an optional offset.
bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode,
ARMEncoding encoding) {
#if 0
@@ -11850,7 +11797,8 @@ bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode,
if single_reg then
MemA[address,4] = S[d];
else
- // Store as two word-aligned words in the correct order for current endianness.
+ // Store as two word-aligned words in the correct order for current
+ // endianness.
MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
#endif
@@ -11970,10 +11918,9 @@ bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode,
return true;
}
-// A8.6.307 VLDI1 (multiple single elements)
-// This instruction loads elements from memory into one, two, three or four
-// registers, without de-interleaving. Every
-// element of each register is loaded.
+// A8.6.307 VLDI1 (multiple single elements) This instruction loads elements
+// from memory into one, two, three or four registers, without de-interleaving.
+// Every element of each register is loaded.
bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode,
ARMEncoding encoding) {
#if 0
@@ -12291,8 +12238,7 @@ bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode,
if (index > 0)
mask = mask | Bits64(all_ones, (index * esize) - 1,
0); // add 1's to the right of where 'element' goes.
- // now mask should be 0's where element goes & 1's
- // everywhere else.
+ // now mask should be 0's where element goes & 1's everywhere else.
uint64_t masked_reg =
reg_data & mask; // Take original reg value & zero out 'element' bits
@@ -12307,10 +12253,9 @@ bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode,
return true;
}
-// A8.6.391 VST1 (multiple single elements)
-// Vector Store (multiple single elements) stores elements to memory from one,
-// two, three, or four registers, without
-// interleaving. Every element of each register is stored.
+// A8.6.391 VST1 (multiple single elements) Vector Store (multiple single
+// elements) stores elements to memory from one, two, three, or four registers,
+// without interleaving. Every element of each register is stored.
bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode,
ARMEncoding encoding) {
#if 0
@@ -12465,8 +12410,8 @@ bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode,
return true;
}
-// A8.6.392 VST1 (single element from one lane)
-// This instruction stores one element to memory from one element of a register.
+// A8.6.392 VST1 (single element from one lane) This instruction stores one
+// element to memory from one element of a register.
bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode,
ARMEncoding encoding) {
#if 0
@@ -12624,9 +12569,8 @@ bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode,
return true;
}
-// A8.6.309 VLD1 (single element to all lanes)
-// This instruction loads one element from memory into every element of one or
-// two vectors.
+// A8.6.309 VLD1 (single element to all lanes) This instruction loads one
+// element from memory into every element of one or two vectors.
bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -12754,11 +12698,10 @@ bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode,
return true;
}
-// B6.2.13 SUBS PC, LR and related instructions
-// The SUBS PC, LR, #<const? instruction provides an exception return without
-// the use of the stack. It subtracts the
-// immediate constant from the LR, branches to the resulting address, and also
-// copies the SPSR to the CPSR.
+// B6.2.13 SUBS PC, LR and related instructions The SUBS PC, LR, #<const?
+// instruction provides an exception return without the use of the stack. It
+// subtracts the immediate constant from the LR, branches to the resulting
+// address, and also copies the SPSR to the CPSR.
bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode,
const ARMEncoding encoding) {
#if 0
@@ -12797,9 +12740,9 @@ bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode,
switch (encoding) {
case eEncodingT1:
- // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
- // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode =
- // '0010'; // = SUB
+ // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE n = 14;
+ // imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010';
+ // // = SUB
n = 14;
imm32 = Bits32(opcode, 7, 0);
register_form = false;
@@ -12924,8 +12867,7 @@ bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode,
// CPSRWriteByInstr(SPSR[], '1111', TRUE);
// For now, in emulation mode, we don't have access to the SPSR, so we will
- // use the CPSR instead, and hope for
- // the best.
+ // use the CPSR instead, and hope for the best.
uint32_t spsr =
ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
if (!success)
@@ -13946,10 +13888,10 @@ bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode,
else {
AddressClass addr_class = inst_addr.GetAddressClass();
- if ((addr_class == eAddressClassCode) ||
- (addr_class == eAddressClassUnknown))
+ if ((addr_class == AddressClass::eCode) ||
+ (addr_class == AddressClass::eUnknown))
m_opcode_mode = eModeARM;
- else if (addr_class == eAddressClassCodeAlternateISA)
+ else if (addr_class == AddressClass::eCodeAlternateISA)
m_opcode_mode = eModeThumb;
else
return false;
@@ -13999,8 +13941,7 @@ bool EmulateInstructionARM::ReadInstruction() {
if (!m_ignore_conditions) {
// If we are not ignoreing the conditions then init the it session from
- // the current
- // value of cpsr.
+ // the current value of cpsr.
uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) |
Bits32(m_opcode_cpsr, 26, 25);
if (it != 0)
@@ -14018,10 +13959,9 @@ bool EmulateInstructionARM::ReadInstruction() {
uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; }
bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) {
- // If we are ignoring conditions, then always return true.
- // this allows us to iterate over disassembly code and still
- // emulate an instruction even if we don't have all the right
- // bits set in the CPSR register...
+ // If we are ignoring conditions, then always return true. this allows us to
+ // iterate over disassembly code and still emulate an instruction even if we
+ // don't have all the right bits set in the CPSR register...
if (m_ignore_conditions)
return true;
@@ -14225,8 +14165,8 @@ bool EmulateInstructionARM::BranchWritePC(const Context &context,
bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) {
addr_t target;
// If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
- // we want to record it and issue a WriteRegister callback so the clients
- // can track the mode changes accordingly.
+ // we want to record it and issue a WriteRegister callback so the clients can
+ // track the mode changes accordingly.
bool cpsr_changed = false;
if (BitIsSet(addr, 0)) {
@@ -14307,9 +14247,10 @@ bool EmulateInstructionARM::UnalignedSupport() {
return (ArchVersion() >= ARMv7);
}
-// The main addition and subtraction instructions can produce status information
-// about both unsigned carry and signed overflow conditions. This status
-// information can be used to synthesize multi-word additions and subtractions.
+// The main addition and subtraction instructions can produce status
+// information about both unsigned carry and signed overflow conditions. This
+// status information can be used to synthesize multi-word additions and
+// subtractions.
EmulateInstructionARM::AddWithCarryResult
EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) {
uint32_t result;
@@ -14364,9 +14305,8 @@ uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) {
uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success);
// When executing an ARM instruction , PC reads as the address of the current
- // instruction plus 8.
- // When executing a Thumb instruction , PC reads as the address of the current
- // instruction plus 4.
+ // instruction plus 8. When executing a Thumb instruction , PC reads as the
+ // address of the current instruction plus 4.
if (num == 15) {
if (CurrentInstrSet() == eModeARM)
val += 8;
@@ -14434,8 +14374,7 @@ bool EmulateInstructionARM::WriteCoreRegOptionalFlags(
// APSR.V = overflow
//
// Default arguments can be specified for carry and overflow parameters, which
-// means
-// not to update the respective flags.
+// means not to update the respective flags.
bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result,
const uint32_t carry,
const uint32_t overflow) {
@@ -14496,8 +14435,7 @@ bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) {
}
// Advance the ITSTATE bits to their values for the next instruction if we
- // haven't just executed
- // an IT instruction what initialized it.
+ // haven't just executed an IT instruction what initialized it.
if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() &&
(opcode_data == nullptr ||
opcode_data->callback != &EmulateInstructionARM::EmulateIT))
diff --git a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
index d882108c25f4..2f484ab5ea97 100644
--- a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
+++ b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
@@ -76,19 +76,6 @@ static inline bool IsZero(uint64_t x) { return x == 0; }
static inline uint64_t NOT(uint64_t x) { return ~x; }
-#if 0
-// LSL_C()
-// =======
-static inline uint64_t
-LSL_C (uint64_t x, integer shift, bool &carry_out)
-{
- assert (shift >= 0);
- uint64_t result = x << shift;
- carry_out = ((1ull << (64-1)) >> (shift - 1)) != 0;
- return result;
-}
-#endif
-
// LSL()
// =====
@@ -519,8 +506,8 @@ bool EmulateInstructionARM64::UsingAArch32() {
bool EmulateInstructionARM64::BranchTo(const Context &context, uint32_t N,
addr_t target) {
#if 0
- // Set program counter to a new address, with a branch reason hint
- // for possible use by hardware fetching the next instruction.
+ // Set program counter to a new address, with a branch reason hint for
+ // possible use by hardware fetching the next instruction.
BranchTo(bits(N) target, BranchType branch_type)
Hint_Branch(branch_type);
if N == 32 then
@@ -568,10 +555,9 @@ bool EmulateInstructionARM64::BranchTo(const Context &context, uint32_t N,
}
bool EmulateInstructionARM64::ConditionHolds(const uint32_t cond) {
- // If we are ignoring conditions, then always return true.
- // this allows us to iterate over disassembly code and still
- // emulate an instruction even if we don't have all the right
- // bits set in the CPSR register...
+ // If we are ignoring conditions, then always return true. this allows us to
+ // iterate over disassembly code and still emulate an instruction even if we
+ // don't have all the right bits set in the CPSR register...
if (m_ignore_conditions)
return true;
@@ -703,8 +689,8 @@ bool EmulateInstructionARM64::EmulateADDSUBImm(const uint32_t opcode) {
context.SetRegisterPlusOffset(reg_info_Rn, imm);
if (n == GetFramePointerRegisterNumber() && d == gpr_sp_arm64 && !setflags) {
- // 'mov sp, fp' - common epilogue instruction, CFA is now in terms
- // of the stack pointer, instead of frame pointer.
+ // 'mov sp, fp' - common epilogue instruction, CFA is now in terms of the
+ // stack pointer, instead of frame pointer.
context.type = EmulateInstruction::eContextRestoreStackPointer;
} else if ((n == gpr_sp_arm64 || n == GetFramePointerRegisterNumber()) &&
d == gpr_sp_arm64 && !setflags) {
diff --git a/source/Plugins/Instruction/CMakeLists.txt b/source/Plugins/Instruction/CMakeLists.txt
index 78f2f64cf1ab..89771e8f46d1 100644
--- a/source/Plugins/Instruction/CMakeLists.txt
+++ b/source/Plugins/Instruction/CMakeLists.txt
@@ -2,3 +2,4 @@ add_subdirectory(ARM)
add_subdirectory(ARM64)
add_subdirectory(MIPS)
add_subdirectory(MIPS64)
+add_subdirectory(PPC64)
diff --git a/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp b/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
index db3d8fc1b8ca..b65747e12890 100644
--- a/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
+++ b/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
@@ -1015,7 +1015,7 @@ bool EmulateInstructionMIPS::SetInstruction(const Opcode &insn_opcode,
m_use_alt_disaasm = false;
if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) {
- if (inst_addr.GetAddressClass() == eAddressClassCodeAlternateISA) {
+ if (inst_addr.GetAddressClass() == AddressClass::eCodeAlternateISA) {
Status error;
lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
@@ -1044,7 +1044,7 @@ bool EmulateInstructionMIPS::SetInstruction(const Opcode &insn_opcode,
return true;
} else {
/*
- * If the address class is not eAddressClassCodeAlternateISA then
+ * If the address class is not AddressClass::eCodeAlternateISA then
* the function is not microMIPS. In this case instruction size is
* always 4 bytes.
*/
@@ -1205,13 +1205,10 @@ bool EmulateInstructionMIPS::Emulate_ADDiu(llvm::MCInst &insn) {
dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
- // If immediate value is greater then 2^16 - 1 then clang generate
- // LUI, ADDIU, SUBU instructions in prolog.
- // Example
- // lui $1, 0x2
- // addiu $1, $1, -0x5920
- // subu $sp, $sp, $1
- // In this case, ADDIU dst and src will be same and not equal to sp
+ // If immediate value is greater then 2^16 - 1 then clang generate LUI,
+ // ADDIU, SUBU instructions in prolog. Example lui $1, 0x2 addiu $1, $1,
+ // -0x5920 subu $sp, $sp, $1 In this case, ADDIU dst and src will be same
+ // and not equal to sp
if (dst == src) {
Context context;
@@ -1545,8 +1542,8 @@ bool EmulateInstructionMIPS::Emulate_SWSP(llvm::MCInst &insn) {
address = address + imm5;
// We use bad_vaddr_context to store base address which is used by H/W
- // watchpoint
- // Set the bad_vaddr register with base address used in the instruction
+ // watchpoint Set the bad_vaddr register with base address used in the
+ // instruction
bad_vaddr_context.type = eContextInvalid;
WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
address);
@@ -1682,8 +1679,8 @@ bool EmulateInstructionMIPS::Emulate_LWSP(llvm::MCInst &insn) {
base_address = base_address + imm5;
// We use bad_vaddr_context to store base address which is used by H/W
- // watchpoint
- // Set the bad_vaddr register with base address used in the instruction
+ // watchpoint Set the bad_vaddr register with base address used in the
+ // instruction
bad_vaddr_context.type = eContextInvalid;
WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
base_address);
diff --git a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
index d298589afdd9..5af12ad141aa 100644
--- a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
+++ b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
@@ -1091,13 +1091,10 @@ bool EmulateInstructionMIPS64::Emulate_DADDiu(llvm::MCInst &insn) {
dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
- // If immediate is greater than 2^16 - 1 then clang generate
- // LUI, (D)ADDIU,(D)SUBU instructions in prolog.
- // Example
- // lui $1, 0x2
- // daddiu $1, $1, -0x5920
- // dsubu $sp, $sp, $1
- // In this case, (D)ADDIU dst and src will be same and not equal to sp
+ // If immediate is greater than 2^16 - 1 then clang generate LUI,
+ // (D)ADDIU,(D)SUBU instructions in prolog. Example lui $1, 0x2 daddiu $1,
+ // $1, -0x5920 dsubu $sp, $sp, $1 In this case, (D)ADDIU dst and src will be
+ // same and not equal to sp
if (dst == src) {
Context context;
diff --git a/source/Plugins/Instruction/PPC64/CMakeLists.txt b/source/Plugins/Instruction/PPC64/CMakeLists.txt
new file mode 100644
index 000000000000..0926433fc77c
--- /dev/null
+++ b/source/Plugins/Instruction/PPC64/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_lldb_library(lldbPluginInstructionPPC64 PLUGIN
+ EmulateInstructionPPC64.cpp
+
+ LINK_LIBS
+ lldbCore
+ lldbInterpreter
+ lldbSymbol
+ lldbPluginProcessUtility
+ LINK_COMPONENTS
+ Support
+ )
diff --git a/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp b/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp
new file mode 100644
index 000000000000..f3a9ca570a4a
--- /dev/null
+++ b/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp
@@ -0,0 +1,406 @@
+//===-- EmulateInstructionPPC64.cpp ------------------------------*- C++-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "EmulateInstructionPPC64.h"
+
+#include <stdlib.h>
+
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/ConstString.h"
+
+#include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h"
+
+#define DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
+#include "Plugins/Process/Utility/RegisterInfos_ppc64le.h"
+
+#include "Plugins/Process/Utility/InstructionUtils.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+EmulateInstructionPPC64::EmulateInstructionPPC64(const ArchSpec &arch)
+ : EmulateInstruction(arch) {}
+
+void EmulateInstructionPPC64::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+}
+
+void EmulateInstructionPPC64::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+ConstString EmulateInstructionPPC64::GetPluginNameStatic() {
+ ConstString g_plugin_name("lldb.emulate-instruction.ppc64");
+ return g_plugin_name;
+}
+
+ConstString EmulateInstructionPPC64::GetPluginName() {
+ static ConstString g_plugin_name("EmulateInstructionPPC64");
+ return g_plugin_name;
+}
+
+const char *EmulateInstructionPPC64::GetPluginDescriptionStatic() {
+ return "Emulate instructions for the PPC64 architecture.";
+}
+
+EmulateInstruction *
+EmulateInstructionPPC64::CreateInstance(const ArchSpec &arch,
+ InstructionType inst_type) {
+ if (EmulateInstructionPPC64::SupportsEmulatingInstructionsOfTypeStatic(
+ inst_type)) {
+ if (arch.GetTriple().getArch() == llvm::Triple::ppc64 ||
+ arch.GetTriple().getArch() == llvm::Triple::ppc64le) {
+ return new EmulateInstructionPPC64(arch);
+ }
+ }
+
+ return nullptr;
+}
+
+bool EmulateInstructionPPC64::SetTargetTriple(const ArchSpec &arch) {
+ if (arch.GetTriple().getArch() == llvm::Triple::ppc64)
+ return true;
+ else if (arch.GetTriple().getArch() == llvm::Triple::ppc64le)
+ return true;
+
+ return false;
+}
+
+static bool LLDBTableGetRegisterInfo(uint32_t reg_num, RegisterInfo &reg_info) {
+ if (reg_num >= llvm::array_lengthof(g_register_infos_ppc64le))
+ return false;
+ reg_info = g_register_infos_ppc64le[reg_num];
+ return true;
+}
+
+bool EmulateInstructionPPC64::GetRegisterInfo(RegisterKind reg_kind,
+ uint32_t reg_num,
+ RegisterInfo &reg_info) {
+ if (reg_kind == eRegisterKindGeneric) {
+ switch (reg_num) {
+ case LLDB_REGNUM_GENERIC_PC:
+ reg_kind = eRegisterKindLLDB;
+ reg_num = gpr_pc_ppc64le;
+ break;
+ case LLDB_REGNUM_GENERIC_SP:
+ reg_kind = eRegisterKindLLDB;
+ reg_num = gpr_r1_ppc64le;
+ break;
+ case LLDB_REGNUM_GENERIC_RA:
+ reg_kind = eRegisterKindLLDB;
+ reg_num = gpr_lr_ppc64le;
+ break;
+ case LLDB_REGNUM_GENERIC_FLAGS:
+ reg_kind = eRegisterKindLLDB;
+ reg_num = gpr_cr_ppc64le;
+ break;
+
+ default:
+ return false;
+ }
+ }
+
+ if (reg_kind == eRegisterKindLLDB)
+ return LLDBTableGetRegisterInfo(reg_num, reg_info);
+ return false;
+}
+
+bool EmulateInstructionPPC64::ReadInstruction() {
+ bool success = false;
+ m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
+ LLDB_INVALID_ADDRESS, &success);
+ if (success) {
+ Context ctx;
+ ctx.type = eContextReadOpcode;
+ ctx.SetNoArgs();
+ m_opcode.SetOpcode32(ReadMemoryUnsigned(ctx, m_addr, 4, 0, &success),
+ GetByteOrder());
+ }
+ if (!success)
+ m_addr = LLDB_INVALID_ADDRESS;
+ return success;
+}
+
+bool EmulateInstructionPPC64::CreateFunctionEntryUnwind(
+ UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindLLDB);
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+
+ // Our previous Call Frame Address is the stack pointer
+ row->GetCFAValue().SetIsRegisterPlusOffset(gpr_r1_ppc64le, 0);
+
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("EmulateInstructionPPC64");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetReturnAddressRegister(gpr_lr_ppc64le);
+ return true;
+}
+
+EmulateInstructionPPC64::Opcode *
+EmulateInstructionPPC64::GetOpcodeForInstruction(uint32_t opcode) {
+ static EmulateInstructionPPC64::Opcode g_opcodes[] = {
+ {0xfc0007ff, 0x7c0002a6, &EmulateInstructionPPC64::EmulateMFSPR,
+ "mfspr RT, SPR"},
+ {0xfc000003, 0xf8000000, &EmulateInstructionPPC64::EmulateSTD,
+ "std RS, DS(RA)"},
+ {0xfc000003, 0xf8000001, &EmulateInstructionPPC64::EmulateSTD,
+ "stdu RS, DS(RA)"},
+ {0xfc0007fe, 0x7c000378, &EmulateInstructionPPC64::EmulateOR,
+ "or RA, RS, RB"},
+ {0xfc000000, 0x38000000, &EmulateInstructionPPC64::EmulateADDI,
+ "addi RT, RA, SI"},
+ {0xfc000003, 0xe8000000, &EmulateInstructionPPC64::EmulateLD,
+ "ld RT, DS(RA)"}};
+ static const size_t k_num_ppc_opcodes = llvm::array_lengthof(g_opcodes);
+
+ for (size_t i = 0; i < k_num_ppc_opcodes; ++i) {
+ if ((g_opcodes[i].mask & opcode) == g_opcodes[i].value)
+ return &g_opcodes[i];
+ }
+ return nullptr;
+}
+
+bool EmulateInstructionPPC64::EvaluateInstruction(uint32_t evaluate_options) {
+ const uint32_t opcode = m_opcode.GetOpcode32();
+ // LLDB_LOG(log, "PPC64::EvaluateInstruction: opcode={0:X+8}", opcode);
+ Opcode *opcode_data = GetOpcodeForInstruction(opcode);
+ if (!opcode_data)
+ return false;
+
+ // LLDB_LOG(log, "PPC64::EvaluateInstruction: {0}", opcode_data->name);
+ const bool auto_advance_pc =
+ evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
+
+ bool success = false;
+
+ uint32_t orig_pc_value = 0;
+ if (auto_advance_pc) {
+ orig_pc_value =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_pc_ppc64le, 0, &success);
+ if (!success)
+ return false;
+ }
+
+ // Call the Emulate... function.
+ success = (this->*opcode_data->callback)(opcode);
+ if (!success)
+ return false;
+
+ if (auto_advance_pc) {
+ uint32_t new_pc_value =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_pc_ppc64le, 0, &success);
+ if (!success)
+ return false;
+
+ if (auto_advance_pc && (new_pc_value == orig_pc_value)) {
+ EmulateInstruction::Context context;
+ context.type = eContextAdvancePC;
+ context.SetNoArgs();
+ if (!WriteRegisterUnsigned(context, eRegisterKindLLDB, gpr_pc_ppc64le,
+ orig_pc_value + 4))
+ return false;
+ }
+ }
+ return true;
+}
+
+bool EmulateInstructionPPC64::EmulateMFSPR(uint32_t opcode) {
+ uint32_t rt = Bits32(opcode, 25, 21);
+ uint32_t spr = Bits32(opcode, 20, 11);
+
+ enum { SPR_LR = 0x100 };
+
+ // For now, we're only insterested in 'mfspr r0, lr'
+ if (rt != gpr_r0_ppc64le || spr != SPR_LR)
+ return false;
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+ LLDB_LOG(log, "EmulateMFSPR: {0:X+8}: mfspr r0, lr", m_addr);
+
+ bool success;
+ uint64_t lr =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_lr_ppc64le, 0, &success);
+ if (!success)
+ return false;
+ Context context;
+ context.type = eContextWriteRegisterRandomBits;
+ WriteRegisterUnsigned(context, eRegisterKindLLDB, gpr_r0_ppc64le, lr);
+ LLDB_LOG(log, "EmulateMFSPR: success!");
+ return true;
+}
+
+bool EmulateInstructionPPC64::EmulateLD(uint32_t opcode) {
+ uint32_t rt = Bits32(opcode, 25, 21);
+ uint32_t ra = Bits32(opcode, 20, 16);
+ uint32_t ds = Bits32(opcode, 15, 2);
+
+ int32_t ids = llvm::SignExtend32<16>(ds << 2);
+
+ // For now, tracking only loads from 0(r1) to r1 (0(r1) is the ABI defined
+ // location to save previous SP)
+ if (ra != gpr_r1_ppc64le || rt != gpr_r1_ppc64le || ids != 0)
+ return false;
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+ LLDB_LOG(log, "EmulateLD: {0:X+8}: ld r{1}, {2}(r{3})", m_addr, rt, ids, ra);
+
+ RegisterInfo r1_info;
+ if (!GetRegisterInfo(eRegisterKindLLDB, gpr_r1_ppc64le, r1_info))
+ return false;
+
+ // restore SP
+ Context ctx;
+ ctx.type = eContextRestoreStackPointer;
+ ctx.SetRegisterToRegisterPlusOffset(r1_info, r1_info, 0);
+
+ WriteRegisterUnsigned(ctx, eRegisterKindLLDB, gpr_r1_ppc64le, 0);
+ LLDB_LOG(log, "EmulateLD: success!");
+ return true;
+}
+
+bool EmulateInstructionPPC64::EmulateSTD(uint32_t opcode) {
+ uint32_t rs = Bits32(opcode, 25, 21);
+ uint32_t ra = Bits32(opcode, 20, 16);
+ uint32_t ds = Bits32(opcode, 15, 2);
+ uint32_t u = Bits32(opcode, 1, 0);
+
+ // For now, tracking only stores to r1
+ if (ra != gpr_r1_ppc64le)
+ return false;
+ // ... and only stores of SP, FP and LR (moved into r0 by a previous mfspr)
+ if (rs != gpr_r1_ppc64le && rs != gpr_r31_ppc64le && rs != gpr_r30_ppc64le &&
+ rs != gpr_r0_ppc64le)
+ return false;
+
+ bool success;
+ uint64_t rs_val = ReadRegisterUnsigned(eRegisterKindLLDB, rs, 0, &success);
+ if (!success)
+ return false;
+
+ int32_t ids = llvm::SignExtend32<16>(ds << 2);
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+ LLDB_LOG(log, "EmulateSTD: {0:X+8}: std{1} r{2}, {3}(r{4})", m_addr,
+ u ? "u" : "", rs, ids, ra);
+
+ // Make sure that r0 is really holding LR value (this won't catch unlikely
+ // cases, such as r0 being overwritten after mfspr)
+ uint32_t rs_num = rs;
+ if (rs == gpr_r0_ppc64le) {
+ uint64_t lr =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_lr_ppc64le, 0, &success);
+ if (!success || lr != rs_val)
+ return false;
+ rs_num = gpr_lr_ppc64le;
+ }
+
+ // set context
+ RegisterInfo rs_info;
+ if (!GetRegisterInfo(eRegisterKindLLDB, rs_num, rs_info))
+ return false;
+ RegisterInfo ra_info;
+ if (!GetRegisterInfo(eRegisterKindLLDB, ra, ra_info))
+ return false;
+
+ Context ctx;
+ ctx.type = eContextPushRegisterOnStack;
+ ctx.SetRegisterToRegisterPlusOffset(rs_info, ra_info, ids);
+
+ // store
+ uint64_t ra_val = ReadRegisterUnsigned(eRegisterKindLLDB, ra, 0, &success);
+ if (!success)
+ return false;
+
+ lldb::addr_t addr = ra_val + ids;
+ WriteMemory(ctx, addr, &rs_val, sizeof(rs_val));
+
+ // update RA?
+ if (u) {
+ Context ctx;
+ // NOTE Currently, RA will always be equal to SP(r1)
+ ctx.type = eContextAdjustStackPointer;
+ WriteRegisterUnsigned(ctx, eRegisterKindLLDB, ra, addr);
+ }
+
+ LLDB_LOG(log, "EmulateSTD: success!");
+ return true;
+}
+
+bool EmulateInstructionPPC64::EmulateOR(uint32_t opcode) {
+ uint32_t rs = Bits32(opcode, 25, 21);
+ uint32_t ra = Bits32(opcode, 20, 16);
+ uint32_t rb = Bits32(opcode, 15, 11);
+
+ // to be safe, process only the known 'mr r31/r30, r1' prologue instructions
+ if (m_fp != LLDB_INVALID_REGNUM || rs != rb ||
+ (ra != gpr_r30_ppc64le && ra != gpr_r31_ppc64le) || rb != gpr_r1_ppc64le)
+ return false;
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+ LLDB_LOG(log, "EmulateOR: {0:X+8}: mr r{1}, r{2}", m_addr, ra, rb);
+
+ // set context
+ RegisterInfo ra_info;
+ if (!GetRegisterInfo(eRegisterKindLLDB, ra, ra_info))
+ return false;
+
+ Context ctx;
+ ctx.type = eContextSetFramePointer;
+ ctx.SetRegister(ra_info);
+
+ // move
+ bool success;
+ uint64_t rb_val = ReadRegisterUnsigned(eRegisterKindLLDB, rb, 0, &success);
+ if (!success)
+ return false;
+ WriteRegisterUnsigned(ctx, eRegisterKindLLDB, ra, rb_val);
+ m_fp = ra;
+ LLDB_LOG(log, "EmulateOR: success!");
+ return true;
+}
+
+bool EmulateInstructionPPC64::EmulateADDI(uint32_t opcode) {
+ uint32_t rt = Bits32(opcode, 25, 21);
+ uint32_t ra = Bits32(opcode, 20, 16);
+ uint32_t si = Bits32(opcode, 15, 0);
+
+ // handle stack adjustments only
+ // (this is a typical epilogue operation, with ra == r1. If it's
+ // something else, then we won't know the correct value of ra)
+ if (rt != gpr_r1_ppc64le || ra != gpr_r1_ppc64le)
+ return false;
+
+ int32_t si_val = llvm::SignExtend32<16>(si);
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+ LLDB_LOG(log, "EmulateADDI: {0:X+8}: addi r1, r1, {1}", m_addr, si_val);
+
+ // set context
+ RegisterInfo r1_info;
+ if (!GetRegisterInfo(eRegisterKindLLDB, gpr_r1_ppc64le, r1_info))
+ return false;
+
+ Context ctx;
+ ctx.type = eContextRestoreStackPointer;
+ ctx.SetRegisterToRegisterPlusOffset(r1_info, r1_info, 0);
+
+ // adjust SP
+ bool success;
+ uint64_t r1 =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_r1_ppc64le, 0, &success);
+ if (!success)
+ return false;
+ WriteRegisterUnsigned(ctx, eRegisterKindLLDB, gpr_r1_ppc64le, r1 + si_val);
+ LLDB_LOG(log, "EmulateADDI: success!");
+ return true;
+}
diff --git a/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h b/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h
new file mode 100644
index 000000000000..be65de9a5063
--- /dev/null
+++ b/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h
@@ -0,0 +1,97 @@
+//===-- EmulateInstructionPPC64.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef EmulateInstructionPPC64_h_
+#define EmulateInstructionPPC64_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/EmulateInstruction.h"
+#include "lldb/Interpreter/OptionValue.h"
+#include "lldb/Utility/Log.h"
+
+namespace lldb_private {
+
+class EmulateInstructionPPC64 : public EmulateInstruction {
+public:
+ EmulateInstructionPPC64(const ArchSpec &arch);
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ static EmulateInstruction *CreateInstance(const ArchSpec &arch,
+ InstructionType inst_type);
+
+ static bool
+ SupportsEmulatingInstructionsOfTypeStatic(InstructionType inst_type) {
+ switch (inst_type) {
+ case eInstructionTypeAny:
+ case eInstructionTypePrologueEpilogue:
+ return true;
+
+ case eInstructionTypePCModifying:
+ case eInstructionTypeAll:
+ return false;
+ }
+ return false;
+ }
+
+ ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override { return 1; }
+
+ bool SetTargetTriple(const ArchSpec &arch) override;
+
+ bool SupportsEmulatingInstructionsOfType(InstructionType inst_type) override {
+ return SupportsEmulatingInstructionsOfTypeStatic(inst_type);
+ }
+
+ bool ReadInstruction() override;
+
+ bool EvaluateInstruction(uint32_t evaluate_options) override;
+
+ bool TestEmulation(Stream *out_stream, ArchSpec &arch,
+ OptionValueDictionary *test_data) override {
+ return false;
+ }
+
+ bool GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num,
+ RegisterInfo &reg_info) override;
+
+ bool CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) override;
+
+private:
+ struct Opcode {
+ uint32_t mask;
+ uint32_t value;
+ bool (EmulateInstructionPPC64::*callback)(uint32_t opcode);
+ const char *name;
+ };
+
+ uint32_t m_fp = LLDB_INVALID_REGNUM;
+
+ Opcode *GetOpcodeForInstruction(uint32_t opcode);
+
+ bool EmulateMFSPR(uint32_t opcode);
+ bool EmulateLD(uint32_t opcode);
+ bool EmulateSTD(uint32_t opcode);
+ bool EmulateOR(uint32_t opcode);
+ bool EmulateADDI(uint32_t opcode);
+};
+
+} // namespace lldb_private
+
+#endif // EmulateInstructionPPC64_h_
diff --git a/source/Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.cpp b/source/Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.cpp
index eb238419ab18..32da327ee465 100644
--- a/source/Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.cpp
+++ b/source/Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.cpp
@@ -267,8 +267,8 @@ MainThreadCheckerRuntime::GetBacktracesFromExtendedStopInfo(
new HistoryThread(*process_sp, tid, PCs, stop_id, stop_id_is_valid);
ThreadSP new_thread_sp(history_thread);
- // Save this in the Process' ExtendedThreadList so a strong pointer
- // retains the object
+ // Save this in the Process' ExtendedThreadList so a strong pointer retains
+ // the object
process_sp->GetExtendedThreadList().AddThread(new_thread_sp);
threads->AddThread(new_thread_sp);
diff --git a/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp b/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp
index cf9ba60c7b60..6ce50f5c6839 100644
--- a/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp
+++ b/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp
@@ -282,9 +282,8 @@ GetRenumberedThreadIds(ProcessSP process_sp, ValueObjectSP data,
} else {
// This isn't a live thread anymore. Ask process to assign a new
// Index ID (or return an old one if we've already seen this
- // thread_os_id).
- // It will also make sure that no new threads are assigned this Index
- // ID.
+ // thread_os_id). It will also make sure that no new threads are
+ // assigned this Index ID.
lldb_user_id = process_sp->AssignIndexIDToThread(thread_os_id);
}
@@ -574,7 +573,7 @@ static void GetSymbolDeclarationFromAddress(ProcessSP process_sp, addr_t addr,
return;
VariableList var_list;
- module->FindGlobalVariables(sym_name, nullptr, true, 1U, var_list);
+ module->FindGlobalVariables(sym_name, nullptr, 1U, var_list);
if (var_list.GetSize() < 1)
return;
diff --git a/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp b/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp
index 28c28e41ef44..1e9280c8c064 100644
--- a/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp
+++ b/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp
@@ -334,8 +334,8 @@ UndefinedBehaviorSanitizerRuntime::GetBacktracesFromExtendedStopInfo(
std::string stop_reason_description = GetStopReasonDescription(info);
new_thread_sp->SetName(stop_reason_description.c_str());
- // Save this in the Process' ExtendedThreadList so a strong pointer
- // retains the object
+ // Save this in the Process' ExtendedThreadList so a strong pointer retains
+ // the object
process_sp->GetExtendedThreadList().AddThread(new_thread_sp);
threads->AddThread(new_thread_sp);
diff --git a/source/Plugins/JITLoader/GDB/CMakeLists.txt b/source/Plugins/JITLoader/GDB/CMakeLists.txt
index 25e8d1ee231f..190599cbd588 100644
--- a/source/Plugins/JITLoader/GDB/CMakeLists.txt
+++ b/source/Plugins/JITLoader/GDB/CMakeLists.txt
@@ -1,5 +1,3 @@
-include_directories(.)
-
add_lldb_library(lldbPluginJITLoaderGDB PLUGIN
JITLoaderGDB.cpp
diff --git a/source/Plugins/Language/CPlusPlus/BlockPointer.cpp b/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
index 5e8f051dec98..82b7ac1675fa 100644
--- a/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
+++ b/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
@@ -147,9 +147,8 @@ public:
return child_sp;
}
- // return true if this object is now safe to use forever without
- // ever updating again; the typical (and tested) answer here is
- // 'false'
+ // return true if this object is now safe to use forever without ever
+ // updating again; the typical (and tested) answer here is 'false'
bool Update() override { return false; }
// maybe return false if the block pointer is, say, null
diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 51ed88065c84..2c63e6467d4c 100644
--- a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -120,10 +120,9 @@ static bool ReverseFindMatchingChars(const llvm::StringRef &s,
static bool IsTrivialBasename(const llvm::StringRef &basename) {
// Check that the basename matches with the following regular expression
- // "^~?([A-Za-z_][A-Za-z_0-9]*)$"
- // We are using a hand written implementation because it is significantly more
- // efficient then
- // using the general purpose regular expression library.
+ // "^~?([A-Za-z_][A-Za-z_0-9]*)$" We are using a hand written implementation
+ // because it is significantly more efficient then using the general purpose
+ // regular expression library.
size_t idx = 0;
if (basename.size() > 0 && basename[0] == '~')
idx = 1;
@@ -151,10 +150,9 @@ static bool IsTrivialBasename(const llvm::StringRef &basename) {
}
bool CPlusPlusLanguage::MethodName::TrySimplifiedParse() {
- // This method tries to parse simple method definitions
- // which are presumably most comman in user programs.
- // Definitions that can be parsed by this function don't have return types
- // and templates in the name.
+ // This method tries to parse simple method definitions which are presumably
+ // most comman in user programs. Definitions that can be parsed by this
+ // function don't have return types and templates in the name.
// A::B::C::fun(std::vector<T> &) const
size_t arg_start, arg_end;
llvm::StringRef full(m_full.GetCString());
@@ -251,13 +249,17 @@ std::string CPlusPlusLanguage::MethodName::GetScopeQualifiedName() {
}
bool CPlusPlusLanguage::IsCPPMangledName(const char *name) {
- // FIXME, we should really run through all the known C++ Language plugins and
- // ask each one if
- // this is a C++ mangled name, but we can put that off till there is actually
- // more than one
- // we care about.
-
- return (name != nullptr && name[0] == '_' && name[1] == 'Z');
+ // FIXME!! we should really run through all the known C++ Language plugins
+ // and ask each one if this is a C++ mangled name
+
+ if (name == nullptr)
+ return false;
+
+ // MSVC style mangling
+ if (name[0] == '?')
+ return true;
+
+ return (name[0] != '\0' && name[0] == '_' && name[1] == 'Z');
}
bool CPlusPlusLanguage::ExtractContextAndIdentifier(
@@ -307,13 +309,15 @@ static ConstString SubsPrimitiveParmItanium(llvm::StringRef mangled,
// FastDemangle will call our hook for each instance of a primitive type,
// allowing us to perform substitution
- const char *const demangled =
+ char *const demangled =
FastDemangle(mangled.str().c_str(), mangled.size(), swap_parms_hook);
if (log)
log->Printf("substituted mangling for %s:{%s} %s:{%s}\n",
mangled.str().c_str(), demangled, output_buf.c_str(),
FastDemangle(output_buf.c_str()));
+ // FastDemangle malloc'd this string.
+ free(demangled);
return output_buf == mangled ? ConstString() : ConstString(output_buf);
}
@@ -419,18 +423,20 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
SyntheticChildren::Flags stl_synth_flags;
stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
false);
+ SyntheticChildren::Flags stl_deref_flags = stl_synth_flags;
+ stl_deref_flags.SetFrontEndWantsDereference();
AddCXXSynthetic(
cpp_category_sp,
lldb_private::formatters::LibcxxBitsetSyntheticFrontEndCreator,
"libc++ std::bitset synthetic children",
- ConstString("^std::__(ndk)?1::bitset<.+>(( )?&)?$"), stl_synth_flags,
+ ConstString("^std::__(ndk)?1::bitset<.+>(( )?&)?$"), stl_deref_flags,
true);
AddCXXSynthetic(
cpp_category_sp,
lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator,
"libc++ std::vector synthetic children",
- ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"), stl_synth_flags,
+ ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"), stl_deref_flags,
true);
AddCXXSynthetic(
cpp_category_sp,
@@ -453,13 +459,13 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
cpp_category_sp,
lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
"libc++ std::set synthetic children",
- ConstString("^std::__(ndk)?1::set<.+> >(( )?&)?$"), stl_synth_flags,
+ ConstString("^std::__(ndk)?1::set<.+> >(( )?&)?$"), stl_deref_flags,
true);
AddCXXSynthetic(
cpp_category_sp,
lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
"libc++ std::multiset synthetic children",
- ConstString("^std::__(ndk)?1::multiset<.+> >(( )?&)?$"), stl_synth_flags,
+ ConstString("^std::__(ndk)?1::multiset<.+> >(( )?&)?$"), stl_deref_flags,
true);
AddCXXSynthetic(
cpp_category_sp,
diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp b/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp
index aebea6ae3569..b32fe9588965 100644
--- a/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp
+++ b/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp
@@ -25,8 +25,8 @@ Optional<ParsedFunction> CPlusPlusNameParser::ParseAsFunctionDefinition() {
m_next_token_index = 0;
Optional<ParsedFunction> result(None);
- // Try to parse the name as function without a return type specified
- // e.g. main(int, char*[])
+ // Try to parse the name as function without a return type specified e.g.
+ // main(int, char*[])
{
Bookmark start_position = SetBookmark();
result = ParseFunctionImpl(false);
@@ -34,8 +34,8 @@ Optional<ParsedFunction> CPlusPlusNameParser::ParseAsFunctionDefinition() {
return result;
}
- // Try to parse the name as function with function pointer return type
- // e.g. void (*get_func(const char*))()
+ // Try to parse the name as function with function pointer return type e.g.
+ // void (*get_func(const char*))()
result = ParseFuncPtr(true);
if (result)
return result;
@@ -183,13 +183,13 @@ bool CPlusPlusNameParser::ConsumeTemplateArgs() {
Advance();
// Consuming template arguments is a bit trickier than consuming function
- // arguments, because '<' '>' brackets are not always trivially balanced.
- // In some rare cases tokens '<' and '>' can appear inside template arguments
- // as arithmetic or shift operators not as template brackets.
- // Examples: std::enable_if<(10u)<(64), bool>
+ // arguments, because '<' '>' brackets are not always trivially balanced. In
+ // some rare cases tokens '<' and '>' can appear inside template arguments as
+ // arithmetic or shift operators not as template brackets. Examples:
+ // std::enable_if<(10u)<(64), bool>
// f<A<operator<(X,Y)::Subclass>>
- // Good thing that compiler makes sure that really ambiguous cases of
- // '>' usage should be enclosed within '()' brackets.
+ // Good thing that compiler makes sure that really ambiguous cases of '>'
+ // usage should be enclosed within '()' brackets.
int template_counter = 1;
bool can_open_template = false;
while (HasMoreTokens() && template_counter > 0) {
@@ -208,9 +208,9 @@ bool CPlusPlusNameParser::ConsumeTemplateArgs() {
case tok::less:
// '<' is an attempt to open a subteamplte
// check if parser is at the point where it's actually possible,
- // otherwise it's just a part of an expression like 'sizeof(T)<(10)'.
- // No need to do the same for '>' because compiler actually makes sure
- // that '>' always surrounded by brackets to avoid ambiguity.
+ // otherwise it's just a part of an expression like 'sizeof(T)<(10)'. No
+ // need to do the same for '>' because compiler actually makes sure that
+ // '>' always surrounded by brackets to avoid ambiguity.
if (can_open_template)
++template_counter;
can_open_template = false;
@@ -242,8 +242,7 @@ bool CPlusPlusNameParser::ConsumeTemplateArgs() {
}
}
- assert(template_counter >= 0);
- if (template_counter > 0) {
+ if (template_counter != 0) {
return false;
}
start_position.Remove();
@@ -389,10 +388,9 @@ void CPlusPlusNameParser::SkipFunctionQualifiers() {
bool CPlusPlusNameParser::ConsumeBuiltinType() {
bool result = false;
bool continue_parsing = true;
- // Built-in types can be made of a few keywords
- // like 'unsigned long long int'. This function
- // consumes all built-in type keywords without
- // checking if they make sense like 'unsigned char void'.
+ // Built-in types can be made of a few keywords like 'unsigned long long
+ // int'. This function consumes all built-in type keywords without checking
+ // if they make sense like 'unsigned char void'.
while (continue_parsing && HasMoreTokens()) {
switch (Peek().getKind()) {
case tok::kw_short:
diff --git a/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index f6d1f18cb596..95e02a473cd7 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -123,12 +123,11 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() {
static ConstString g___i_("__i_");
- // this must be a ValueObject* because it is a child of the ValueObject we are
- // producing children for
- // it if were a ValueObjectSP, we would end up with a loop (iterator ->
- // synthetic -> child -> parent == iterator)
- // and that would in turn leak memory by never allowing the ValueObjects to
- // die and free their memory
+ // this must be a ValueObject* because it is a child of the ValueObject we
+ // are producing children for it if were a ValueObjectSP, we would end up
+ // with a loop (iterator -> synthetic -> child -> parent == iterator) and
+ // that would in turn leak memory by never allowing the ValueObjects to die
+ // and free their memory
m_pair_ptr = valobj_sp
->GetValueForExpressionPath(
".__i_.__ptr_->__value_", nullptr, nullptr,
@@ -386,7 +385,8 @@ enum LibcxxStringLayoutMode {
};
// this function abstracts away the layout and mode details of a libc++ string
-// and returns the address of the data and the size ready for callers to consume
+// and returns the address of the data and the size ready for callers to
+// consume
static bool ExtractLibcxxStringInfo(ValueObject &valobj,
ValueObjectSP &location_sp,
uint64_t &size) {
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxList.cpp b/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
index 6407ae129ad7..6066f14b18cc 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
@@ -206,8 +206,7 @@ bool AbstractListFrontEnd::HasLoop(size_t count) {
if (m_loop_detected == 0) {
// This is the first time we are being run (after the last update). Set up
- // the loop
- // invariant for the first element.
+ // the loop invariant for the first element.
m_slow_runner = ListEntry(m_head).next();
m_fast_runner = m_slow_runner.next();
m_loop_detected = 1;
@@ -215,9 +214,8 @@ bool AbstractListFrontEnd::HasLoop(size_t count) {
// Loop invariant:
// Loop detection has been run over the first m_loop_detected elements. If
- // m_slow_runner ==
- // m_fast_runner then the loop has been detected after m_loop_detected
- // elements.
+ // m_slow_runner == m_fast_runner then the loop has been detected after
+ // m_loop_detected elements.
const size_t steps_to_run = std::min(count, m_count);
while (m_loop_detected < steps_to_run && m_slow_runner && m_fast_runner &&
m_slow_runner != m_fast_runner) {
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
index be96a6d95bcd..8f82bdcbfd59 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
@@ -382,8 +382,8 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex(
return lldb::ValueObjectSP();
}
} else {
- // because of the way our debug info is made, we need to read item 0 first
- // so that we can cache information used to generate other elements
+ // because of the way our debug info is made, we need to read item 0
+ // first so that we can cache information used to generate other elements
if (m_skip_size == UINT32_MAX)
GetChildAtIndex(0);
if (m_skip_size == UINT32_MAX) {
diff --git a/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp b/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
index b6d664df16ef..9d46e3e3ee58 100644
--- a/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
@@ -43,6 +43,8 @@ private:
ValueObjectSP m_ptr_obj;
ValueObjectSP m_obj_obj;
ValueObjectSP m_del_obj;
+
+ ValueObjectSP GetTuple();
};
} // end of anonymous namespace
@@ -53,17 +55,36 @@ LibStdcppUniquePtrSyntheticFrontEnd::LibStdcppUniquePtrSyntheticFrontEnd(
Update();
}
-bool LibStdcppUniquePtrSyntheticFrontEnd::Update() {
+ValueObjectSP LibStdcppUniquePtrSyntheticFrontEnd::GetTuple() {
ValueObjectSP valobj_backend_sp = m_backend.GetSP();
+
if (!valobj_backend_sp)
- return false;
+ return nullptr;
ValueObjectSP valobj_sp = valobj_backend_sp->GetNonSyntheticValue();
if (!valobj_sp)
- return false;
+ return nullptr;
- ValueObjectSP tuple_sp =
+ ValueObjectSP obj_child_sp =
valobj_sp->GetChildMemberWithName(ConstString("_M_t"), true);
+ if (!obj_child_sp)
+ return nullptr;
+
+ ValueObjectSP obj_subchild_sp =
+ obj_child_sp->GetChildMemberWithName(ConstString("_M_t"), true);
+
+ // if there is a _M_t subchild, the tuple is found in the obj_subchild_sp
+ // (for libstdc++ 6.0.23).
+ if (obj_subchild_sp) {
+ return obj_subchild_sp;
+ }
+
+ return obj_child_sp;
+}
+
+bool LibStdcppUniquePtrSyntheticFrontEnd::Update() {
+ ValueObjectSP tuple_sp = GetTuple();
+
if (!tuple_sp)
return false;
diff --git a/source/Plugins/Language/ObjC/Cocoa.cpp b/source/Plugins/Language/ObjC/Cocoa.cpp
index 8f4997533212..8f278fc2d513 100644
--- a/source/Plugins/Language/ObjC/Cocoa.cpp
+++ b/source/Plugins/Language/ObjC/Cocoa.cpp
@@ -67,12 +67,12 @@ bool lldb_private::formatters::NSBundleSummaryProvider(
if (!valobj_addr)
return false;
- const char *class_name = descriptor->GetClassName().GetCString();
+ llvm::StringRef class_name(descriptor->GetClassName().GetCString());
- if (!class_name || !*class_name)
+ if (class_name.empty())
return false;
- if (!strcmp(class_name, "NSBundle")) {
+ if (class_name == "NSBundle") {
uint64_t offset = 5 * ptr_size;
ValueObjectSP text(valobj.GetSyntheticChildAtOffset(
offset,
@@ -117,12 +117,12 @@ bool lldb_private::formatters::NSTimeZoneSummaryProvider(
if (!valobj_addr)
return false;
- const char *class_name = descriptor->GetClassName().GetCString();
+ llvm::StringRef class_name(descriptor->GetClassName().GetCString());
- if (!class_name || !*class_name)
+ if (class_name.empty())
return false;
- if (!strcmp(class_name, "__NSTimeZone")) {
+ if (class_name == "__NSTimeZone") {
uint64_t offset = ptr_size;
ValueObjectSP text(valobj.GetSyntheticChildAtOffset(
offset, valobj.GetCompilerType(), true));
@@ -164,12 +164,12 @@ bool lldb_private::formatters::NSNotificationSummaryProvider(
if (!valobj_addr)
return false;
- const char *class_name = descriptor->GetClassName().GetCString();
+ llvm::StringRef class_name(descriptor->GetClassName().GetCString());
- if (!class_name || !*class_name)
+ if (class_name.empty())
return false;
- if (!strcmp(class_name, "NSConcreteNotification")) {
+ if (class_name == "NSConcreteNotification") {
uint64_t offset = ptr_size;
ValueObjectSP text(valobj.GetSyntheticChildAtOffset(
offset, valobj.GetCompilerType(), true));
@@ -211,14 +211,14 @@ bool lldb_private::formatters::NSMachPortSummaryProvider(
if (!valobj_addr)
return false;
- const char *class_name = descriptor->GetClassName().GetCString();
+ llvm::StringRef class_name(descriptor->GetClassName().GetCString());
- if (!class_name || !*class_name)
+ if (class_name.empty())
return false;
uint64_t port_number = 0;
- if (!strcmp(class_name, "NSMachPort")) {
+ if (class_name == "NSMachPort") {
uint64_t offset = (ptr_size == 4 ? 12 : 20);
Status error;
port_number = process_sp->ReadUnsignedIntegerFromMemory(
@@ -259,16 +259,15 @@ bool lldb_private::formatters::NSIndexSetSummaryProvider(
if (!valobj_addr)
return false;
- const char *class_name = descriptor->GetClassName().GetCString();
+ llvm::StringRef class_name(descriptor->GetClassName().GetCString());
- if (!class_name || !*class_name)
+ if (class_name.empty())
return false;
uint64_t count = 0;
do {
- if (!strcmp(class_name, "NSIndexSet") ||
- !strcmp(class_name, "NSMutableIndexSet")) {
+ if (class_name == "NSIndexSet" || class_name == "NSMutableIndexSet") {
Status error;
uint32_t mode = process_sp->ReadUnsignedIntegerFromMemory(
valobj_addr + ptr_size, 4, 0, error);
@@ -451,15 +450,18 @@ bool lldb_private::formatters::NSNumberSummaryProvider(
if (!valobj_addr)
return false;
- const char *class_name = descriptor->GetClassName().GetCString();
+ llvm::StringRef class_name(descriptor->GetClassName().GetCString());
- if (!class_name || !*class_name)
+ if (class_name.empty())
return false;
- if (!strcmp(class_name, "__NSCFBoolean"))
+ if (class_name == "__NSCFBoolean")
return ObjCBooleanSummaryProvider(valobj, stream, options);
- if (!strcmp(class_name, "NSNumber") || !strcmp(class_name, "__NSCFNumber")) {
+ if (class_name == "NSDecimalNumber")
+ return NSDecimalNumberSummaryProvider(valobj, stream, options);
+
+ if (class_name == "NSNumber" || class_name == "__NSCFNumber") {
uint64_t value = 0;
uint64_t i_bits = 0;
if (descriptor->GetTaggedPointerInfo(&i_bits, &value)) {
@@ -626,6 +628,55 @@ bool lldb_private::formatters::NSNumberSummaryProvider(
return false;
}
+bool lldb_private::formatters::NSDecimalNumberSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ Status error;
+ int8_t exponent = process_sp->ReadUnsignedIntegerFromMemory(
+ valobj_addr + ptr_size, 1, 0, error);
+ if (error.Fail())
+ return false;
+
+ uint8_t length_and_negative = process_sp->ReadUnsignedIntegerFromMemory(
+ valobj_addr + ptr_size + 1, 1, 0, error);
+ if (error.Fail())
+ return false;
+
+ // Fifth bit marks negativity.
+ const bool is_negative = (length_and_negative >> 4) & 1;
+
+ // Zero length and negative means NaN.
+ uint8_t length = length_and_negative & 0xf;
+ const bool is_nan = is_negative && (length == 0);
+
+ if (is_nan) {
+ stream.Printf("NaN");
+ return true;
+ }
+
+ if (length == 0) {
+ stream.Printf("0");
+ return true;
+ }
+
+ uint64_t mantissa = process_sp->ReadUnsignedIntegerFromMemory(
+ valobj_addr + ptr_size + 4, 8, 0, error);
+ if (error.Fail())
+ return false;
+
+ if (is_negative)
+ stream.Printf("-");
+
+ stream.Printf("%" PRIu64 " x 10^%" PRIi8, mantissa, exponent);
+ return true;
+}
+
bool lldb_private::formatters::NSURLSummaryProvider(
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
ProcessSP process_sp = valobj.GetProcessSP();
@@ -766,9 +817,9 @@ bool lldb_private::formatters::NSDateSummaryProvider(
stream.Printf("0001-12-30 00:00:00 +0000");
return true;
}
- // this snippet of code assumes that time_t == seconds since Jan-1-1970
- // this is generally true and POSIXly happy, but might break if a library
- // vendor decides to get creative
+ // this snippet of code assumes that time_t == seconds since Jan-1-1970 this
+ // is generally true and POSIXly happy, but might break if a library vendor
+ // decides to get creative
time_t epoch = GetOSXEpoch();
epoch = epoch + (time_t)date_value;
tm *tm_date = gmtime(&epoch);
@@ -871,28 +922,34 @@ bool lldb_private::formatters::NSDataSummaryProvider(
uint64_t value = 0;
- const char *class_name = descriptor->GetClassName().GetCString();
+ llvm::StringRef class_name = descriptor->GetClassName().GetCString();
- if (!class_name || !*class_name)
+ if (class_name.empty())
return false;
- if (!strcmp(class_name, "NSConcreteData") ||
- !strcmp(class_name, "NSConcreteMutableData") ||
- !strcmp(class_name, "__NSCFData")) {
- uint32_t offset = (is_64bit ? 16 : 8);
+ bool isNSConcreteData = class_name == "NSConcreteData";
+ bool isNSConcreteMutableData = class_name == "NSConcreteMutableData";
+ bool isNSCFData = class_name == "__NSCFData";
+ if (isNSConcreteData || isNSConcreteMutableData || isNSCFData) {
+ uint32_t offset;
+ if (isNSConcreteData)
+ offset = is_64bit ? 8 : 4;
+ else
+ offset = is_64bit ? 16 : 8;
+
Status error;
value = process_sp->ReadUnsignedIntegerFromMemory(
valobj_addr + offset, is_64bit ? 8 : 4, 0, error);
if (error.Fail())
return false;
- } else if (!strcmp(class_name, "_NSInlineData")) {
+ } else if (class_name == "_NSInlineData") {
uint32_t offset = (is_64bit ? 8 : 4);
Status error;
value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + offset, 2,
0, error);
if (error.Fail())
return false;
- } else if (!strcmp(class_name, "_NSZeroData")) {
+ } else if (class_name == "_NSZeroData") {
value = 0;
} else
return false;
diff --git a/source/Plugins/Language/ObjC/Cocoa.h b/source/Plugins/Language/ObjC/Cocoa.h
index 10ff3bce3b98..0f2ca5496302 100644
--- a/source/Plugins/Language/ObjC/Cocoa.h
+++ b/source/Plugins/Language/ObjC/Cocoa.h
@@ -32,6 +32,9 @@ bool NSDataSummaryProvider(ValueObject &valobj, Stream &stream,
bool NSNumberSummaryProvider(ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options);
+bool NSDecimalNumberSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
bool NSNotificationSummaryProvider(ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options);
diff --git a/source/Plugins/Language/ObjC/NSDictionary.cpp b/source/Plugins/Language/ObjC/NSDictionary.cpp
index c564aa1a8571..5be051b46bd6 100644
--- a/source/Plugins/Language/ObjC/NSDictionary.cpp
+++ b/source/Plugins/Language/ObjC/NSDictionary.cpp
@@ -396,6 +396,8 @@ bool lldb_private::formatters::NSDictionarySummaryProvider(
static const ConstString g_DictionaryMLegacy("__NSDictionaryM_Legacy");
static const ConstString g_DictionaryMImmutable("__NSDictionaryM_Immutable");
static const ConstString g_Dictionary1("__NSSingleEntryDictionaryI");
+ static const ConstString g_Dictionary0("__NSDictionary0");
+ static const ConstString g_DictionaryCF("__NSCFDictionary");
if (class_name.IsEmpty())
return false;
@@ -407,7 +409,8 @@ bool lldb_private::formatters::NSDictionarySummaryProvider(
if (error.Fail())
return false;
value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
- } else if (class_name == g_DictionaryM || class_name == g_DictionaryMLegacy) {
+ } else if (class_name == g_DictionaryM || class_name == g_DictionaryMLegacy ||
+ class_name == g_DictionaryCF) {
AppleObjCRuntime *apple_runtime =
llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
Status error;
@@ -423,17 +426,9 @@ bool lldb_private::formatters::NSDictionarySummaryProvider(
return false;
} else if (class_name == g_Dictionary1) {
value = 1;
+ } else if (class_name == g_Dictionary0) {
+ value = 0;
}
- /*else if (!strcmp(class_name,"__NSCFDictionary"))
- {
- Status error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ?
- 20 : 12), 4, 0, error);
- if (error.Fail())
- return false;
- if (is_64bit)
- value &= ~0x0f1f000000000000UL;
- }*/
else {
auto &map(NSDictionary_Additionals::GetAdditionalSummaries());
for (auto &candidate : map) {
@@ -491,6 +486,7 @@ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator(
static const ConstString g_Dictionary1("__NSSingleEntryDictionaryI");
static const ConstString g_DictionaryImmutable("__NSDictionaryM_Immutable");
static const ConstString g_DictionaryMLegacy("__NSDictionaryM_Legacy");
+ static const ConstString g_Dictionary0("__NSDictionary0");
if (class_name.IsEmpty())
return nullptr;
@@ -673,11 +669,7 @@ lldb_private::formatters::NSDictionary1SyntheticFrontEnd::
size_t lldb_private::formatters::NSDictionary1SyntheticFrontEnd::
GetIndexOfChildWithName(const ConstString &name) {
static const ConstString g_zero("[0]");
-
- if (name == g_zero)
- return 0;
-
- return UINT32_MAX;
+ return name == g_zero ? 0 : UINT32_MAX;
}
size_t lldb_private::formatters::NSDictionary1SyntheticFrontEnd::
diff --git a/source/Plugins/Language/ObjC/NSError.cpp b/source/Plugins/Language/ObjC/NSError.cpp
index 4365a12b54e1..77721e2db326 100644
--- a/source/Plugins/Language/ObjC/NSError.cpp
+++ b/source/Plugins/Language/ObjC/NSError.cpp
@@ -177,12 +177,11 @@ public:
private:
// the child here can be "real" (i.e. an actual child of the root) or
- // synthetized from raw memory
- // if the former, I need to store a plain pointer to it - or else a loop of
- // references will cause this entire hierarchy of values to leak
- // if the latter, then I need to store a SharedPointer to it - so that it only
- // goes away when everyone else in the cluster goes away
- // oh joy!
+ // synthetized from raw memory if the former, I need to store a plain pointer
+ // to it - or else a loop of references will cause this entire hierarchy of
+ // values to leak if the latter, then I need to store a SharedPointer to it -
+ // so that it only goes away when everyone else in the cluster goes away oh
+ // joy!
ValueObject *m_child_ptr;
ValueObjectSP m_child_sp;
};
diff --git a/source/Plugins/Language/ObjC/NSException.cpp b/source/Plugins/Language/ObjC/NSException.cpp
index 1da4f6de19a0..c6970efae4d3 100644
--- a/source/Plugins/Language/ObjC/NSException.cpp
+++ b/source/Plugins/Language/ObjC/NSException.cpp
@@ -171,12 +171,11 @@ public:
private:
// the child here can be "real" (i.e. an actual child of the root) or
- // synthetized from raw memory
- // if the former, I need to store a plain pointer to it - or else a loop of
- // references will cause this entire hierarchy of values to leak
- // if the latter, then I need to store a SharedPointer to it - so that it only
- // goes away when everyone else in the cluster goes away
- // oh joy!
+ // synthetized from raw memory if the former, I need to store a plain pointer
+ // to it - or else a loop of references will cause this entire hierarchy of
+ // values to leak if the latter, then I need to store a SharedPointer to it -
+ // so that it only goes away when everyone else in the cluster goes away oh
+ // joy!
ValueObject *m_child_ptr;
ValueObjectSP m_child_sp;
};
diff --git a/source/Plugins/Language/ObjC/NSSet.cpp b/source/Plugins/Language/ObjC/NSSet.cpp
index fa2483ecc094..2da4bc034f32 100644
--- a/source/Plugins/Language/ObjC/NSSet.cpp
+++ b/source/Plugins/Language/ObjC/NSSet.cpp
@@ -269,7 +269,8 @@ bool lldb_private::formatters::NSSetSummaryProvider(
if (!class_name || !*class_name)
return false;
- if (!strcmp(class_name, "__NSSetI")) {
+ if (!strcmp(class_name, "__NSSetI") ||
+ !strcmp(class_name, "__NSOrderedSetI")) {
Status error;
value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
ptr_size, 0, error);
@@ -289,32 +290,7 @@ bool lldb_private::formatters::NSSetSummaryProvider(
}
if (error.Fail())
return false;
- }
- /*else if (!strcmp(class_name,"__NSCFSet"))
- {
- Status error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ?
- 20 : 12), 4, 0, error);
- if (error.Fail())
- return false;
- if (is_64bit)
- value &= ~0x1fff000000000000UL;
- }
- else if (!strcmp(class_name,"NSCountedSet"))
- {
- Status error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
- ptr_size, 0, error);
- if (error.Fail())
- return false;
- value = process_sp->ReadUnsignedIntegerFromMemory(value + (is_64bit ? 20 :
- 12), 4, 0, error);
- if (error.Fail())
- return false;
- if (is_64bit)
- value &= ~0x1fff000000000000UL;
- }*/
- else {
+ } else {
auto &map(NSSet_Additionals::GetAdditionalSummaries());
auto iter = map.find(class_name_cs), end = map.end();
if (iter != end)
@@ -371,7 +347,8 @@ lldb_private::formatters::NSSetSyntheticFrontEndCreator(
if (!class_name || !*class_name)
return nullptr;
- if (!strcmp(class_name, "__NSSetI")) {
+ if (!strcmp(class_name, "__NSSetI") ||
+ !strcmp(class_name, "__NSOrderedSetI")) {
return (new NSSetISyntheticFrontEnd(valobj_sp));
} else if (!strcmp(class_name, "__NSSetM")) {
AppleObjCRuntime *apple_runtime =
diff --git a/source/Plugins/Language/ObjC/NSString.cpp b/source/Plugins/Language/ObjC/NSString.cpp
index 3b4edf68e063..0b12edb53d7a 100644
--- a/source/Plugins/Language/ObjC/NSString.cpp
+++ b/source/Plugins/Language/ObjC/NSString.cpp
@@ -256,8 +256,7 @@ bool lldb_private::formatters::NSStringSummaryProvider(
uint64_t location = valobj_addr + 2 * ptr_size;
if (!has_explicit_length) {
// in this kind of string, the byte before the string content is a length
- // byte
- // so let's try and use it to handle the embedded NUL case
+ // byte so let's try and use it to handle the embedded NUL case
Status error;
explicit_length =
process_sp->ReadUnsignedIntegerFromMemory(location, 1, 0, error);
@@ -368,9 +367,7 @@ bool lldb_private::formatters::NSTaggedString_SummaryProvider(
}
// this is a fairly ugly trick - pretend that the numeric value is actually a
- // char*
- // this works under a few assumptions:
- // little endian architecture
+ // char* this works under a few assumptions: little endian architecture
// sizeof(uint64_t) > g_MaxNonBitmaskedLen
if (len_bits <= g_MaxNonBitmaskedLen) {
stream.Printf("%s", prefix.c_str());
diff --git a/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/source/Plugins/Language/ObjC/ObjCLanguage.cpp
index ea2eec7b33b7..47874b3be8fd 100644
--- a/source/Plugins/Language/ObjC/ObjCLanguage.cpp
+++ b/source/Plugins/Language/ObjC/ObjCLanguage.cpp
@@ -90,9 +90,8 @@ bool ObjCLanguage::MethodName::SetName(llvm::StringRef name, bool strict) {
if (name.empty())
return IsValid(strict);
- // If "strict" is true. then the method must be specified with a
- // '+' or '-' at the beginning. If "strict" is false, then the '+'
- // or '-' can be omitted
+ // If "strict" is true. then the method must be specified with a '+' or '-'
+ // at the beginning. If "strict" is false, then the '+' or '-' can be omitted
bool valid_prefix = false;
if (name.size() > 1 && (name[0] == '+' || name[0] == '-')) {
@@ -108,7 +107,7 @@ bool ObjCLanguage::MethodName::SetName(llvm::StringRef name, bool strict) {
if (valid_prefix) {
int name_len = name.size();
- // Objective C methods must have at least:
+ // Objective-C methods must have at least:
// "-[" or "+[" prefix
// One character for a class name
// One character for the space between the class name
@@ -134,8 +133,8 @@ const ConstString &ObjCLanguage::MethodName::GetClassName() {
if (paren_pos) {
m_class.SetCStringWithLength(class_start, paren_pos - class_start);
} else {
- // No '(' was found in the full name, we can definitively say
- // that our category was valid (and empty).
+ // No '(' was found in the full name, we can definitively say that our
+ // category was valid (and empty).
m_category_is_valid = true;
const char *space_pos = strchr(full, ' ');
if (space_pos) {
@@ -164,8 +163,8 @@ const ConstString &ObjCLanguage::MethodName::GetClassNameWithCategory() {
// contain a '(', then we can also fill in the m_class
if (!m_class && strchr(m_class_category.GetCString(), '(') == nullptr) {
m_class = m_class_category;
- // No '(' was found in the full name, we can definitively say
- // that our category was valid (and empty).
+ // No '(' was found in the full name, we can definitively say that
+ // our category was valid (and empty).
m_category_is_valid = true;
}
}
@@ -764,6 +763,10 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) {
AddCXXSummary(
objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
"NSNumber summary provider", ConstString("NSCFNumber"), appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSNumberSummaryProvider,
+ "NSDecimalNumber summary provider",
+ ConstString("NSDecimalNumber"), appkit_flags);
AddCXXSummary(objc_category_sp,
lldb_private::formatters::NSURLSummaryProvider,
@@ -796,8 +799,8 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) {
objc_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider,
"NSTimeZone summary provider", ConstString("__NSTimeZone"), appkit_flags);
- // CFAbsoluteTime is actually a double rather than a pointer to an object
- // we do not care about the numeric value, since it is probably meaningless to
+ // CFAbsoluteTime is actually a double rather than a pointer to an object we
+ // do not care about the numeric value, since it is probably meaningless to
// users
appkit_flags.SetDontShowValue(true);
AddCXXSummary(objc_category_sp,
diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index e5a459dfe861..fc661bbbf2c9 100644
--- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -83,26 +83,30 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress(
// We are a C++ class, that's good. Get the class name and look it
// up:
const char *class_name = name + strlen(vtable_demangled_prefix);
+ // We know the class name is absolute, so tell FindTypes that by
+ // prefixing it with the root namespace:
+ std::string lookup_name("::");
+ lookup_name.append(class_name);
+
type_info.SetName(class_name);
const bool exact_match = true;
TypeList class_types;
uint32_t num_matches = 0;
- // First look in the module that the vtable symbol came from
- // and look for a single exact match.
+ // First look in the module that the vtable symbol came from and
+ // look for a single exact match.
llvm::DenseSet<SymbolFile *> searched_symbol_files;
if (sc.module_sp) {
num_matches = sc.module_sp->FindTypes(
- sc, ConstString(class_name), exact_match, 1,
+ sc, ConstString(lookup_name), exact_match, 1,
searched_symbol_files, class_types);
}
- // If we didn't find a symbol, then move on to the entire
- // module list in the target and get as many unique matches
- // as possible
+ // If we didn't find a symbol, then move on to the entire module
+ // list in the target and get as many unique matches as possible
if (num_matches == 0) {
num_matches = target.GetImages().FindTypes(
- sc, ConstString(class_name), exact_match, UINT32_MAX,
+ sc, ConstString(lookup_name), exact_match, UINT32_MAX,
searched_symbol_files, class_types);
}
@@ -187,15 +191,12 @@ bool ItaniumABILanguageRuntime::GetDynamicTypeAndAddress(
TypeAndOrName &class_type_or_name, Address &dynamic_address,
Value::ValueType &value_type) {
// For Itanium, if the type has a vtable pointer in the object, it will be at
- // offset 0
- // in the object. That will point to the "address point" within the vtable
- // (not the beginning of the
- // vtable.) We can then look up the symbol containing this "address point"
- // and that symbol's name
- // demangled will contain the full class name.
- // The second pointer above the "address point" is the "offset_to_top". We'll
- // use that to get the
- // start of the value object which holds the dynamic type.
+ // offset 0 in the object. That will point to the "address point" within the
+ // vtable (not the beginning of the vtable.) We can then look up the symbol
+ // containing this "address point" and that symbol's name demangled will
+ // contain the full class name. The second pointer above the "address point"
+ // is the "offset_to_top". We'll use that to get the start of the value
+ // object which holds the dynamic type.
//
class_type_or_name.Clear();
@@ -230,17 +231,15 @@ bool ItaniumABILanguageRuntime::GetDynamicTypeAndAddress(
if (class_type_or_name) {
TypeSP type_sp = class_type_or_name.GetTypeSP();
- // There can only be one type with a given name,
- // so we've just found duplicate definitions, and this
- // one will do as well as any other.
- // We don't consider something to have a dynamic type if
- // it is the same as the static type. So compare against
- // the value we were handed.
+ // There can only be one type with a given name, so we've just found
+ // duplicate definitions, and this one will do as well as any other. We
+ // don't consider something to have a dynamic type if it is the same as
+ // the static type. So compare against the value we were handed.
if (type_sp) {
if (ClangASTContext::AreTypesSame(in_value.GetCompilerType(),
type_sp->GetForwardCompilerType())) {
- // The dynamic type we found was the same type,
- // so we don't have a dynamic type here...
+ // The dynamic type we found was the same type, so we don't have a
+ // dynamic type here...
return false;
}
@@ -257,8 +256,8 @@ bool ItaniumABILanguageRuntime::GetDynamicTypeAndAddress(
if (offset_to_top == INT64_MIN)
return false;
- // So the dynamic type is a value that starts at offset_to_top
- // above the original address.
+ // So the dynamic type is a value that starts at offset_to_top above
+ // the original address.
lldb::addr_t dynamic_addr = original_ptr + offset_to_top;
if (!process->GetTarget().GetSectionLoadList().ResolveLoadAddress(
dynamic_addr, dynamic_address)) {
@@ -280,10 +279,9 @@ TypeAndOrName ItaniumABILanguageRuntime::FixUpDynamicType(
TypeAndOrName ret(type_and_or_name);
if (type_and_or_name.HasType()) {
// The type will always be the type of the dynamic object. If our parent's
- // type was a pointer,
- // then our type should be a pointer to the type of the dynamic object. If
- // a reference, then the original type
- // should be okay...
+ // type was a pointer, then our type should be a pointer to the type of the
+ // dynamic object. If a reference, then the original type should be
+ // okay...
CompilerType orig_type = type_and_or_name.GetCompilerType();
CompilerType corrected_type = orig_type;
if (static_type_flags.AllSet(eTypeIsPointer))
@@ -368,8 +366,8 @@ protected:
// the actual Mangled class should be strict about this, but on the
// command line if you're copying mangled names out of 'nm' on Darwin,
- // they will come out with an extra underscore - be willing to strip
- // this on behalf of the user. This is the moral equivalent of the -_/-n
+ // they will come out with an extra underscore - be willing to strip this
+ // on behalf of the user. This is the moral equivalent of the -_/-n
// options to c++filt
auto name = entry.ref;
if (name.startswith("__Z"))
@@ -448,13 +446,12 @@ BreakpointResolverSP ItaniumABILanguageRuntime::CreateExceptionResolver(
BreakpointResolverSP ItaniumABILanguageRuntime::CreateExceptionResolver(
Breakpoint *bkpt, bool catch_bp, bool throw_bp, bool for_expressions) {
// One complication here is that most users DON'T want to stop at
- // __cxa_allocate_expression, but until we can do
- // anything better with predicting unwinding the expression parser does. So
- // we have two forms of the exception
- // breakpoints, one for expressions that leaves out __cxa_allocate_exception,
- // and one that includes it.
- // The SetExceptionBreakpoints does the latter, the CreateExceptionBreakpoint
- // in the runtime the former.
+ // __cxa_allocate_expression, but until we can do anything better with
+ // predicting unwinding the expression parser does. So we have two forms of
+ // the exception breakpoints, one for expressions that leaves out
+ // __cxa_allocate_exception, and one that includes it. The
+ // SetExceptionBreakpoints does the latter, the CreateExceptionBreakpoint in
+ // the runtime the former.
static const char *g_catch_name = "__cxa_begin_catch";
static const char *g_throw_name1 = "__cxa_throw";
static const char *g_throw_name2 = "__cxa_rethrow";
@@ -517,8 +514,7 @@ void ItaniumABILanguageRuntime::SetExceptionBreakpoints() {
const bool for_expressions = true;
// For the exception breakpoints set by the Expression parser, we'll be a
- // little more aggressive and
- // stop at exception allocation as well.
+ // little more aggressive and stop at exception allocation as well.
if (m_cxx_exception_bp_sp) {
m_cxx_exception_bp_sp->SetEnabled(true);
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
index ecb0b64f2346..edb29e735ca9 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
@@ -378,8 +378,7 @@ bool ClassDescriptorV2::Describe(
AppleObjCRuntime::ClassDescriptorSP metaclass(GetMetaclass());
// We don't care about the metaclass's superclass, or its class methods.
- // Its instance methods are
- // our class methods.
+ // Its instance methods are our class methods.
if (metaclass) {
metaclass->Describe(
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
index eacc98a07193..fef42c78b24f 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
@@ -54,23 +54,20 @@ bool AppleObjCRuntime::GetObjectDescription(Stream &str, ValueObject &valobj) {
CompilerType compiler_type(valobj.GetCompilerType());
bool is_signed;
// ObjC objects can only be pointers (or numbers that actually represents
- // pointers
- // but haven't been typecast, because reasons..)
+ // pointers but haven't been typecast, because reasons..)
if (!compiler_type.IsIntegerType(is_signed) && !compiler_type.IsPointerType())
return false;
- // Make the argument list: we pass one arg, the address of our pointer, to the
- // print function.
+ // Make the argument list: we pass one arg, the address of our pointer, to
+ // the print function.
Value val;
if (!valobj.ResolveValue(val.GetScalar()))
return false;
// Value Objects may not have a process in their ExecutionContextRef. But we
- // need to have one
- // in the ref we pass down to eventually call description. Get it from the
- // target if it isn't
- // present.
+ // need to have one in the ref we pass down to eventually call description.
+ // Get it from the target if it isn't present.
ExecutionContext exe_ctx;
if (valobj.GetProcessSP()) {
exe_ctx = ExecutionContext(valobj.GetExecutionContextRef());
@@ -257,10 +254,9 @@ AppleObjCRuntime::FixUpDynamicType(const TypeAndOrName &type_and_or_name,
TypeAndOrName ret(type_and_or_name);
if (type_and_or_name.HasType()) {
// The type will always be the type of the dynamic object. If our parent's
- // type was a pointer,
- // then our type should be a pointer to the type of the dynamic object. If
- // a reference, then the original type
- // should be okay...
+ // type was a pointer, then our type should be a pointer to the type of the
+ // dynamic object. If a reference, then the original type should be
+ // okay...
CompilerType orig_type = type_and_or_name.GetCompilerType();
CompilerType corrected_type = orig_type;
if (static_type_flags.AllSet(eTypeIsPointer))
@@ -297,16 +293,14 @@ bool AppleObjCRuntime::AppleIsModuleObjCLibrary(const ModuleSP &module_sp) {
uint32_t AppleObjCRuntime::GetFoundationVersion() {
if (!m_Foundation_major.hasValue()) {
const ModuleList &modules = m_process->GetTarget().GetImages();
- uint32_t major = UINT32_MAX;
for (uint32_t idx = 0; idx < modules.GetSize(); idx++) {
lldb::ModuleSP module_sp = modules.GetModuleAtIndex(idx);
if (!module_sp)
continue;
if (strcmp(module_sp->GetFileSpec().GetFilename().AsCString(""),
"Foundation") == 0) {
- module_sp->GetVersion(&major, 1);
- m_Foundation_major = major;
- return major;
+ m_Foundation_major = module_sp->GetVersion().getMajor();
+ return *m_Foundation_major;
}
}
return LLDB_INVALID_MODULE_VERSION;
@@ -325,8 +319,8 @@ bool AppleObjCRuntime::IsModuleObjCLibrary(const ModuleSP &module_sp) {
bool AppleObjCRuntime::ReadObjCLibrary(const ModuleSP &module_sp) {
// Maybe check here and if we have a handler already, and the UUID of this
- // module is the same as the one in the
- // current module, then we don't have to reread it?
+ // module is the same as the one in the current module, then we don't have to
+ // reread it?
m_objc_trampoline_handler_ap.reset(
new AppleObjCTrampolineHandler(m_process->shared_from_this(), module_sp));
if (m_objc_trampoline_handler_ap.get() != NULL) {
@@ -365,11 +359,9 @@ AppleObjCRuntime::GetObjCVersion(Process *process, ModuleSP &objc_module_sp) {
for (size_t i = 0; i < num_images; i++) {
ModuleSP module_sp = target_modules.GetModuleAtIndexUnlocked(i);
// One tricky bit here is that we might get called as part of the initial
- // module loading, but
- // before all the pre-run libraries get winnowed from the module list. So
- // there might actually
- // be an old and incorrect ObjC library sitting around in the list, and we
- // don't want to look at that.
+ // module loading, but before all the pre-run libraries get winnowed from
+ // the module list. So there might actually be an old and incorrect ObjC
+ // library sitting around in the list, and we don't want to look at that.
// That's why we call IsLoadedInTarget.
if (AppleIsModuleObjCLibrary(module_sp) &&
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
index 9cac499c0ff0..5001c0461b3b 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
@@ -42,8 +42,7 @@ AppleObjCRuntimeV1::AppleObjCRuntimeV1(Process *process)
m_isa_hash_table_ptr(LLDB_INVALID_ADDRESS) {}
// for V1 runtime we just try to return a class name as that is the minimum
-// level of support
-// required for the data formatters to work
+// level of support required for the data formatters to work
bool AppleObjCRuntimeV1::GetDynamicTypeAndAddress(
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name, Address &address,
@@ -85,7 +84,7 @@ AppleObjCRuntimeV1::CreateInstance(Process *process,
void AppleObjCRuntimeV1::Initialize() {
PluginManager::RegisterPlugin(
- GetPluginNameStatic(), "Apple Objective C Language Runtime - Version 1",
+ GetPluginNameStatic(), "Apple Objective-C Language Runtime - Version 1",
CreateInstance);
}
@@ -284,6 +283,10 @@ bool AppleObjCRuntimeV1::ClassDescriptorV1::Describe(
return false;
}
+lldb::addr_t AppleObjCRuntimeV1::GetTaggedPointerObfuscator() {
+ return 0;
+}
+
lldb::addr_t AppleObjCRuntimeV1::GetISAHashTablePointer() {
if (m_isa_hash_table_ptr == LLDB_INVALID_ADDRESS) {
ModuleSP objc_module_sp(GetObjCModule());
@@ -383,8 +386,8 @@ void AppleObjCRuntimeV1::UpdateISAToDescriptorMapIfNeeded() {
ObjCISA isa;
if (bucket_isa_count == 1) {
- // When we only have one entry in the bucket, the bucket data is
- // the "isa"
+ // When we only have one entry in the bucket, the bucket data
+ // is the "isa"
isa = bucket_data;
if (isa) {
if (!ISAIsCached(isa)) {
@@ -402,8 +405,7 @@ void AppleObjCRuntimeV1::UpdateISAToDescriptorMapIfNeeded() {
}
} else {
// When we have more than one entry in the bucket, the bucket
- // data is a pointer
- // to an array of "isa" values
+ // data is a pointer to an array of "isa" values
addr_t isa_addr = bucket_data;
for (uint32_t isa_idx = 0; isa_idx < bucket_isa_count;
++isa_idx, isa_addr += addr_size) {
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
index 3dddf1b094e1..52eec0f692fb 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
@@ -45,6 +45,8 @@ public:
}
}
+ lldb::addr_t GetTaggedPointerObfuscator();
+
class ClassDescriptorV1 : public ObjCLanguageRuntime::ClassDescriptor {
public:
ClassDescriptorV1(ValueObject &isa_pointer);
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index bdf79f7b82bd..d217ed3ff325 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -37,6 +37,7 @@
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionValueBoolean.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -76,8 +77,7 @@ static constexpr std::chrono::seconds g_utility_function_timeout(2);
static const char *g_get_dynamic_class_info_name =
"__lldb_apple_objc_v2_get_dynamic_class_info";
// Testing using the new C++11 raw string literals. If this breaks GCC then we
-// will
-// need to revert to the code above...
+// will need to revert to the code above...
static const char *g_get_dynamic_class_info_body = R"(
extern "C"
@@ -161,8 +161,7 @@ __lldb_apple_objc_v2_get_dynamic_class_info (void *gdb_objc_realized_classes_ptr
static const char *g_get_shared_cache_class_info_name =
"__lldb_apple_objc_v2_get_shared_cache_class_info";
// Testing using the new C++11 raw string literals. If this breaks GCC then we
-// will
-// need to revert to the code above...
+// will need to revert to the code above...
static const char *g_get_shared_cache_class_info_body = R"(
extern "C"
@@ -385,7 +384,9 @@ AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process,
m_get_class_info_args_mutex(), m_get_shared_cache_class_info_code(),
m_get_shared_cache_class_info_args(LLDB_INVALID_ADDRESS),
m_get_shared_cache_class_info_args_mutex(), m_decl_vendor_ap(),
- m_isa_hash_table_ptr(LLDB_INVALID_ADDRESS), m_hash_signature(),
+ m_tagged_pointer_obfuscator(LLDB_INVALID_ADDRESS),
+ m_isa_hash_table_ptr(LLDB_INVALID_ADDRESS),
+ m_hash_signature(),
m_has_object_getClass(false), m_loaded_objc_opt(false),
m_non_pointer_isa_cache_ap(
NonPointerISACache::CreateInstance(*this, objc_module_sp)),
@@ -406,10 +407,9 @@ bool AppleObjCRuntimeV2::GetDynamicTypeAndAddress(
assert(m_process != NULL);
// The Runtime is attached to a particular process, you shouldn't pass in a
- // value from another process.
- // Note, however, the process might be NULL (e.g. if the value was made with
- // SBTarget::EvaluateExpression...)
- // in which case it is sufficient if the target's match:
+ // value from another process. Note, however, the process might be NULL (e.g.
+ // if the value was made with SBTarget::EvaluateExpression...) in which case
+ // it is sufficient if the target's match:
Process *process = in_value.GetProcessSP().get();
if (process)
@@ -422,8 +422,8 @@ bool AppleObjCRuntimeV2::GetDynamicTypeAndAddress(
// Make sure we can have a dynamic value before starting...
if (CouldHaveDynamicValue(in_value)) {
- // First job, pull out the address at 0 offset from the object That will be
- // the ISA pointer.
+ // First job, pull out the address at 0 offset from the object That will
+ // be the ISA pointer.
ClassDescriptorSP objc_class_sp(GetNonKVOClassDescriptor(in_value));
if (objc_class_sp) {
const addr_t object_ptr = in_value.GetPointerValue();
@@ -682,7 +682,7 @@ protected:
if (!arg_str)
continue;
Status error;
- lldb::addr_t arg_addr = Args::StringToAddress(
+ lldb::addr_t arg_addr = OptionArgParser::ToAddress(
&exe_ctx, arg_str, LLDB_INVALID_ADDRESS, &error);
if (arg_addr == 0 || arg_addr == LLDB_INVALID_ADDRESS || error.Fail())
continue;
@@ -771,7 +771,7 @@ public:
void AppleObjCRuntimeV2::Initialize() {
PluginManager::RegisterPlugin(
- GetPluginNameStatic(), "Apple Objective C Language Runtime - Version 2",
+ GetPluginNameStatic(), "Apple Objective-C Language Runtime - Version 2",
CreateInstance,
[](CommandInterpreter &interpreter) -> lldb::CommandObjectSP {
return CommandObjectSP(new CommandObjectMultiwordObjC(interpreter));
@@ -870,8 +870,8 @@ size_t AppleObjCRuntimeV2::GetByteOffsetForIvar(CompilerType &parent_ast_type,
const char *class_name = parent_ast_type.GetConstTypeName().AsCString();
if (class_name && class_name[0] && ivar_name && ivar_name[0]) {
//----------------------------------------------------------------------
- // Make the objective C V2 mangled name for the ivar offset from the
- // class name and ivar name
+ // Make the objective C V2 mangled name for the ivar offset from the class
+ // name and ivar name
//----------------------------------------------------------------------
std::string buffer("OBJC_IVAR_$_");
buffer.append(class_name);
@@ -880,8 +880,8 @@ size_t AppleObjCRuntimeV2::GetByteOffsetForIvar(CompilerType &parent_ast_type,
ConstString ivar_const_str(buffer.c_str());
//----------------------------------------------------------------------
- // Try to get the ivar offset address from the symbol table first using
- // the name we created above
+ // Try to get the ivar offset address from the symbol table first using the
+ // name we created above
//----------------------------------------------------------------------
SymbolContextList sc_list;
Target &target = m_process->GetTarget();
@@ -914,11 +914,9 @@ size_t AppleObjCRuntimeV2::GetByteOffsetForIvar(CompilerType &parent_ast_type,
}
// tagged pointers are special not-a-real-pointer values that contain both type
-// and value information
-// this routine attempts to check with as little computational effort as
-// possible whether something
-// could possibly be a tagged pointer - false positives are possible but false
-// negatives shouldn't
+// and value information this routine attempts to check with as little
+// computational effort as possible whether something could possibly be a
+// tagged pointer - false positives are possible but false negatives shouldn't
bool AppleObjCRuntimeV2::IsTaggedPointer(addr_t ptr) {
if (!m_tagged_pointer_vendor_ap)
return false;
@@ -950,11 +948,11 @@ public:
Status err;
// This currently holds true for all platforms we support, but we might
- // need to change this to use get the actually byte size of "unsigned"
- // from the target AST...
+ // need to change this to use get the actually byte size of "unsigned" from
+ // the target AST...
const uint32_t unsigned_byte_size = sizeof(uint32_t);
- // Skip the prototype as we don't need it (const struct +NXMapTablePrototype
- // *prototype)
+ // Skip the prototype as we don't need it (const struct
+ // +NXMapTablePrototype *prototype)
bool success = true;
if (load_addr == LLDB_INVALID_ADDRESS)
@@ -988,8 +986,8 @@ public:
return success;
}
- // const_iterator mimics NXMapState and its code comes from NXInitMapState and
- // NXNextMapState.
+ // const_iterator mimics NXMapState and its code comes from NXInitMapState
+ // and NXNextMapState.
typedef std::pair<ConstString, ObjCLanguageRuntime::ObjCISA> element;
friend class const_iterator;
@@ -1132,8 +1130,8 @@ bool AppleObjCRuntimeV2::HashTableSignature::NeedsUpdate(
return false; // Failed to parse the header, no need to update anything
}
- // Check with out current signature and return true if the count,
- // number of buckets or the hash table address changes.
+ // Check with out current signature and return true if the count, number of
+ // buckets or the hash table address changes.
if (m_count == hash_table.GetCount() &&
m_num_buckets == hash_table.GetBucketCount() &&
m_buckets_ptr == hash_table.GetBucketDataPointer()) {
@@ -1167,9 +1165,9 @@ AppleObjCRuntimeV2::GetClassDescriptor(ValueObject &valobj) {
}
return nullptr;
}
- // if we get an invalid VO (which might still happen when playing around
- // with pointers returned by the expression parser, don't consider this
- // a valid ObjC object)
+ // if we get an invalid VO (which might still happen when playing around with
+ // pointers returned by the expression parser, don't consider this a valid
+ // ObjC object)
if (valobj.GetCompilerType().IsValid()) {
addr_t isa_pointer = valobj.GetPointerValue();
@@ -1200,6 +1198,38 @@ AppleObjCRuntimeV2::GetClassDescriptor(ValueObject &valobj) {
return objc_class_sp;
}
+lldb::addr_t AppleObjCRuntimeV2::GetTaggedPointerObfuscator() {
+ if (m_tagged_pointer_obfuscator != LLDB_INVALID_ADDRESS)
+ return m_tagged_pointer_obfuscator;
+
+
+ Process *process = GetProcess();
+ ModuleSP objc_module_sp(GetObjCModule());
+
+ if (!objc_module_sp)
+ return LLDB_INVALID_ADDRESS;
+
+ static ConstString g_gdb_objc_obfuscator("objc_debug_taggedpointer_obfuscator");
+
+ const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType(
+ g_gdb_objc_obfuscator, lldb::eSymbolTypeAny);
+ if (symbol) {
+ lldb::addr_t g_gdb_obj_obfuscator_ptr =
+ symbol->GetLoadAddress(&process->GetTarget());
+
+ if (g_gdb_obj_obfuscator_ptr != LLDB_INVALID_ADDRESS) {
+ Status error;
+ m_tagged_pointer_obfuscator = process->ReadPointerFromMemory(
+ g_gdb_obj_obfuscator_ptr, error);
+ }
+ }
+ // If we don't have a correct value at this point, there must be no obfuscation.
+ if (m_tagged_pointer_obfuscator == LLDB_INVALID_ADDRESS)
+ m_tagged_pointer_obfuscator = 0;
+
+ return m_tagged_pointer_obfuscator;
+}
+
lldb::addr_t AppleObjCRuntimeV2::GetISAHashTablePointer() {
if (m_isa_hash_table_ptr == LLDB_INVALID_ADDRESS) {
Process *process = GetProcess();
@@ -1359,8 +1389,8 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr;
arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size;
- // Only dump the runtime classes from the expression evaluation if the
- // log is verbose:
+ // Only dump the runtime classes from the expression evaluation if the log is
+ // verbose:
Log *type_log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES);
bool dump_log = type_log && type_log->GetVerbose();
@@ -1440,7 +1470,8 @@ uint32_t AppleObjCRuntimeV2::ParseClassInfoArray(const DataExtractor &data,
// uint32_t hash;
// } __attribute__((__packed__));
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES));
+ bool should_log = log && log->GetVerbose();
uint32_t num_parsed = 0;
@@ -1450,15 +1481,15 @@ uint32_t AppleObjCRuntimeV2::ParseClassInfoArray(const DataExtractor &data,
ObjCISA isa = data.GetPointer(&offset);
if (isa == 0) {
- if (log)
+ if (should_log)
log->Printf(
"AppleObjCRuntimeV2 found NULL isa, ignoring this class info");
continue;
}
- // Check if we already know about this ISA, if we do, the info will
- // never change, so we can just skip it.
+ // Check if we already know about this ISA, if we do, the info will never
+ // change, so we can just skip it.
if (ISAIsCached(isa)) {
- if (log)
+ if (should_log)
log->Printf("AppleObjCRuntimeV2 found cached isa=0x%" PRIx64
", ignoring this class info",
isa);
@@ -1469,14 +1500,14 @@ uint32_t AppleObjCRuntimeV2::ParseClassInfoArray(const DataExtractor &data,
ClassDescriptorSP descriptor_sp(new ClassDescriptorV2(*this, isa, NULL));
AddClass(isa, descriptor_sp, name_hash);
num_parsed++;
- if (log)
+ if (should_log)
log->Printf("AppleObjCRuntimeV2 added isa=0x%" PRIx64
", hash=0x%8.8x, name=%s",
isa, name_hash,
descriptor_sp->GetClassName().AsCString("<unknown>"));
}
}
- if (log)
+ if (should_log)
log->Printf("AppleObjCRuntimeV2 parsed %" PRIu32 " class infos",
num_parsed);
return num_parsed;
@@ -1607,8 +1638,8 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
arguments.GetValueAtIndex(0)->GetScalar() = objc_opt_ptr;
arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr;
arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size;
- // Only dump the runtime classes from the expression evaluation if the
- // log is verbose:
+ // Only dump the runtime classes from the expression evaluation if the log is
+ // verbose:
Log *type_log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES);
bool dump_log = type_log && type_log->GetVerbose();
@@ -1788,21 +1819,17 @@ void AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded() {
DescriptorMapUpdateResult dynamic_update_result =
UpdateISAToDescriptorMapDynamic(hash_table);
- // Now get the objc classes that are baked into the Objective C runtime
- // in the shared cache, but only once per process as this data never
- // changes
+ // Now get the objc classes that are baked into the Objective-C runtime in
+ // the shared cache, but only once per process as this data never changes
if (!m_loaded_objc_opt) {
// it is legitimately possible for the shared cache to be empty - in that
- // case, the dynamic hash table
- // will contain all the class information we need; the situation we're
- // trying to detect is one where
- // we aren't seeing class information from the runtime - in order to
- // detect that vs. just the shared cache
- // being empty or sparsely populated, we set an arbitrary (very low)
- // threshold for the number of classes
- // that we want to see in a "good" scenario - anything below that is
- // suspicious (Foundation alone has thousands
- // of classes)
+ // case, the dynamic hash table will contain all the class information we
+ // need; the situation we're trying to detect is one where we aren't
+ // seeing class information from the runtime - in order to detect that
+ // vs. just the shared cache being empty or sparsely populated, we set an
+ // arbitrary (very low) threshold for the number of classes that we want
+ // to see in a "good" scenario - anything below that is suspicious
+ // (Foundation alone has thousands of classes)
const uint32_t num_classes_to_warn_at = 500;
DescriptorMapUpdateResult shared_cache_update_result =
@@ -2089,8 +2116,8 @@ AppleObjCRuntimeV2::TaggedPointerVendorV2::CreateInstance(
if (error.Fail())
return new TaggedPointerVendorLegacy(runtime);
- // try to detect the "extended tagged pointer" variables - if any are missing,
- // use the non-extended vendor
+ // try to detect the "extended tagged pointer" variables - if any are
+ // missing, use the non-extended vendor
do {
auto objc_debug_taggedpointer_ext_mask = ExtractRuntimeGlobalSymbol(
process, ConstString("objc_debug_taggedpointer_ext_mask"),
@@ -2143,8 +2170,8 @@ AppleObjCRuntimeV2::TaggedPointerVendorV2::CreateInstance(
objc_debug_taggedpointer_classes, objc_debug_taggedpointer_ext_classes);
} while (false);
- // we might want to have some rules to outlaw these values (e.g if the table's
- // address is zero)
+ // we might want to have some rules to outlaw these values (e.g if the
+ // table's address is zero)
return new TaggedPointerVendorRuntimeAssisted(
runtime, objc_debug_taggedpointer_mask,
@@ -2217,7 +2244,9 @@ AppleObjCRuntimeV2::TaggedPointerVendorLegacy::GetClassDescriptor(
return ObjCLanguageRuntime::ClassDescriptorSP();
}
}
- return ClassDescriptorSP(new ClassDescriptorV2Tagged(name, ptr));
+
+ lldb::addr_t unobfuscated = ptr ^ m_runtime.GetTaggedPointerObfuscator();
+ return ClassDescriptorSP(new ClassDescriptorV2Tagged(name, unobfuscated));
}
AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::
@@ -2249,8 +2278,9 @@ AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::GetClassDescriptor(
lldb::addr_t ptr) {
ClassDescriptorSP actual_class_descriptor_sp;
uint64_t data_payload;
+ uint64_t unobfuscated = (ptr) ^ m_runtime.GetTaggedPointerObfuscator();
- if (!IsPossibleTaggedPointer(ptr))
+ if (!IsPossibleTaggedPointer(unobfuscated))
return ObjCLanguageRuntime::ClassDescriptorSP();
uintptr_t slot = (ptr >> m_objc_debug_taggedpointer_slot_shift) &
@@ -2276,7 +2306,7 @@ AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::GetClassDescriptor(
}
data_payload =
- (((uint64_t)ptr << m_objc_debug_taggedpointer_payload_lshift) >>
+ (((uint64_t)unobfuscated << m_objc_debug_taggedpointer_payload_lshift) >>
m_objc_debug_taggedpointer_payload_rshift);
return ClassDescriptorSP(
@@ -2333,11 +2363,12 @@ AppleObjCRuntimeV2::TaggedPointerVendorExtended::GetClassDescriptor(
lldb::addr_t ptr) {
ClassDescriptorSP actual_class_descriptor_sp;
uint64_t data_payload;
+ uint64_t unobfuscated = (ptr) ^ m_runtime.GetTaggedPointerObfuscator();
- if (!IsPossibleTaggedPointer(ptr))
+ if (!IsPossibleTaggedPointer(unobfuscated))
return ObjCLanguageRuntime::ClassDescriptorSP();
- if (!IsPossibleExtendedTaggedPointer(ptr))
+ if (!IsPossibleExtendedTaggedPointer(unobfuscated))
return this->TaggedPointerVendorRuntimeAssisted::GetClassDescriptor(ptr);
uintptr_t slot = (ptr >> m_objc_debug_taggedpointer_ext_slot_shift) &
@@ -2363,7 +2394,7 @@ AppleObjCRuntimeV2::TaggedPointerVendorExtended::GetClassDescriptor(
}
data_payload =
- (((uint64_t)ptr << m_objc_debug_taggedpointer_ext_payload_lshift) >>
+ (((uint64_t)unobfuscated << m_objc_debug_taggedpointer_ext_payload_lshift) >>
m_objc_debug_taggedpointer_ext_payload_rshift);
return ClassDescriptorSP(
@@ -2414,11 +2445,10 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA(
if ((isa & ~m_objc_debug_isa_class_mask) == 0)
return false;
- // If all of the indexed ISA variables are set, then its possible that
- // this ISA is indexed, and we should first try to get its value using
- // the index.
- // Note, we check these varaibles first as the ObjC runtime will set at
- // least one of their values to 0 if they aren't needed.
+ // If all of the indexed ISA variables are set, then its possible that this
+ // ISA is indexed, and we should first try to get its value using the index.
+ // Note, we check these varaibles first as the ObjC runtime will set at least
+ // one of their values to 0 if they aren't needed.
if (m_objc_debug_indexed_isa_magic_mask &&
m_objc_debug_indexed_isa_magic_value &&
m_objc_debug_indexed_isa_index_mask &&
@@ -2431,10 +2461,10 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA(
// Magic bits are correct, so try extract the index.
uintptr_t index = (isa & m_objc_debug_indexed_isa_index_mask) >>
m_objc_debug_indexed_isa_index_shift;
- // If the index is out of bounds of the length of the array then
- // check if the array has been updated. If that is the case then
- // we should try read the count again, and update the cache if the
- // count has been updated.
+ // If the index is out of bounds of the length of the array then check if
+ // the array has been updated. If that is the case then we should try
+ // read the count again, and update the cache if the count has been
+ // updated.
if (index > m_indexed_isa_cache.size()) {
if (log)
log->Printf("AOCRT::NPI (index = %" PRIu64
@@ -2459,9 +2489,9 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA(
(uint64_t)objc_indexed_classes_count);
if (objc_indexed_classes_count > m_indexed_isa_cache.size()) {
- // Read the class entries we don't have. We should just
- // read all of them instead of just the one we need as then
- // we can cache those we may need later.
+ // Read the class entries we don't have. We should just read all of
+ // them instead of just the one we need as then we can cache those we
+ // may need later.
auto num_new_classes =
objc_indexed_classes_count - m_indexed_isa_cache.size();
const uint32_t addr_size = process->GetAddressByteSize();
@@ -2504,8 +2534,8 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA(
return false;
}
- // Definately not an indexed ISA, so try to use a mask to extract
- // the pointer from the ISA.
+ // Definately not an indexed ISA, so try to use a mask to extract the pointer
+ // from the ISA.
if ((isa & m_objc_debug_isa_magic_mask) == m_objc_debug_isa_magic_value) {
ret_isa = isa & m_objc_debug_isa_class_mask;
return (ret_isa != 0); // this is a pointer so 0 is not a valid value
@@ -2533,14 +2563,14 @@ bool AppleObjCRuntimeV2::GetCFBooleanValuesIfNeeded() {
if (m_CFBoolean_values)
return true;
- static ConstString g_kCFBooleanFalse("kCFBooleanFalse");
- static ConstString g_kCFBooleanTrue("kCFBooleanTrue");
+ static ConstString g_kCFBooleanFalse("__kCFBooleanFalse");
+ static ConstString g_kCFBooleanTrue("__kCFBooleanTrue");
std::function<lldb::addr_t(ConstString)> get_symbol =
[this](ConstString sym) -> lldb::addr_t {
SymbolContextList sc_list;
if (GetProcess()->GetTarget().GetImages().FindSymbolsWithNameAndType(
- g_kCFBooleanFalse, lldb::eSymbolTypeData, sc_list) == 1) {
+ sym, lldb::eSymbolTypeData, sc_list) == 1) {
SymbolContext sc;
sc_list.GetContextAtIndex(0, sc);
if (sc.symbol)
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
index 89e81d5b181e..487b67ca6271 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
@@ -94,6 +94,8 @@ public:
return m_tagged_pointer_vendor_ap.get();
}
+ lldb::addr_t GetTaggedPointerObfuscator();
+
void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true,
lldb::addr_t &cf_false) override;
@@ -330,6 +332,7 @@ private:
std::mutex m_get_shared_cache_class_info_args_mutex;
std::unique_ptr<DeclVendor> m_decl_vendor_ap;
+ lldb::addr_t m_tagged_pointer_obfuscator;
lldb::addr_t m_isa_hash_table_ptr;
HashTableSignature m_hash_signature;
bool m_has_object_getClass;
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
index a6e9c0c16f16..c75fa71ba131 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
@@ -49,227 +49,237 @@ const char *AppleObjCTrampolineHandler::g_lookup_implementation_function_name =
const char *AppleObjCTrampolineHandler::
g_lookup_implementation_with_stret_function_code =
" \n\
-extern \"C\" \n\
-{ \n\
- extern void *class_getMethodImplementation(void *objc_class, void *sel); \n\
- extern void *class_getMethodImplementation_stret(void *objc_class, void *sel); \n\
- extern void * object_getClass (id object); \n\
- extern void * sel_getUid(char *name); \n\
- extern int printf(const char *format, ...); \n\
-} \n\
-extern \"C\" void * __lldb_objc_find_implementation_for_selector (void *object, \n\
- void *sel, \n\
- int is_stret, \n\
- int is_super, \n\
- int is_super2, \n\
- int is_fixup, \n\
- int is_fixed, \n\
- int debug) \n\
-{ \n\
- struct __lldb_imp_return_struct \n\
- { \n\
- void *class_addr; \n\
- void *sel_addr; \n\
- void *impl_addr; \n\
- }; \n\
- \n\
- struct __lldb_objc_class { \n\
- void *isa; \n\
- void *super_ptr; \n\
- }; \n\
- struct __lldb_objc_super { \n\
- void *reciever; \n\
- struct __lldb_objc_class *class_ptr; \n\
- }; \n\
- struct __lldb_msg_ref { \n\
- void *dont_know; \n\
- void *sel; \n\
- }; \n\
- \n\
- struct __lldb_imp_return_struct return_struct; \n\
- \n\
- if (debug) \n\
- printf (\"\\n*** Called with obj: 0x%p sel: 0x%p is_stret: %d is_super: %d, \" \n\
- \"is_super2: %d, is_fixup: %d, is_fixed: %d\\n\", \n\
- object, sel, is_stret, is_super, is_super2, is_fixup, is_fixed); \n\
- if (is_super) \n\
- { \n\
- if (is_super2) \n\
- { \n\
- return_struct.class_addr = ((__lldb_objc_super *) object)->class_ptr->super_ptr; \n\
- } \n\
- else \n\
- { \n\
- return_struct.class_addr = ((__lldb_objc_super *) object)->class_ptr; \n\
- } \n\
- } \n\
- else \n\
- { \n\
- // This code seems a little funny, but has its reasons... \n\
- // The call to [object class] is here because if this is a class, and has not been called into \n\
- // yet, we need to do something to force the class to initialize itself. \n\
- // Then the call to object_getClass will actually return the correct class, either the class \n\
- // if object is a class instance, or the meta-class if it is a class pointer. \n\
- void *class_ptr = (void *) [(id) object class]; \n\
- return_struct.class_addr = (id) object_getClass((id) object); \n\
- if (debug) \n\
- { \n\
- if (class_ptr == object) \n\
- { \n\
- printf (\"Found a class object, need to use the meta class %p -> %p\\n\", \n\
- class_ptr, return_struct.class_addr); \n\
- } \n\
- else \n\
- { \n\
- printf (\"[object class] returned: %p object_getClass: %p.\\n\", \n\
- class_ptr, return_struct.class_addr); \n\
- } \n\
- } \n\
- } \n\
- \n\
- if (is_fixup) \n\
- { \n\
- if (is_fixed) \n\
- { \n\
- return_struct.sel_addr = ((__lldb_msg_ref *) sel)->sel; \n\
- } \n\
- else \n\
- { \n\
- char *sel_name = (char *) ((__lldb_msg_ref *) sel)->sel; \n\
- return_struct.sel_addr = sel_getUid (sel_name); \n\
- if (debug) \n\
- printf (\"\\n*** Got fixed up selector: %p for name %s.\\n\", \n\
- return_struct.sel_addr, sel_name); \n\
- } \n\
- } \n\
- else \n\
- { \n\
- return_struct.sel_addr = sel; \n\
- } \n\
- \n\
- if (is_stret) \n\
- { \n\
- return_struct.impl_addr = class_getMethodImplementation_stret (return_struct.class_addr, \n\
- return_struct.sel_addr); \n\
- } \n\
- else \n\
- { \n\
- return_struct.impl_addr = class_getMethodImplementation (return_struct.class_addr, \n\
- return_struct.sel_addr); \n\
- } \n\
- if (debug) \n\
- printf (\"\\n*** Returning implementation: %p.\\n\", return_struct.impl_addr); \n\
- \n\
- return return_struct.impl_addr; \n\
-} \n\
+extern \"C\" \n\
+{ \n\
+ extern void *class_getMethodImplementation(void *objc_class, void *sel); \n\
+ extern void *class_getMethodImplementation_stret(void *objc_class, \n\
+ void *sel); \n\
+ extern void * object_getClass (id object); \n\
+ extern void * sel_getUid(char *name); \n\
+ extern int printf(const char *format, ...); \n\
+} \n\
+extern \"C\" void * __lldb_objc_find_implementation_for_selector ( \n\
+ void *object, \n\
+ void *sel, \n\
+ int is_stret, \n\
+ int is_super, \n\
+ int is_super2, \n\
+ int is_fixup, \n\
+ int is_fixed, \n\
+ int debug) \n\
+{ \n\
+ struct __lldb_imp_return_struct \n\
+ { \n\
+ void *class_addr; \n\
+ void *sel_addr; \n\
+ void *impl_addr; \n\
+ }; \n\
+ \n\
+ struct __lldb_objc_class { \n\
+ void *isa; \n\
+ void *super_ptr; \n\
+ }; \n\
+ struct __lldb_objc_super { \n\
+ void *reciever; \n\
+ struct __lldb_objc_class *class_ptr; \n\
+ }; \n\
+ struct __lldb_msg_ref { \n\
+ void *dont_know; \n\
+ void *sel; \n\
+ }; \n\
+ \n\
+ struct __lldb_imp_return_struct return_struct; \n\
+ \n\
+ if (debug) \n\
+ printf (\"\\n*** Called with obj: 0x%p sel: 0x%p is_stret: %d is_super: %d, \"\n\
+ \"is_super2: %d, is_fixup: %d, is_fixed: %d\\n\", \n\
+ object, sel, is_stret, is_super, is_super2, is_fixup, is_fixed);\n\
+ if (is_super) \n\
+ { \n\
+ if (is_super2) \n\
+ { \n\
+ return_struct.class_addr = ((__lldb_objc_super *) object)->class_ptr->super_ptr;\n\
+ } \n\
+ else \n\
+ { \n\
+ return_struct.class_addr = ((__lldb_objc_super *) object)->class_ptr;\n\
+ } \n\
+ } \n\
+ else \n\
+ { \n\
+ // This code seems a little funny, but has its reasons... \n\
+ \n\
+ // The call to [object class] is here because if this is a \n\
+ // class, and has not been called into yet, we need to do \n\
+ // something to force the class to initialize itself. \n\
+ // Then the call to object_getClass will actually return the \n\
+ // correct class, either the class if object is a class \n\
+ // instance, or the meta-class if it is a class pointer. \n\
+ void *class_ptr = (void *) [(id) object class]; \n\
+ return_struct.class_addr = (id) object_getClass((id) object); \n\
+ if (debug) \n\
+ { \n\
+ if (class_ptr == object) \n\
+ { \n\
+ printf (\"Found a class object, need to use the meta class %p -> %p\\n\",\n\
+ class_ptr, return_struct.class_addr); \n\
+ } \n\
+ else \n\
+ { \n\
+ printf (\"[object class] returned: %p object_getClass: %p.\\n\", \n\
+ class_ptr, return_struct.class_addr); \n\
+ } \n\
+ } \n\
+ } \n\
+ \n\
+ if (is_fixup) \n\
+ { \n\
+ if (is_fixed) \n\
+ { \n\
+ return_struct.sel_addr = ((__lldb_msg_ref *) sel)->sel; \n\
+ } \n\
+ else \n\
+ { \n\
+ char *sel_name = (char *) ((__lldb_msg_ref *) sel)->sel; \n\
+ return_struct.sel_addr = sel_getUid (sel_name); \n\
+ if (debug) \n\
+ printf (\"\\n*** Got fixed up selector: %p for name %s.\\n\",\n\
+ return_struct.sel_addr, sel_name); \n\
+ } \n\
+ } \n\
+ else \n\
+ { \n\
+ return_struct.sel_addr = sel; \n\
+ } \n\
+ \n\
+ if (is_stret) \n\
+ { \n\
+ return_struct.impl_addr = \n\
+ class_getMethodImplementation_stret (return_struct.class_addr, \n\
+ return_struct.sel_addr); \n\
+ } \n\
+ else \n\
+ { \n\
+ return_struct.impl_addr = \n\
+ class_getMethodImplementation (return_struct.class_addr, \n\
+ return_struct.sel_addr); \n\
+ } \n\
+ if (debug) \n\
+ printf (\"\\n*** Returning implementation: %p.\\n\", \n\
+ return_struct.impl_addr); \n\
+ \n\
+ return return_struct.impl_addr; \n\
+} \n\
";
const char *
AppleObjCTrampolineHandler::g_lookup_implementation_no_stret_function_code =
" \n\
-extern \"C\" \n\
-{ \n\
- extern void *class_getMethodImplementation(void *objc_class, void *sel); \n\
- extern void * object_getClass (id object); \n\
- extern void * sel_getUid(char *name); \n\
- extern int printf(const char *format, ...); \n\
-} \n\
+extern \"C\" \n\
+{ \n\
+ extern void *class_getMethodImplementation(void *objc_class, void *sel); \n\
+ extern void * object_getClass (id object); \n\
+ extern void * sel_getUid(char *name); \n\
+ extern int printf(const char *format, ...); \n\
+} \n\
extern \"C\" void * __lldb_objc_find_implementation_for_selector (void *object, \n\
- void *sel, \n\
- int is_stret, \n\
- int is_super, \n\
- int is_super2, \n\
- int is_fixup, \n\
- int is_fixed, \n\
- int debug) \n\
-{ \n\
- struct __lldb_imp_return_struct \n\
- { \n\
- void *class_addr; \n\
- void *sel_addr; \n\
- void *impl_addr; \n\
- }; \n\
- \n\
- struct __lldb_objc_class { \n\
- void *isa; \n\
- void *super_ptr; \n\
- }; \n\
- struct __lldb_objc_super { \n\
- void *reciever; \n\
- struct __lldb_objc_class *class_ptr; \n\
- }; \n\
- struct __lldb_msg_ref { \n\
- void *dont_know; \n\
- void *sel; \n\
- }; \n\
- \n\
- struct __lldb_imp_return_struct return_struct; \n\
- \n\
- if (debug) \n\
+ void *sel, \n\
+ int is_stret, \n\
+ int is_super, \n\
+ int is_super2, \n\
+ int is_fixup, \n\
+ int is_fixed, \n\
+ int debug) \n\
+{ \n\
+ struct __lldb_imp_return_struct \n\
+ { \n\
+ void *class_addr; \n\
+ void *sel_addr; \n\
+ void *impl_addr; \n\
+ }; \n\
+ \n\
+ struct __lldb_objc_class { \n\
+ void *isa; \n\
+ void *super_ptr; \n\
+ }; \n\
+ struct __lldb_objc_super { \n\
+ void *reciever; \n\
+ struct __lldb_objc_class *class_ptr; \n\
+ }; \n\
+ struct __lldb_msg_ref { \n\
+ void *dont_know; \n\
+ void *sel; \n\
+ }; \n\
+ \n\
+ struct __lldb_imp_return_struct return_struct; \n\
+ \n\
+ if (debug) \n\
printf (\"\\n*** Called with obj: 0x%p sel: 0x%p is_stret: %d is_super: %d, \" \n\
- \"is_super2: %d, is_fixup: %d, is_fixed: %d\\n\", \n\
+ \"is_super2: %d, is_fixup: %d, is_fixed: %d\\n\", \n\
object, sel, is_stret, is_super, is_super2, is_fixup, is_fixed); \n\
- if (is_super) \n\
- { \n\
- if (is_super2) \n\
- { \n\
+ if (is_super) \n\
+ { \n\
+ if (is_super2) \n\
+ { \n\
return_struct.class_addr = ((__lldb_objc_super *) object)->class_ptr->super_ptr; \n\
- } \n\
- else \n\
- { \n\
+ } \n\
+ else \n\
+ { \n\
return_struct.class_addr = ((__lldb_objc_super *) object)->class_ptr; \n\
- } \n\
- } \n\
- else \n\
- { \n\
- // This code seems a little funny, but has its reasons... \n\
+ } \n\
+ } \n\
+ else \n\
+ { \n\
+ // This code seems a little funny, but has its reasons... \n\
// The call to [object class] is here because if this is a class, and has not been called into \n\
// yet, we need to do something to force the class to initialize itself. \n\
// Then the call to object_getClass will actually return the correct class, either the class \n\
// if object is a class instance, or the meta-class if it is a class pointer. \n\
- void *class_ptr = (void *) [(id) object class]; \n\
- return_struct.class_addr = (id) object_getClass((id) object); \n\
- if (debug) \n\
- { \n\
- if (class_ptr == object) \n\
- { \n\
+ void *class_ptr = (void *) [(id) object class]; \n\
+ return_struct.class_addr = (id) object_getClass((id) object); \n\
+ if (debug) \n\
+ { \n\
+ if (class_ptr == object) \n\
+ { \n\
printf (\"Found a class object, need to return the meta class %p -> %p\\n\", \n\
- class_ptr, return_struct.class_addr); \n\
- } \n\
- else \n\
- { \n\
+ class_ptr, return_struct.class_addr); \n\
+ } \n\
+ else \n\
+ { \n\
printf (\"[object class] returned: %p object_getClass: %p.\\n\", \n\
- class_ptr, return_struct.class_addr); \n\
- } \n\
- } \n\
- } \n\
- \n\
- if (is_fixup) \n\
- { \n\
- if (is_fixed) \n\
- { \n\
- return_struct.sel_addr = ((__lldb_msg_ref *) sel)->sel; \n\
- } \n\
- else \n\
- { \n\
- char *sel_name = (char *) ((__lldb_msg_ref *) sel)->sel; \n\
- return_struct.sel_addr = sel_getUid (sel_name); \n\
- if (debug) \n\
- printf (\"\\n*** Got fixed up selector: %p for name %s.\\n\", \n\
- return_struct.sel_addr, sel_name); \n\
- } \n\
- } \n\
- else \n\
- { \n\
- return_struct.sel_addr = sel; \n\
- } \n\
- \n\
- return_struct.impl_addr = class_getMethodImplementation (return_struct.class_addr, \n\
- return_struct.sel_addr); \n\
- if (debug) \n\
- printf (\"\\n*** Returning implementation: 0x%p.\\n\", return_struct.impl_addr); \n\
- \n\
- return return_struct.impl_addr; \n\
-} \n\
+ class_ptr, return_struct.class_addr); \n\
+ } \n\
+ } \n\
+ } \n\
+ \n\
+ if (is_fixup) \n\
+ { \n\
+ if (is_fixed) \n\
+ { \n\
+ return_struct.sel_addr = ((__lldb_msg_ref *) sel)->sel; \n\
+ } \n\
+ else \n\
+ { \n\
+ char *sel_name = (char *) ((__lldb_msg_ref *) sel)->sel; \n\
+ return_struct.sel_addr = sel_getUid (sel_name); \n\
+ if (debug) \n\
+ printf (\"\\n*** Got fixed up selector: %p for name %s.\\n\",\n\
+ return_struct.sel_addr, sel_name); \n\
+ } \n\
+ } \n\
+ else \n\
+ { \n\
+ return_struct.sel_addr = sel; \n\
+ } \n\
+ \n\
+ return_struct.impl_addr = \n\
+ class_getMethodImplementation (return_struct.class_addr, \n\
+ return_struct.sel_addr); \n\
+ if (debug) \n\
+ printf (\"\\n*** Returning implementation: 0x%p.\\n\", \n\
+ return_struct.impl_addr); \n\
+ \n\
+ return return_struct.impl_addr; \n\
+} \n\
";
AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::VTableRegion(
@@ -328,12 +338,11 @@ void AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::SetUpRegion() {
// uint32_t offset
// uint32_t flags
//
- // Where offset is either 0 - in which case it is unused, or
- // it is the offset of the vtable code from the beginning of the descriptor
- // record.
- // Below, we'll convert that into an absolute code address, since I don't want
- // to have
- // to compute it over and over.
+ // Where offset is either 0 - in which case it is unused, or it is
+ // the offset of the vtable code from the beginning of the
+ // descriptor record. Below, we'll convert that into an absolute
+ // code address, since I don't want to have to compute it over and
+ // over.
// Ingest the whole descriptor array:
const lldb::addr_t desc_ptr = m_header_addr + header_size;
@@ -370,10 +379,9 @@ void AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::SetUpRegion() {
offset = start_offset + descriptor_size;
}
- // Finally, a little bird told me that all the vtable code blocks are the same
- // size.
- // Let's compute the blocks and if they are all the same add the size to the
- // code end address:
+ // Finally, a little bird told me that all the vtable code blocks
+ // are the same size. Let's compute the blocks and if they are all
+ // the same add the size to the code end address:
lldb::addr_t code_size = 0;
bool all_the_same = true;
for (size_t i = 0; i < num_descriptors - 1; i++) {
@@ -548,9 +556,8 @@ bool AppleObjCTrampolineHandler::AppleObjCVTables::RefreshTrampolines(
}
bool AppleObjCTrampolineHandler::AppleObjCVTables::ReadRegions() {
- // The no argument version reads the start region from the value of the
- // gdb_regions_header, and
- // gets started from there.
+ // The no argument version reads the start region from the value of
+ // the gdb_regions_header, and gets started from there.
m_regions.clear();
if (!InitializeVTableSymbols())
@@ -718,13 +725,12 @@ AppleObjCTrampolineHandler::AppleObjCTrampolineHandler(
g_lookup_implementation_with_stret_function_code;
}
- // Look up the addresses for the objc dispatch functions and cache them. For
- // now I'm inspecting the symbol
- // names dynamically to figure out how to dispatch to them. If it becomes
- // more complicated than this we can
- // turn the g_dispatch_functions char * array into a template table, and
- // populate the DispatchFunction map
- // from there.
+ // Look up the addresses for the objc dispatch functions and cache
+ // them. For now I'm inspecting the symbol names dynamically to
+ // figure out how to dispatch to them. If it becomes more
+ // complicated than this we can turn the g_dispatch_functions char *
+ // array into a template table, and populate the DispatchFunction
+ // map from there.
for (size_t i = 0; i != llvm::array_lengthof(g_dispatch_functions); i++) {
ConstString name_const_str(g_dispatch_functions[i].name);
@@ -732,11 +738,11 @@ AppleObjCTrampolineHandler::AppleObjCTrampolineHandler(
m_objc_module_sp->FindFirstSymbolWithNameAndType(name_const_str,
eSymbolTypeCode);
if (msgSend_symbol && msgSend_symbol->ValueIsAddress()) {
- // FixMe: Make g_dispatch_functions static table of DispatchFunctions, and
- // have the map be address->index.
- // Problem is we also need to lookup the dispatch function. For now we
- // could have a side table of stret & non-stret
- // dispatch functions. If that's as complex as it gets, we're fine.
+ // FIXME: Make g_dispatch_functions static table of
+ // DispatchFunctions, and have the map be address->index.
+ // Problem is we also need to lookup the dispatch function. For
+ // now we could have a side table of stret & non-stret dispatch
+ // functions. If that's as complex as it gets, we're fine.
lldb::addr_t sym_addr =
msgSend_symbol->GetAddressRef().GetOpcodeLoadAddress(target);
@@ -820,11 +826,11 @@ AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread,
diagnostics.Clear();
- // Now write down the argument values for this particular call. This looks
- // like it might be a race condition
- // if other threads were calling into here, but actually it isn't because we
- // allocate a new args structure for
- // this call by passing args_addr = LLDB_INVALID_ADDRESS...
+ // Now write down the argument values for this particular call.
+ // This looks like it might be a race condition if other threads
+ // were calling into here, but actually it isn't because we allocate
+ // a new args structure for this call by passing args_addr =
+ // LLDB_INVALID_ADDRESS...
if (!impl_function_caller->WriteFunctionArguments(
exe_ctx, args_addr, dispatch_values, diagnostics)) {
@@ -847,9 +853,9 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
DispatchFunction this_dispatch;
bool found_it = false;
- // First step is to look and see if we are in one of the known ObjC dispatch
- // functions. We've already compiled
- // a table of same, so consult it.
+ // First step is to look and see if we are in one of the known ObjC
+ // dispatch functions. We've already compiled a table of same, so
+ // consult it.
MsgsendMap::iterator pos;
pos = m_msgSend_map.find(curr_pc);
@@ -879,8 +885,8 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
if (found_it) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
- // We are decoding a method dispatch.
- // First job is to pull the arguments out:
+ // We are decoding a method dispatch. First job is to pull the
+ // arguments out:
lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
@@ -906,10 +912,10 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
int obj_index;
int sel_index;
- // If this is a struct return dispatch, then the first argument is the
- // return struct pointer, and the object is the second, and the selector is
- // the third.
- // Otherwise the object is the first and the selector the second.
+ // If this is a struct return dispatch, then the first argument is
+ // the return struct pointer, and the object is the second, and
+ // the selector is the third. Otherwise the object is the first
+ // and the selector the second.
if (this_dispatch.stret_return) {
obj_index = 1;
sel_index = 2;
@@ -938,29 +944,26 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
ExecutionContext exe_ctx(thread.shared_from_this());
Process *process = exe_ctx.GetProcessPtr();
- // isa_addr will store the class pointer that the method is being dispatched
- // to - so either the class
- // directly or the super class if this is one of the objc_msgSendSuper
- // flavors. That's mostly used to
- // look up the class/selector pair in our cache.
+ // isa_addr will store the class pointer that the method is being
+ // dispatched to - so either the class directly or the super class
+ // if this is one of the objc_msgSendSuper flavors. That's mostly
+ // used to look up the class/selector pair in our cache.
lldb::addr_t isa_addr = LLDB_INVALID_ADDRESS;
lldb::addr_t sel_addr =
argument_values.GetValueAtIndex(sel_index)->GetScalar().ULongLong();
- // Figure out the class this is being dispatched to and see if we've already
- // cached this method call,
- // If so we can push a run-to-address plan directly. Otherwise we have to
- // figure out where
- // the implementation lives.
+ // Figure out the class this is being dispatched to and see if
+ // we've already cached this method call, If so we can push a
+ // run-to-address plan directly. Otherwise we have to figure out
+ // where the implementation lives.
if (this_dispatch.is_super) {
if (this_dispatch.is_super2) {
- // In the objc_msgSendSuper2 case, we don't get the object directly, we
- // get a structure containing
- // the object and the class to which the super message is being sent.
- // So we need to dig the super
- // out of the class and use that.
+ // In the objc_msgSendSuper2 case, we don't get the object
+ // directly, we get a structure containing the object and the
+ // class to which the super message is being sent. So we need
+ // to dig the super out of the class and use that.
Value super_value(*(argument_values.GetValueAtIndex(obj_index)));
super_value.GetScalar() += process->GetAddressByteSize();
@@ -984,11 +987,11 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
log->Printf("Failed to extract the class value from objc_super.");
}
} else {
- // In the objc_msgSendSuper case, we don't get the object directly, we
- // get a two element structure containing
- // the object and the super class to which the super message is being
- // sent. So the class we want is
- // the second element of this structure.
+ // In the objc_msgSendSuper case, we don't get the object
+ // directly, we get a two element structure containing the
+ // object and the super class to which the super message is
+ // being sent. So the class we want is the second element of
+ // this structure.
Value super_value(*(argument_values.GetValueAtIndex(obj_index)));
super_value.GetScalar() += process->GetAddressByteSize();
@@ -1009,9 +1012,9 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
// making the object value a load address value and resolving it will get
// the pointer sized data pointed to by that value...
- // Note, it isn't a fatal error not to be able to get the address from the
- // object, since this might
- // be a "tagged pointer" which isn't a real object, but rather some word
+ // Note, it isn't a fatal error not to be able to get the
+ // address from the object, since this might be a "tagged
+ // pointer" which isn't a real object, but rather some word
// length encoded dingus.
Value isa_value(*(argument_values.GetValueAtIndex(obj_index)));
@@ -1126,9 +1129,9 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
flag_value.GetScalar() = 0; // FIXME - Set to 0 when debugging is done.
dispatch_values.PushValue(flag_value);
- // The step through code might have to fill in the cache, so it is not
- // safe to run only one thread.
- // So we override the stop_others value passed in to us here:
+ // The step through code might have to fill in the cache, so it
+ // is not safe to run only one thread. So we override the
+ // stop_others value passed in to us here:
const bool trampoline_stop_others = false;
ret_plan_sp.reset(new AppleThreadPlanStepThroughObjCTrampoline(
thread, this, dispatch_values, isa_addr, sel_addr,
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
index 316115b0dcb1..9bb1a4e0ee42 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
@@ -105,10 +105,9 @@ clang::QualType AppleObjCTypeEncodingParser::BuildAggregate(
return clang::QualType();
std::string name(ReadStructName(type));
- // We do not handle templated classes/structs at the moment.
- // If the name has a < in it, we are going to abandon this.
- // We're still obliged to parse it, so we just set a flag that
- // means "Don't actually build anything."
+ // We do not handle templated classes/structs at the moment. If the name has
+ // a < in it, we are going to abandon this. We're still obliged to parse it,
+ // so we just set a flag that means "Don't actually build anything."
const bool is_templated = name.find('<') != std::string::npos;
@@ -180,11 +179,9 @@ AppleObjCTypeEncodingParser::BuildArray(clang::ASTContext &ast_ctx,
// the runtime can emit these in the form of @"SomeType", giving more specifics
// this would be interesting for expression parser interop, but since we
-// actually try
-// to avoid exposing the ivar info to the expression evaluator, consume but
-// ignore the type info
-// and always return an 'id'; if anything, dynamic typing will resolve things
-// for us anyway
+// actually try to avoid exposing the ivar info to the expression evaluator,
+// consume but ignore the type info and always return an 'id'; if anything,
+// dynamic typing will resolve things for us anyway
clang::QualType AppleObjCTypeEncodingParser::BuildObjCObjectPointerType(
clang::ASTContext &ast_ctx, lldb_utility::StringLexer &type,
bool for_expression) {
@@ -197,24 +194,21 @@ clang::QualType AppleObjCTypeEncodingParser::BuildObjCObjectPointerType(
// We have to be careful here. We're used to seeing
// @"NSString"
// but in records it is possible that the string following an @ is the name
- // of the next field and @ means "id".
- // This is the case if anything unquoted except for "}", the end of the
- // type, or another name follows the quoted string.
+ // of the next field and @ means "id". This is the case if anything
+ // unquoted except for "}", the end of the type, or another name follows
+ // the quoted string.
//
// E.g.
// - @"NSString"@ means "id, followed by a field named NSString of type id"
- // - @"NSString"} means "a pointer to NSString and the end of the struct"
- // - @"NSString""nextField" means "a pointer to NSString and a field named
- // nextField"
- // - @"NSString" followed by the end of the string means "a pointer to
- // NSString"
+ // - @"NSString"} means "a pointer to NSString and the end of the struct" -
+ // @"NSString""nextField" means "a pointer to NSString and a field named
+ // nextField" - @"NSString" followed by the end of the string means "a
+ // pointer to NSString"
//
// As a result, the rule is: If we see @ followed by a quoted string, we
- // peek.
- // - If we see }, ), ], the end of the string, or a quote ("), the quoted
- // string is a class name.
- // - If we see anything else, the quoted string is a field name and we push
- // it back onto type.
+ // peek. - If we see }, ), ], the end of the string, or a quote ("), the
+ // quoted string is a class name. - If we see anything else, the quoted
+ // string is a field name and we push it back onto type.
name = ReadQuotedString(type);
@@ -260,9 +254,8 @@ clang::QualType AppleObjCTypeEncodingParser::BuildObjCObjectPointerType(
decl_vendor->FindDecls(ConstString(name), append, max_matches, decls);
// The user can forward-declare something that has no definition. The runtime
-// doesn't prohibit this at all.
-// This is a rare and very weird case. We keep this assert in debug builds so
-// we catch other weird cases.
+// doesn't prohibit this at all. This is a rare and very weird case. We keep
+// this assert in debug builds so we catch other weird cases.
#ifdef LLDB_CONFIGURATION_DEBUG
assert(num_types);
#else
@@ -315,8 +308,8 @@ AppleObjCTypeEncodingParser::BuildType(clang::ASTContext &ast_ctx,
// if (!lldb_ctx)
// return clang::QualType();
// return lldb_ctx->GetIntTypeFromBitSize(32, true).GetQualType();
- // which uses one of the constants if one is available, but we don't think all
- // this work is necessary.
+ // which uses one of the constants if one is available, but we don't think
+ // all this work is necessary.
case 'q':
return ast_ctx.LongLongTy;
case 'C':
@@ -364,11 +357,10 @@ AppleObjCTypeEncodingParser::BuildType(clang::ASTContext &ast_ctx,
case '^': {
if (!for_expression && type.NextIf('?')) {
// if we are not supporting the concept of unknownAny, but what is being
- // created here is an unknownAny*, then
- // we can just get away with a void*
+ // created here is an unknownAny*, then we can just get away with a void*
// this is theoretically wrong (in the same sense as 'theoretically
- // nothing exists') but is way better than outright failure
- // in many practical cases
+ // nothing exists') but is way better than outright failure in many
+ // practical cases
return ast_ctx.VoidPtrTy;
} else {
clang::QualType target_type = BuildType(ast_ctx, type, for_expression);
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
index a295d1b4ce76..75b670739427 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
@@ -52,8 +52,8 @@ AppleThreadPlanStepThroughObjCTrampoline::
void AppleThreadPlanStepThroughObjCTrampoline::DidPush() {
// Setting up the memory space for the called function text might require
- // allocations,
- // i.e. a nested function call. This needs to be done as a PreResumeAction.
+ // allocations, i.e. a nested function call. This needs to be done as a
+ // PreResumeAction.
m_thread.GetProcess()->AddPreResumeAction(PreResumeInitializeFunctionCaller,
(void *)this);
}
@@ -110,8 +110,7 @@ bool AppleThreadPlanStepThroughObjCTrampoline::DoPlanExplainsStop(
Event *event_ptr) {
// If we get asked to explain the stop it will be because something went
// wrong (like the implementation for selector function crashed... We're
- // going
- // to figure out what to do about that, so we do explain the stop.
+ // going to figure out what to do about that, so we do explain the stop.
return true;
}
@@ -135,8 +134,7 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) {
}
// Second stage, if all went well with the function calling, then fetch the
- // target address, and
- // queue up a "run to that address" plan.
+ // target address, and queue up a "run to that address" plan.
if (!m_run_to_sp) {
Value target_addr_value;
ExecutionContext exc_ctx;
@@ -201,8 +199,8 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) {
return false;
}
-// The base class MischiefManaged does some cleanup - so you have to call it
-// in your MischiefManaged derived class.
+// The base class MischiefManaged does some cleanup - so you have to call it in
+// your MischiefManaged derived class.
bool AppleThreadPlanStepThroughObjCTrampoline::MischiefManaged() {
if (IsPlanComplete())
return true;
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp
index 654ac9abfcab..cbbc35f1c08a 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp
@@ -38,14 +38,12 @@ using namespace lldb_renderscript;
// [``slang``](https://android.googlesource.com/platform/frameworks/compile/slang),
// the compiler frontend for RenderScript embeds an ARM specific triple in IR
-// that is shipped in the app, after
-// generating IR that has some assumptions that an ARM device is the target.
-// As the IR is then compiled on a device of unknown (at time the IR was
-// generated at least) architecture,
-// when calling RenderScript API function as part of debugger expressions, we
-// have to perform a fixup pass that
-// removes those assumptions right before the module is sent to be generated by
-// the llvm backend.
+// that is shipped in the app, after generating IR that has some assumptions
+// that an ARM device is the target. As the IR is then compiled on a device of
+// unknown (at time the IR was generated at least) architecture, when calling
+// RenderScript API function as part of debugger expressions, we have to
+// perform a fixup pass that removes those assumptions right before the module
+// is sent to be generated by the llvm backend.
namespace {
bool registerRSDefaultTargetOpts(clang::TargetOptions &proto,
@@ -107,10 +105,9 @@ bool RenderScriptRuntimeModulePass::runOnModule(llvm::Module &module) {
case llvm::Triple::ArchType::x86:
changed_module |= fixupX86FunctionCalls(module);
// For some reason this triple gets totally missed by the backend, and must
- // be set manually.
- // There a reference in bcc/Main.cpp about auto feature-detection being
- // removed from LLVM3.5, but I can't
- // see that discussion anywhere public.
+ // be set manually. There a reference in bcc/Main.cpp about auto feature-
+ // detection being removed from LLVM3.5, but I can't see that discussion
+ // anywhere public.
real_triple = "i686--linux-android";
break;
case llvm::Triple::ArchType::x86_64:
@@ -118,12 +115,12 @@ bool RenderScriptRuntimeModulePass::runOnModule(llvm::Module &module) {
break;
case llvm::Triple::ArchType::mipsel:
case llvm::Triple::ArchType::mips64el:
- // No actual IR fixup pass is needed on MIPS, but the datalayout
- // and targetmachine do need to be explicitly set.
+ // No actual IR fixup pass is needed on MIPS, but the datalayout and
+ // targetmachine do need to be explicitly set.
- // bcc explicitly compiles MIPS code to use the static relocation
- // model due to an issue with relocations in mclinker.
- // see libbcc/support/CompilerConfig.cpp for details
+ // bcc explicitly compiles MIPS code to use the static relocation model due
+ // to an issue with relocations in mclinker. see
+ // libbcc/support/CompilerConfig.cpp for details
reloc_model = llvm::Reloc::Static;
changed_module = true;
break;
@@ -146,8 +143,7 @@ bool RenderScriptRuntimeModulePass::runOnModule(llvm::Module &module) {
assert(target_machine &&
"failed to identify RenderScriptRuntime target machine");
// We've been using a triple and datalayout of some ARM variant all along,
- // so
- // we need to let the backend know that this is no longer the case.
+ // so we need to let the backend know that this is no longer the case.
if (log) {
log->Printf("%s - Changing RS target triple to '%s'", __FUNCTION__,
real_triple.str().c_str());
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
index ad1083be0285..4eb15369aa1e 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
@@ -26,7 +26,6 @@
#include "lldb/Expression/UserExpression.h"
#include "lldb/Host/OptionParser.h"
#include "lldb/Host/StringConvert.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/CommandReturnObject.h"
@@ -40,6 +39,7 @@
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/DataBufferLLVM.h"
#include "lldb/Utility/Log.h"
@@ -312,7 +312,8 @@ bool GetArgsMipsel(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
Status err;
- // find offset to arguments on the stack (+16 to skip over a0-a3 shadow space)
+ // find offset to arguments on the stack (+16 to skip over a0-a3 shadow
+ // space)
uint64_t sp = ctx.reg_ctx->GetSP() + 16;
for (size_t i = 0; i < num_args; ++i) {
@@ -447,12 +448,11 @@ bool IsRenderScriptScriptModule(ModuleSP module) {
}
bool ParseCoordinate(llvm::StringRef coord_s, RSCoordinate &coord) {
- // takes an argument of the form 'num[,num][,num]'.
- // Where 'coord_s' is a comma separated 1,2 or 3-dimensional coordinate
- // with the whitespace trimmed.
- // Missing coordinates are defaulted to zero.
- // If parsing of any elements fails the contents of &coord are undefined
- // and `false` is returned, `true` otherwise
+ // takes an argument of the form 'num[,num][,num]'. Where 'coord_s' is a
+ // comma separated 1,2 or 3-dimensional coordinate with the whitespace
+ // trimmed. Missing coordinates are defaulted to zero. If parsing of any
+ // elements fails the contents of &coord are undefined and `false` is
+ // returned, `true` otherwise
RegularExpression regex;
RegularExpression::Match regex_match(3);
@@ -593,7 +593,7 @@ struct RenderScriptRuntime::Element {
empirical_type<uint32_t> datum_size; // Size of a single Element with padding
empirical_type<uint32_t> padding; // Number of padding bytes
empirical_type<uint32_t>
- array_size; // Number of items in array, only needed for strucrs
+ array_size; // Number of items in array, only needed for structs
ConstString type_name; // Name of type, only needed for structs
static const ConstString &
@@ -633,8 +633,9 @@ struct RenderScriptRuntime::AllocationDetails {
// subelements, there may be more than one instance of the ElementHeader
// struct. With this first instance being the root element, and the other
// instances being the root's descendants. To identify which instances are an
- // ElementHeader's children, each struct is immediately followed by a sequence
- // of consecutive offsets to the start of its child structs. These offsets are
+ // ElementHeader's children, each struct is immediately followed by a
+ // sequence of consecutive offsets to the start of its child structs. These
+ // offsets are
// 4 bytes in size, and the 0 offset signifies no more children.
struct FileHeader {
uint8_t ident[4]; // ASCII 'RSAD' identifying the file
@@ -653,8 +654,8 @@ struct RenderScriptRuntime::AllocationDetails {
// Monotonically increasing from 1
static uint32_t ID;
- // Maps Allocation DataType enum and vector size to printable strings
- // using mapping from RenderScript numerical types summary documentation
+ // Maps Allocation DataType enum and vector size to printable strings using
+ // mapping from RenderScript numerical types summary documentation
static const char *RsDataTypeToString[][4];
// Maps Allocation DataKind enum to printable strings
@@ -844,11 +845,10 @@ RSReduceBreakpointResolver::SearchCallback(lldb_private::SearchFilter &filter,
lldb_private::SymbolContext &context,
Address *, bool) {
// We need to have access to the list of reductions currently parsed, as
- // reduce names don't actually exist as
- // symbols in a module. They are only identifiable by parsing the .rs.info
- // packet, or finding the expand symbol. We
- // therefore need access to the list of parsed rs modules to properly resolve
- // reduction names.
+ // reduce names don't actually exist as symbols in a module. They are only
+ // identifiable by parsing the .rs.info packet, or finding the expand symbol.
+ // We therefore need access to the list of parsed rs modules to properly
+ // resolve reduction names.
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
ModuleSP module = context.module_sp;
@@ -967,8 +967,8 @@ Searcher::CallbackReturn RSScriptGroupBreakpointResolver::SearchCallback(
log->Printf("%s: Placed %sbreakpoint on %s", __FUNCTION__,
new_bp ? "new " : "", k.m_name.AsCString());
- // exit after placing the first breakpoint if we do not intend to stop
- // on all kernels making up this script group
+ // exit after placing the first breakpoint if we do not intend to stop on
+ // all kernels making up this script group
if (!m_stop_on_all)
break;
}
@@ -1684,8 +1684,8 @@ void RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp) {
const ModuleSP module = rsmodule_sp->m_module;
const FileSpec &file = module->GetPlatformFileSpec();
- // Iterate over all of the scripts that we currently know of.
- // Note: We cant push or pop to m_scripts here or it may invalidate rs_script.
+ // Iterate over all of the scripts that we currently know of. Note: We cant
+ // push or pop to m_scripts here or it may invalidate rs_script.
for (const auto &rs_script : m_scripts) {
// Extract the expected .so file path for this script.
std::string shared_lib;
@@ -1825,9 +1825,9 @@ const char *JITTemplate(ExpressionStrings e) {
// rsaTypeGetNativeData(Context*, Type*, void* typeData, size) Pack the
// data in the following way mHal.state.dimX; mHal.state.dimY;
- // mHal.state.dimZ; mHal.state.lodCount; mHal.state.faces; mElement; into
- // typeData Need to specify 32 or 64 bit for uint_t since this differs
- // between devices
+ // mHal.state.dimZ; mHal.state.lodCount; mHal.state.faces; mElement;
+ // into typeData Need to specify 32 or 64 bit for uint_t since this
+ // differs between devices
JIT_TEMPLATE_CONTEXT
"uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(ctxt"
", 0x%" PRIx64 ", data, 6); data[0]", // eExprTypeDimX
@@ -1882,10 +1882,10 @@ const char *JITTemplate(ExpressionStrings e) {
}
} // end of the anonymous namespace
-// JITs the RS runtime for the internal data pointer of an allocation. Is passed
-// x,y,z coordinates for the pointer to a specific element. Then sets the
-// data_ptr member in Allocation with the result. Returns true on success, false
-// otherwise
+// JITs the RS runtime for the internal data pointer of an allocation. Is
+// passed x,y,z coordinates for the pointer to a specific element. Then sets
+// the data_ptr member in Allocation with the result. Returns true on success,
+// false otherwise
bool RenderScriptRuntime::JITDataPointer(AllocationDetails *alloc,
StackFrame *frame_ptr, uint32_t x,
uint32_t y, uint32_t z) {
@@ -1961,8 +1961,8 @@ bool RenderScriptRuntime::JITTypePointer(AllocationDetails *alloc,
}
// JITs the RS runtime for information about the dimensions and type of an
-// allocation Then sets dimension and element_ptr members in Allocation with the
-// result. Returns true on success, false otherwise
+// allocation Then sets dimension and element_ptr members in Allocation with
+// the result. Returns true on success, false otherwise
bool RenderScriptRuntime::JITTypePacked(AllocationDetails *alloc,
StackFrame *frame_ptr) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
@@ -2245,9 +2245,8 @@ bool RenderScriptRuntime::JITAllocationSize(AllocationDetails *alloc,
}
// JITs the RS runtime for information about the stride between rows in the
-// allocation. This is done to detect padding, since allocated memory is 16-byte
-// aligned.
-// Returns true on success, false otherwise
+// allocation. This is done to detect padding, since allocated memory is
+// 16-byte aligned. Returns true on success, false otherwise
bool RenderScriptRuntime::JITAllocationStride(AllocationDetails *alloc,
StackFrame *frame_ptr) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
@@ -2313,9 +2312,8 @@ bool RenderScriptRuntime::RefreshAllocation(AllocationDetails *alloc,
}
// Function attempts to set the type_name member of the paramaterised Element
-// object.
-// This string should be the name of the struct type the Element represents.
-// We need this string for pretty printing the Element to users.
+// object. This string should be the name of the struct type the Element
+// represents. We need this string for pretty printing the Element to users.
void RenderScriptRuntime::FindStructTypeName(Element &elem,
StackFrame *frame_ptr) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
@@ -2330,12 +2328,11 @@ void RenderScriptRuntime::FindStructTypeName(Element &elem,
VariableList var_list;
for (auto module_sp : m_rsmodules)
module_sp->m_module->FindGlobalVariables(
- RegularExpression(llvm::StringRef(".")), true, UINT32_MAX, var_list);
+ RegularExpression(llvm::StringRef(".")), UINT32_MAX, var_list);
// Iterate over all the global variables looking for one with a matching type
- // to the Element.
- // We make the assumption a match exists since there needs to be a global
- // variable to reflect the struct type back into java host code.
+ // to the Element. We make the assumption a match exists since there needs to
+ // be a global variable to reflect the struct type back into java host code.
for (uint32_t i = 0; i < var_list.GetSize(); ++i) {
const VariableSP var_sp(var_list.GetVariableAtIndex(i));
if (!var_sp)
@@ -2347,15 +2344,14 @@ void RenderScriptRuntime::FindStructTypeName(Element &elem,
// Find the number of variable fields.
// If it has no fields, or more fields than our Element, then it can't be
- // the struct we're looking for.
- // Don't check for equality since RS can add extra struct members for
- // padding.
+ // the struct we're looking for. Don't check for equality since RS can add
+ // extra struct members for padding.
size_t num_children = valobj_sp->GetNumChildren();
if (num_children > elem.children.size() || num_children == 0)
continue;
- // Iterate over children looking for members with matching field names.
- // If all the field names match, this is likely the struct we want.
+ // Iterate over children looking for members with matching field names. If
+ // all the field names match, this is likely the struct we want.
// TODO: This could be made more robust by also checking children data
// sizes, or array size
bool found = true;
@@ -2404,8 +2400,8 @@ void RenderScriptRuntime::FindStructTypeName(Element &elem,
}
// Function sets the datum_size member of Element. Representing the size of a
-// single instance including padding.
-// Assumes the relevant allocation information has already been jitted.
+// single instance including padding. Assumes the relevant allocation
+// information has already been jitted.
void RenderScriptRuntime::SetElementSize(Element &elem) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
const Element::DataType type = *elem.type.get();
@@ -2446,9 +2442,9 @@ void RenderScriptRuntime::SetElementSize(Element &elem) {
data_size + padding);
}
-// Given an allocation, this function copies the allocation contents from device
-// into a buffer on the heap.
-// Returning a shared pointer to the buffer containing the data.
+// Given an allocation, this function copies the allocation contents from
+// device into a buffer on the heap. Returning a shared pointer to the buffer
+// containing the data.
std::shared_ptr<uint8_t>
RenderScriptRuntime::GetAllocationData(AllocationDetails *alloc,
StackFrame *frame_ptr) {
@@ -2496,9 +2492,8 @@ RenderScriptRuntime::GetAllocationData(AllocationDetails *alloc,
return buffer;
}
-// Function copies data from a binary file into an allocation.
-// There is a header at the start of the file, FileHeader, before the data
-// content itself.
+// Function copies data from a binary file into an allocation. There is a
+// header at the start of the file, FileHeader, before the data content itself.
// Information from this header is used to display warnings to the user about
// incompatibilities
bool RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id,
@@ -2630,7 +2625,8 @@ bool RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id,
// Calculate size of allocation data in file
size_t size = data_sp->GetByteSize() - file_header->hdr_size;
- // Check if the target allocation and file both have the same total data size.
+ // Check if the target allocation and file both have the same total data
+ // size.
const uint32_t alloc_size = *alloc->size.get();
if (alloc_size != size) {
strm.Printf("Warning: Mismatched allocation sizes - file 0x%" PRIx64
@@ -2660,15 +2656,15 @@ bool RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id,
// Function takes as parameters a byte buffer, which will eventually be written
// to file as the element header, an offset into that buffer, and an Element
-// that will be saved into the buffer at the parametrised offset.
-// Return value is the new offset after writing the element into the buffer.
-// Elements are saved to the file as the ElementHeader struct followed by
-// offsets to the structs of all the element's children.
+// that will be saved into the buffer at the parametrised offset. Return value
+// is the new offset after writing the element into the buffer. Elements are
+// saved to the file as the ElementHeader struct followed by offsets to the
+// structs of all the element's children.
size_t RenderScriptRuntime::PopulateElementHeaders(
const std::shared_ptr<uint8_t> header_buffer, size_t offset,
const Element &elem) {
- // File struct for an element header with all the relevant details copied from
- // elem. We assume members are valid already.
+ // File struct for an element header with all the relevant details copied
+ // from elem. We assume members are valid already.
AllocationDetails::ElementHeader elem_header;
elem_header.type = *elem.type.get();
elem_header.kind = *elem.type_kind.get();
@@ -2678,9 +2674,8 @@ size_t RenderScriptRuntime::PopulateElementHeaders(
elem.array_size.isValid() ? *elem.array_size.get() : 0;
const size_t elem_header_size = sizeof(AllocationDetails::ElementHeader);
- // Copy struct into buffer and advance offset
- // We assume that header_buffer has been checked for nullptr before this
- // method is called
+ // Copy struct into buffer and advance offset We assume that header_buffer
+ // has been checked for nullptr before this method is called
memcpy(header_buffer.get() + offset, &elem_header, elem_header_size);
offset += elem_header_size;
@@ -2721,8 +2716,8 @@ size_t RenderScriptRuntime::CalculateElementHeaderSize(const Element &elem) {
return size;
}
-// Function copies allocation contents into a binary file. This file can then be
-// loaded later into a different allocation. There is a header, FileHeader,
+// Function copies allocation contents into a binary file. This file can then
+// be loaded later into a different allocation. There is a header, FileHeader,
// before the allocation data containing meta-data.
bool RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id,
const char *path,
@@ -2852,8 +2847,8 @@ bool RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp) {
if (module_sp) {
for (const auto &rs_module : m_rsmodules) {
if (rs_module->m_module == module_sp) {
- // Check if the user has enabled automatically breaking on
- // all RS kernels.
+ // Check if the user has enabled automatically breaking on all RS
+ // kernels.
if (m_breakAllKernels)
BreakOnModuleKernels(rs_module);
@@ -2975,11 +2970,10 @@ bool RSModuleDescriptor::ParseExportReduceCount(llvm::StringRef *lines,
size_t n_lines) {
// The list of reduction kernels in the `.rs.info` symbol is of the form
// "signature - accumulatordatasize - reduction_name - initializer_name -
- // accumulator_name - combiner_name -
- // outconverter_name - halter_name"
- // Where a function is not explicitly named by the user, or is not generated
- // by the compiler, it is named "." so the
- // dash separated list should always be 8 items long
+ // accumulator_name - combiner_name - outconverter_name - halter_name" Where
+ // a function is not explicitly named by the user, or is not generated by the
+ // compiler, it is named "." so the dash separated list should always be 8
+ // items long
Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
// Skip the exportReduceCount line
++lines;
@@ -3069,8 +3063,7 @@ bool RSModuleDescriptor::ParseExportVarCount(llvm::StringRef *lines,
}
// The .rs.info symbol in renderscript modules contains a string which needs to
-// be parsed.
-// The string is basic and is parsed on a line by line basis.
+// be parsed. The string is basic and is parsed on a line by line basis.
bool RSModuleDescriptor::ParseRSInfo() {
assert(m_module);
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
@@ -3137,8 +3130,8 @@ bool RSModuleDescriptor::ParseRSInfo() {
const auto handler = rs_info_handler(key);
if (handler == -1)
continue;
- // getAsInteger returns `true` on an error condition - we're only interested
- // in numeric fields at the moment
+ // getAsInteger returns `true` on an error condition - we're only
+ // interested in numeric fields at the moment
uint64_t n_lines;
if (val.getAsInteger(10, n_lines)) {
LLDB_LOGV(log, "Failed to parse non-numeric '.rs.info' section {0}",
@@ -3213,9 +3206,8 @@ void RenderScriptRuntime::DumpContexts(Stream &strm) const {
std::map<addr_t, uint64_t> contextReferences;
- // Iterate over all of the currently discovered scripts.
- // Note: We cant push or pop from m_scripts inside this loop or it may
- // invalidate script.
+ // Iterate over all of the currently discovered scripts. Note: We cant push
+ // or pop from m_scripts inside this loop or it may invalidate script.
for (const auto &script : m_scripts) {
if (!script->context.isValid())
continue;
@@ -3393,15 +3385,15 @@ bool RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame *frame_ptr,
if ((type == Element::RS_TYPE_NONE) &&
(alloc->element.children.size() > 0) &&
(alloc->element.type_name != Element::GetFallbackStructName())) {
- // Here we are dumping an Element of struct type.
- // This is done using expression evaluation with the name of the
- // struct type and pointer to element.
- // Don't print the name of the resulting expression, since this will
- // be '$[0-9]+'
+ // Here we are dumping an Element of struct type. This is done using
+ // expression evaluation with the name of the struct type and pointer
+ // to element. Don't print the name of the resulting expression,
+ // since this will be '$[0-9]+'
DumpValueObjectOptions expr_options;
expr_options.SetHideName(true);
- // Setup expression as derefrencing a pointer cast to element address.
+ // Setup expression as dereferencing a pointer cast to element
+ // address.
char expr_char_buffer[jit_max_expr_size];
int written =
snprintf(expr_char_buffer, jit_max_expr_size, "*(%s*) 0x%" PRIx64,
@@ -3435,9 +3427,9 @@ bool RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame *frame_ptr,
return true;
}
-// Function recalculates all our cached information about allocations by jitting
-// the RS runtime regarding each allocation we know about. Returns true if all
-// allocations could be recomputed, false otherwise.
+// Function recalculates all our cached information about allocations by
+// jitting the RS runtime regarding each allocation we know about. Returns true
+// if all allocations could be recomputed, false otherwise.
bool RenderScriptRuntime::RecomputeAllAllocations(Stream &strm,
StackFrame *frame_ptr) {
bool success = true;
@@ -3601,8 +3593,8 @@ void RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target) {
}
}
-// Given the name of a kernel this function creates a breakpoint using our
-// own breakpoint resolver, and returns the Breakpoint shared pointer.
+// Given the name of a kernel this function creates a breakpoint using our own
+// breakpoint resolver, and returns the Breakpoint shared pointer.
BreakpointSP
RenderScriptRuntime::CreateKernelBreakpoint(const ConstString &name) {
Log *log(
@@ -3743,8 +3735,8 @@ bool RenderScriptRuntime::GetKernelCoordinate(RSCoordinate &coord,
log->Printf("%s - Found .expand function '%s'", __FUNCTION__,
func_name.GetCString());
- // Get values for variables in .expand frame that tell us the current kernel
- // invocation
+ // Get values for variables in .expand frame that tell us the current
+ // kernel invocation
uint64_t x, y, z;
bool found = GetFrameVarAsUnsigned(frame_sp, x_expr, x) &&
GetFrameVarAsUnsigned(frame_sp, y_expr, y) &&
@@ -3765,12 +3757,11 @@ bool RenderScriptRuntime::GetKernelCoordinate(RSCoordinate &coord,
// Callback when a kernel breakpoint hits and we're looking for a specific
// coordinate. Baton parameter contains a pointer to the target coordinate we
-// want to break on.
-// Function then checks the .expand frame for the current coordinate and breaks
-// to user if it matches.
-// Parameter 'break_id' is the id of the Breakpoint which made the callback.
-// Parameter 'break_loc_id' is the id for the BreakpointLocation which was hit,
-// a single logical breakpoint can have multiple addresses.
+// want to break on. Function then checks the .expand frame for the current
+// coordinate and breaks to user if it matches. Parameter 'break_id' is the id
+// of the Breakpoint which made the callback. Parameter 'break_loc_id' is the
+// id for the BreakpointLocation which was hit, a single logical breakpoint can
+// have multiple addresses.
bool RenderScriptRuntime::KernelBreakpointHit(void *baton,
StoppointCallbackContext *ctx,
user_id_t break_id,
@@ -3845,12 +3836,10 @@ void RenderScriptRuntime::SetConditional(BreakpointSP bp, Stream &messages,
m_conditional_breaks[bp->GetID()] = std::unique_ptr<RSCoordinate>(baton);
}
-// Tries to set a breakpoint on the start of a kernel, resolved using the kernel
-// name. Argument 'coords', represents a three dimensional coordinate which can
-// be
-// used to specify a single kernel instance to break on. If this is set then we
-// add a callback
-// to the breakpoint.
+// Tries to set a breakpoint on the start of a kernel, resolved using the
+// kernel name. Argument 'coords', represents a three dimensional coordinate
+// which can be used to specify a single kernel instance to break on. If this
+// is set then we add a callback to the breakpoint.
bool RenderScriptRuntime::PlaceBreakpointOnKernel(TargetSP target,
Stream &messages,
const char *name,
@@ -4076,7 +4065,7 @@ void RSModuleDescriptor::Dump(Stream &strm) const {
void RSGlobalDescriptor::Dump(Stream &strm) const {
strm.Indent(m_name.AsCString());
VariableList var_list;
- m_module->m_module->FindGlobalVariables(m_name, nullptr, true, 1U, var_list);
+ m_module->m_module->FindGlobalVariables(m_name, nullptr, 1U, var_list);
if (var_list.GetSize() == 1) {
auto var = var_list.GetVariableAtIndex(0);
auto type = var->GetType();
@@ -4270,8 +4259,8 @@ public:
};
// Matching a comma separated list of known words is fairly
- // straightforward with PCRE, but we're
- // using ERE, so we end up with a little ugliness...
+ // straightforward with PCRE, but we're using ERE, so we end up with a
+ // little ugliness...
RegularExpression::Match match(/* max_matches */ 5);
RegularExpression match_type_list(
llvm::StringRef("^([[:alpha:]]+)(,[[:alpha:]]+){0,4}$"));
@@ -4661,7 +4650,7 @@ public:
switch (short_option) {
case 'f':
- m_outfile.SetFile(option_arg, true);
+ m_outfile.SetFile(option_arg, true, FileSpec::Style::native);
if (m_outfile.Exists()) {
m_outfile.Clear();
err.SetErrorStringWithFormat("file already exists: '%s'",
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp
index fe4ae21a0c39..7786d686ad6a 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp
@@ -10,7 +10,6 @@
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/CommandReturnObject.h"
@@ -20,6 +19,7 @@
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp
index 439d372fadeb..e1f8ea648414 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp
@@ -46,18 +46,15 @@ bool isRSAPICall(llvm::Module &module, llvm::CallInst *call_inst) {
bool isRSLargeReturnCall(llvm::Module &module, llvm::CallInst *call_inst) {
// i686 and x86_64 returns for large vectors in the RenderScript API are not
- // handled as normal
- // register pairs, but as a hidden sret type. This is not reflected in the
- // debug info or mangled
- // symbol name, and the android ABI for x86 and x86_64, (as well as the
- // emulators) specifies there is
- // no AVX, so bcc generates an sret function because we cannot natively return
+ // handled as normal register pairs, but as a hidden sret type. This is not
+ // reflected in the debug info or mangled symbol name, and the android ABI
+ // for x86 and x86_64, (as well as the emulators) specifies there is no AVX,
+ // so bcc generates an sret function because we cannot natively return
// 256 bit vectors.
// This function simply checks whether a function has a > 128bit return type.
- // It is perhaps an
- // unreliable heuristic, and relies on bcc not generating AVX code, so if the
- // android ABI one day
- // provides for AVX, this function may go out of fashion.
+ // It is perhaps an unreliable heuristic, and relies on bcc not generating
+ // AVX code, so if the android ABI one day provides for AVX, this function
+ // may go out of fashion.
(void)module;
if (!call_inst || !call_inst->getCalledFunction())
return false;
@@ -88,12 +85,11 @@ bool isRSAllocationTyCallSite(llvm::Module &module, llvm::CallInst *call_inst) {
llvm::FunctionType *cloneToStructRetFnTy(llvm::CallInst *call_inst) {
// on x86 StructReturn functions return a pointer to the return value, rather
- // than the return
- // value itself [ref](http://www.agner.org/optimize/calling_conventions.pdf
- // section 6).
- // We create a return type by getting the pointer type of the old return type,
- // and inserting a new
- // initial argument of pointer type of the original return type.
+ // than the return value itself
+ // [ref](http://www.agner.org/optimize/calling_conventions.pdf section 6). We
+ // create a return type by getting the pointer type of the old return type,
+ // and inserting a new initial argument of pointer type of the original
+ // return type.
Log *log(
GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_EXPRESSIONS));
@@ -112,8 +108,7 @@ llvm::FunctionType *cloneToStructRetFnTy(llvm::CallInst *call_inst) {
orig_type->param_end()};
// This may not work if the function is somehow declared void as llvm is
- // strongly typed
- // and represents void* with i8*
+ // strongly typed and represents void* with i8*
assert(!orig_type->getReturnType()->isVoidTy() &&
"Cannot add StructRet attribute to void function");
llvm::PointerType *return_type_ptr_type =
@@ -126,8 +121,8 @@ llvm::FunctionType *cloneToStructRetFnTy(llvm::CallInst *call_inst) {
if (log)
log->Printf("%s - return type pointer type for StructRet clone @ '0x%p':\n",
__FUNCTION__, (void *)return_type_ptr_type);
- // put the the sret pointer argument in place at the beginning of the argument
- // list.
+ // put the sret pointer argument in place at the beginning of the
+ // argument list.
params.emplace(params.begin(), return_type_ptr_type);
assert(params.size() == num_params + 1);
return llvm::FunctionType::get(return_type_ptr_type, params,
@@ -157,11 +152,9 @@ bool findRSCallSites(llvm::Module &module,
bool fixupX86StructRetCalls(llvm::Module &module) {
bool changed = false;
- // changing a basic block while iterating over it seems to have some undefined
- // behaviour
- // going on so we find all RS callsites first, then fix them up after
- // consuming
- // the iterator.
+ // changing a basic block while iterating over it seems to have some
+ // undefined behaviour going on so we find all RS callsites first, then fix
+ // them up after consuming the iterator.
std::set<llvm::CallInst *> rs_callsites;
if (!findRSCallSites(module, rs_callsites, isRSLargeReturnCall))
return false;
@@ -180,8 +173,7 @@ bool fixupX86StructRetCalls(llvm::Module &module) {
// Allocate enough space to store the return value of the original function
// we pass a pointer to this allocation as the StructRet param, and then
- // copy its
- // value into the lldb return value
+ // copy its value into the lldb return value
const llvm::DataLayout &DL = module.getDataLayout();
llvm::AllocaInst *return_value_alloc = new llvm::AllocaInst(
func->getReturnType(), DL.getAllocaAddrSpace(), "var_vector_return_alloc",
@@ -222,19 +214,15 @@ bool fixupX86StructRetCalls(llvm::Module &module) {
bool fixupRSAllocationStructByValCalls(llvm::Module &module) {
// On x86_64, calls to functions in the RS runtime that take an
- // `rs_allocation` type argument
- // are actually handled as by-ref params by bcc, but appear to be passed by
- // value by lldb (the callsite all use
- // `struct byval`).
- // On x86_64 Linux, struct arguments are transferred in registers if the
- // struct size is no bigger than
- // 128bits [ref](http://www.agner.org/optimize/calling_conventions.pdf)
- // section 7.1 "Passing and returning objects"
- // otherwise passed on the stack.
- // an object of type `rs_allocation` is actually 256bits, so should be passed
- // on the stack. However, code generated
- // by bcc actually treats formal params of type `rs_allocation` as
- // `rs_allocation *` so we need to convert the
+ // `rs_allocation` type argument are actually handled as by-ref params by
+ // bcc, but appear to be passed by value by lldb (the callsite all use
+ // `struct byval`). On x86_64 Linux, struct arguments are transferred in
+ // registers if the struct size is no bigger than 128bits
+ // [ref](http://www.agner.org/optimize/calling_conventions.pdf) section 7.1
+ // "Passing and returning objects" otherwise passed on the stack. an object
+ // of type `rs_allocation` is actually 256bits, so should be passed on the
+ // stack. However, code generated by bcc actually treats formal params of
+ // type `rs_allocation` as `rs_allocation *` so we need to convert the
// calling convention to pass by reference, and remove any hint of byval from
// formal parameters.
bool changed = false;
diff --git a/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp b/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
index d7bef836d9d8..275f1fa2f70b 100644
--- a/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
+++ b/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
@@ -89,9 +89,9 @@ ObjectContainerBSDArchive::Object::Extract(const DataExtractor &data,
str.assign((const char *)data.GetData(&offset, 16), 16);
if (str.find("#1/") == 0) {
- // If the name is longer than 16 bytes, or contains an embedded space
- // then it will use this format where the length of the name is
- // here and the name characters are after this header.
+ // If the name is longer than 16 bytes, or contains an embedded space then
+ // it will use this format where the length of the name is here and the
+ // name characters are after this header.
ar_name_len = strtoul(str.c_str() + 3, &err, 10);
} else {
// Strip off any trailing spaces.
@@ -203,8 +203,8 @@ ObjectContainerBSDArchive::Archive::FindCachedArchive(
shared_ptr archive_sp;
Archive::Map &archive_map = Archive::GetArchiveCache();
Archive::Map::iterator pos = archive_map.find(file);
- // Don't cache a value for "archive_map.end()" below since we might
- // delete an archive entry...
+ // Don't cache a value for "archive_map.end()" below since we might delete an
+ // archive entry...
while (pos != archive_map.end() && pos->first == file) {
bool match = true;
if (arch.IsValid() &&
@@ -217,14 +217,13 @@ ObjectContainerBSDArchive::Archive::FindCachedArchive(
if (pos->second->GetModificationTime() == time) {
return pos->second;
} else {
- // We have a file at the same path with the same architecture
- // whose modification time doesn't match. It doesn't make sense
- // for us to continue to use this BSD archive since we cache only
- // the object info which consists of file time info and also the
- // file offset and file size of any contained objects. Since
- // this information is now out of date, we won't get the correct
- // information if we go and extract the file data, so we should
- // remove the old and outdated entry.
+ // We have a file at the same path with the same architecture whose
+ // modification time doesn't match. It doesn't make sense for us to
+ // continue to use this BSD archive since we cache only the object info
+ // which consists of file time info and also the file offset and file
+ // size of any contained objects. Since this information is now out of
+ // date, we won't get the correct information if we go and extract the
+ // file data, so we should remove the old and outdated entry.
archive_map.erase(pos);
pos = archive_map.find(file);
continue; // Continue to next iteration so we don't increment pos
@@ -295,9 +294,9 @@ ObjectContainer *ObjectContainerBSDArchive::CreateInstance(
return nullptr;
if (data_sp) {
- // We have data, which means this is the first 512 bytes of the file
- // Check to see if the magic bytes match and if they do, read the entire
- // table of contents for the archive and cache it
+ // We have data, which means this is the first 512 bytes of the file Check
+ // to see if the magic bytes match and if they do, read the entire table of
+ // contents for the archive and cache it
DataExtractor data;
data.SetData(data_sp, data_offset, length);
if (file && data_sp && ObjectContainerBSDArchive::MagicBytesMatch(data)) {
@@ -389,8 +388,8 @@ bool ObjectContainerBSDArchive::ParseHeader() {
m_file, module_sp->GetArchitecture(),
module_sp->GetModificationTime(), m_offset, m_data);
}
- // Clear the m_data that contains the entire archive
- // data and let our m_archive_sp hold onto the data.
+ // Clear the m_data that contains the entire archive data and let our
+ // m_archive_sp hold onto the data.
m_data.Clear();
}
}
@@ -453,9 +452,9 @@ size_t ObjectContainerBSDArchive::GetModuleSpecifications(
lldb::offset_t data_offset, lldb::offset_t file_offset,
lldb::offset_t file_size, lldb_private::ModuleSpecList &specs) {
- // We have data, which means this is the first 512 bytes of the file
- // Check to see if the magic bytes match and if they do, read the entire
- // table of contents for the archive and cache it
+ // We have data, which means this is the first 512 bytes of the file Check to
+ // see if the magic bytes match and if they do, read the entire table of
+ // contents for the archive and cache it
DataExtractor data;
data.SetData(data_sp, data_offset, data_sp->GetByteSize());
if (!file || !data_sp || !ObjectContainerBSDArchive::MagicBytesMatch(data))
@@ -505,8 +504,8 @@ size_t ObjectContainerBSDArchive::GetModuleSpecifications(
const size_t end_count = specs.GetSize();
size_t num_specs_added = end_count - initial_count;
if (set_archive_arch && num_specs_added > 0) {
- // The archive was created but we didn't have an architecture
- // so we need to set it
+ // The archive was created but we didn't have an architecture so we need to
+ // set it
for (size_t i = initial_count; i < end_count; ++i) {
ModuleSpec module_spec;
if (specs.GetModuleSpecAtIndex(i, module_spec)) {
diff --git a/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp b/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
index 0266bbe27e7d..4c48d641829a 100644
--- a/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
+++ b/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
@@ -44,8 +44,8 @@ ObjectContainer *ObjectContainerUniversalMachO::CreateInstance(
const lldb::ModuleSP &module_sp, DataBufferSP &data_sp,
lldb::offset_t data_offset, const FileSpec *file,
lldb::offset_t file_offset, lldb::offset_t length) {
- // We get data when we aren't trying to look for cached container information,
- // so only try and look for an architecture slice if we get data
+ // We get data when we aren't trying to look for cached container
+ // information, so only try and look for an architecture slice if we get data
if (data_sp) {
DataExtractor data;
data.SetData(data_sp, data_offset, length);
@@ -81,8 +81,8 @@ ObjectContainerUniversalMachO::~ObjectContainerUniversalMachO() {}
bool ObjectContainerUniversalMachO::ParseHeader() {
bool success = ParseHeader(m_data, m_header, m_fat_archs);
- // We no longer need any data, we parsed all we needed to parse
- // and cached it in m_header and m_fat_archs
+ // We no longer need any data, we parsed all we needed to parse and cached it
+ // in m_header and m_fat_archs
m_data.Clear();
return success;
}
@@ -92,8 +92,7 @@ bool ObjectContainerUniversalMachO::ParseHeader(
std::vector<llvm::MachO::fat_arch> &fat_archs) {
bool success = false;
// Store the file offset for this universal file as we could have a universal
- // .o file
- // in a BSD archive, or be contained in another kind of object.
+ // .o file in a BSD archive, or be contained in another kind of object.
// Universal mach-o files always have their headers in big endian.
lldb::offset_t offset = 0;
data.SetByteOrder(eByteOrderBig);
diff --git a/source/Plugins/ObjectFile/ELF/ELFHeader.cpp b/source/Plugins/ObjectFile/ELF/ELFHeader.cpp
index 39ea49208700..16cbb6e5753b 100644
--- a/source/Plugins/ObjectFile/ELF/ELFHeader.cpp
+++ b/source/Plugins/ObjectFile/ELF/ELFHeader.cpp
@@ -140,13 +140,12 @@ bool ELFHeader::Parse(lldb_private::DataExtractor &data,
if (data.GetU32(offset, &e_flags, 1) == NULL)
return false;
- // Read e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum and
- // e_shstrndx.
+ // Read e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum and e_shstrndx.
if (data.GetU16(offset, &e_ehsize, 6) == NULL)
return false;
- // Initialize e_phnum, e_shnum, and e_shstrndx with the values
- // read from the header.
+ // Initialize e_phnum, e_shnum, and e_shstrndx with the values read from the
+ // header.
e_phnum = e_phnum_hdr;
e_shnum = e_shnum_hdr;
e_shstrndx = e_shstrndx_hdr;
diff --git a/source/Plugins/ObjectFile/ELF/ELFHeader.h b/source/Plugins/ObjectFile/ELF/ELFHeader.h
index 4e2d3155ebb9..faaf8be99d68 100644
--- a/source/Plugins/ObjectFile/ELF/ELFHeader.h
+++ b/source/Plugins/ObjectFile/ELF/ELFHeader.h
@@ -8,14 +8,14 @@
//===----------------------------------------------------------------------===//
//
/// @file
-/// @brief Generic structures and typedefs for ELF files.
+/// Generic structures and typedefs for ELF files.
///
/// This file provides definitions for the various entities comprising an ELF
/// file. The structures are generic in the sense that they do not correspond
/// to the exact binary layout of an ELF, but can be used to hold the
/// information present in both 32 and 64 bit variants of the format. Each
-/// entity provides a \c Parse method which is capable of transparently reading
-/// both 32 and 64 bit instances of the object.
+/// entity provides a \c Parse method which is capable of transparently
+/// reading both 32 and 64 bit instances of the object.
//===----------------------------------------------------------------------===//
#ifndef liblldb_ELFHeader_h_
@@ -35,8 +35,9 @@ namespace elf {
//------------------------------------------------------------------------------
/// @name ELF type definitions.
///
-/// Types used to represent the various components of ELF structures. All types
-/// are signed or unsigned integral types wide enough to hold values from both
+/// Types used to represent the various components of ELF structures. All
+/// types are signed or unsigned integral types wide enough to hold values
+/// from both
/// 32 and 64 bit ELF variants.
//@{
typedef uint64_t elf_addr;
@@ -51,10 +52,10 @@ typedef int64_t elf_sxword;
//------------------------------------------------------------------------------
/// @class ELFHeader
-/// @brief Generic representation of an ELF file header.
+/// Generic representation of an ELF file header.
///
-/// This object is used to identify the general attributes on an ELF file and to
-/// locate additional sections within the file.
+/// This object is used to identify the general attributes on an ELF file and
+/// to locate additional sections within the file.
struct ELFHeader {
unsigned char e_ident[llvm::ELF::EI_NIDENT]; ///< ELF file identification.
elf_addr e_entry; ///< Virtual address program entry point.
@@ -118,9 +119,9 @@ struct ELFHeader {
bool HasHeaderExtension() const;
//--------------------------------------------------------------------------
- /// Parse an ELFHeader entry starting at position \p offset and
- /// update the data extractor with the address size and byte order
- /// attributes as defined by the header.
+ /// Parse an ELFHeader entry starting at position \p offset and update the
+ /// data extractor with the address size and byte order attributes as
+ /// defined by the header.
///
/// @param[in,out] data
/// The DataExtractor to read from. Updated with the address size and
@@ -157,8 +158,8 @@ struct ELFHeader {
private:
//--------------------------------------------------------------------------
- /// Parse an ELFHeader header extension entry. This method is called
- /// by Parse().
+ /// Parse an ELFHeader header extension entry. This method is called by
+ /// Parse().
///
/// @param[in] data
/// The DataExtractor to read from.
@@ -167,7 +168,7 @@ private:
//------------------------------------------------------------------------------
/// @class ELFSectionHeader
-/// @brief Generic representation of an ELF section header.
+/// Generic representation of an ELF section header.
struct ELFSectionHeader {
elf_word sh_name; ///< Section name string index.
elf_word sh_type; ///< Section type.
@@ -202,7 +203,7 @@ struct ELFSectionHeader {
//------------------------------------------------------------------------------
/// @class ELFProgramHeader
-/// @brief Generic representation of an ELF program header.
+/// Generic representation of an ELF program header.
struct ELFProgramHeader {
elf_word p_type; ///< Type of program segment.
elf_word p_flags; ///< Segment attributes.
@@ -235,7 +236,7 @@ struct ELFProgramHeader {
//------------------------------------------------------------------------------
/// @class ELFSymbol
-/// @brief Represents a symbol within an ELF symbol table.
+/// Represents a symbol within an ELF symbol table.
struct ELFSymbol {
elf_addr st_value; ///< Absolute or relocatable address.
elf_xword st_size; ///< Size of the symbol or zero.
@@ -288,7 +289,7 @@ struct ELFSymbol {
//------------------------------------------------------------------------------
/// @class ELFDynamic
-/// @brief Represents an entry in an ELF dynamic table.
+/// Represents an entry in an ELF dynamic table.
struct ELFDynamic {
elf_sxword d_tag; ///< Type of dynamic table entry.
union {
@@ -318,7 +319,7 @@ struct ELFDynamic {
//------------------------------------------------------------------------------
/// @class ELFRel
-/// @brief Represents a relocation entry with an implicit addend.
+/// Represents a relocation entry with an implicit addend.
struct ELFRel {
elf_addr r_offset; ///< Address of reference.
elf_xword r_info; ///< symbol index and type of relocation.
@@ -360,7 +361,7 @@ struct ELFRel {
//------------------------------------------------------------------------------
/// @class ELFRela
-/// @brief Represents a relocation entry with an explicit addend.
+/// Represents a relocation entry with an explicit addend.
struct ELFRela {
elf_addr r_offset; ///< Address of reference.
elf_xword r_info; ///< Symbol index and type of relocation.
diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 36027dde0432..8701908378f1 100644
--- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -113,7 +113,7 @@ const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS = 0x02;
//===----------------------------------------------------------------------===//
/// @class ELFRelocation
-/// @brief Generic wrapper for ELFRel and ELFRela.
+/// Generic wrapper for ELFRel and ELFRela.
///
/// This helper class allows us to parse both ELFRel and ELFRela relocation
/// entries in a generic manner.
@@ -240,11 +240,10 @@ bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) {
if (data.GetU32(offset, &n_namesz, 3) == NULL)
return false;
- // The name field is required to be nul-terminated, and n_namesz
- // includes the terminating nul in observed implementations (contrary
- // to the ELF-64 spec). A special case is needed for cores generated
- // by some older Linux versions, which write a note named "CORE"
- // without a nul terminator and n_namesz = 4.
+ // The name field is required to be nul-terminated, and n_namesz includes the
+ // terminating nul in observed implementations (contrary to the ELF-64 spec).
+ // A special case is needed for cores generated by some older Linux versions,
+ // which write a note named "CORE" without a nul terminator and n_namesz = 4.
if (n_namesz == 4) {
char buf[4];
if (data.ExtractBytes(*offset, 4, data.GetByteOrder(), buf) != 4)
@@ -295,7 +294,8 @@ static uint32_t mipsVariantFromElfFlags (const elf::ELFHeader &header) {
uint32_t arch_variant = ArchSpec::eMIPSSubType_unknown;
uint32_t fileclass = header.e_ident[EI_CLASS];
- // If there aren't any elf flags available (e.g core elf file) then return default
+ // If there aren't any elf flags available (e.g core elf file) then return
+ // default
// 32 or 64 bit arch (without any architecture revision) based on object file's class.
if (header.e_type == ET_CORE) {
switch (fileclass) {
@@ -549,8 +549,8 @@ uint32_t ObjectFileELF::CalculateELFNotesSegmentsCRC32(
DataExtractor segment_data;
if (segment_data.SetData(object_data, ph_offset, ph_size) != ph_size) {
- // The ELF program header contained incorrect data,
- // probably corefile is incomplete or corrupted.
+ // The ELF program header contained incorrect data, probably corefile
+ // is incomplete or corrupted.
break;
}
@@ -595,8 +595,8 @@ static const char *OSABIAsCString(unsigned char osabi_byte) {
//
// WARNING : This function is being deprecated
-// It's functionality has moved to ArchSpec::SetArchitecture
-// This function is only being kept to validate the move.
+// It's functionality has moved to ArchSpec::SetArchitecture This function is
+// only being kept to validate the move.
//
// TODO : Remove this function
static bool GetOsFromOSABI(unsigned char osabi_byte,
@@ -674,29 +674,16 @@ size_t ObjectFileELF::GetModuleSpecifications(
__FUNCTION__, file.GetPath().c_str());
}
- // In case there is header extension in the section #0, the header
- // we parsed above could have sentinel values for e_phnum, e_shnum,
- // and e_shstrndx. In this case we need to reparse the header
- // with a bigger data source to get the actual values.
- size_t section_header_end = header.e_shoff + header.e_shentsize;
- if (header.HasHeaderExtension() &&
- section_header_end > data_sp->GetByteSize()) {
- data_sp = MapFileData(file, section_header_end, file_offset);
- if (data_sp) {
- data.SetData(data_sp);
- lldb::offset_t header_offset = data_offset;
- header.Parse(data, &header_offset);
- }
- }
-
- // Try to get the UUID from the section list. Usually that's at the
- // end, so map the file in if we don't have it already.
- section_header_end =
- header.e_shoff + header.e_shnum * header.e_shentsize;
- if (section_header_end > data_sp->GetByteSize()) {
- data_sp = MapFileData(file, section_header_end, file_offset);
- if (data_sp)
- data.SetData(data_sp);
+ data_sp = MapFileData(file, -1, file_offset);
+ if (data_sp)
+ data.SetData(data_sp);
+ // In case there is header extension in the section #0, the header we
+ // parsed above could have sentinel values for e_phnum, e_shnum, and
+ // e_shstrndx. In this case we need to reparse the header with a
+ // bigger data source to get the actual values.
+ if (header.HasHeaderExtension()) {
+ lldb::offset_t header_offset = data_offset;
+ header.Parse(data, &header_offset);
}
uint32_t gnu_debuglink_crc = 0;
@@ -733,51 +720,27 @@ size_t ObjectFileELF::GetModuleSpecifications(
// contents crc32 would be too much of luxury. Thus we will need
// to fallback to something simpler.
if (header.e_type == llvm::ELF::ET_CORE) {
- size_t program_headers_end =
- header.e_phoff + header.e_phnum * header.e_phentsize;
- if (program_headers_end > data_sp->GetByteSize()) {
- data_sp = MapFileData(file, program_headers_end, file_offset);
- if (data_sp)
- data.SetData(data_sp);
- }
ProgramHeaderColl program_headers;
GetProgramHeaderInfo(program_headers, data, header);
- size_t segment_data_end = 0;
- for (ProgramHeaderCollConstIter I = program_headers.begin();
- I != program_headers.end(); ++I) {
- segment_data_end = std::max<unsigned long long>(
- I->p_offset + I->p_filesz, segment_data_end);
- }
-
- if (segment_data_end > data_sp->GetByteSize()) {
- data_sp = MapFileData(file, segment_data_end, file_offset);
- if (data_sp)
- data.SetData(data_sp);
- }
-
core_notes_crc =
CalculateELFNotesSegmentsCRC32(program_headers, data);
} else {
- // Need to map entire file into memory to calculate the crc.
- data_sp = MapFileData(file, -1, file_offset);
- if (data_sp) {
- data.SetData(data_sp);
- gnu_debuglink_crc = calc_gnu_debuglink_crc32(
- data.GetDataStart(), data.GetByteSize());
- }
+ gnu_debuglink_crc = calc_gnu_debuglink_crc32(
+ data.GetDataStart(), data.GetByteSize());
}
}
+ using u32le = llvm::support::ulittle32_t;
if (gnu_debuglink_crc) {
// Use 4 bytes of crc from the .gnu_debuglink section.
- uint32_t uuidt[4] = {gnu_debuglink_crc, 0, 0, 0};
- uuid.SetBytes(uuidt, sizeof(uuidt));
+ u32le data(gnu_debuglink_crc);
+ uuid = UUID::fromData(&data, sizeof(data));
} else if (core_notes_crc) {
// Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make
- // it look different form
- // .gnu_debuglink crc followed by 4 bytes of note segments crc.
- uint32_t uuidt[4] = {g_core_uuid_magic, core_notes_crc, 0, 0};
- uuid.SetBytes(uuidt, sizeof(uuidt));
+ // it look different form .gnu_debuglink crc followed by 4 bytes
+ // of note segments crc.
+ u32le data[] = {u32le(g_core_uuid_magic), u32le(core_notes_crc)};
+ uuid = UUID::fromData(data, sizeof(data));
}
}
@@ -861,21 +824,19 @@ bool ObjectFileELF::SetLoadAddress(Target &target, lldb::addr_t value,
size_t sect_idx = 0;
for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
- // Iterate through the object file sections to find all
- // of the sections that have SHF_ALLOC in their flag bits.
+ // Iterate through the object file sections to find all of the sections
+ // that have SHF_ALLOC in their flag bits.
SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
if (section_sp && section_sp->Test(SHF_ALLOC)) {
lldb::addr_t load_addr = section_sp->GetFileAddress();
// We don't want to update the load address of a section with type
// eSectionTypeAbsoluteAddress as they already have the absolute load
- // address
- // already specified
+ // address already specified
if (section_sp->GetType() != eSectionTypeAbsoluteAddress)
load_addr += value;
// On 32-bit systems the load address have to fit into 4 bytes. The
- // rest of
- // the bytes are the overflow from the addition.
+ // rest of the bytes are the overflow from the addition.
if (GetAddressByteSize() == 4)
load_addr &= 0xFFFFFFFF;
@@ -905,24 +866,23 @@ uint32_t ObjectFileELF::GetAddressByteSize() const {
AddressClass ObjectFileELF::GetAddressClass(addr_t file_addr) {
Symtab *symtab = GetSymtab();
if (!symtab)
- return eAddressClassUnknown;
+ return AddressClass::eUnknown;
- // The address class is determined based on the symtab. Ask it from the object
- // file what
- // contains the symtab information.
+ // The address class is determined based on the symtab. Ask it from the
+ // object file what contains the symtab information.
ObjectFile *symtab_objfile = symtab->GetObjectFile();
if (symtab_objfile != nullptr && symtab_objfile != this)
return symtab_objfile->GetAddressClass(file_addr);
auto res = ObjectFile::GetAddressClass(file_addr);
- if (res != eAddressClassCode)
+ if (res != AddressClass::eCode)
return res;
auto ub = m_address_class_map.upper_bound(file_addr);
if (ub == m_address_class_map.begin()) {
- // No entry in the address class map before the address. Return
- // default address class for an address in a code section.
- return eAddressClassCode;
+ // No entry in the address class map before the address. Return default
+ // address class for an address in a code section.
+ return AddressClass::eCode;
}
// Move iterator to the address class entry preceding address
@@ -950,6 +910,7 @@ bool ObjectFileELF::GetUUID(lldb_private::UUID *uuid) {
if (!ParseSectionHeaders() && GetType() != ObjectFile::eTypeCoreFile)
return false;
+ using u32le = llvm::support::ulittle32_t;
if (m_uuid.IsValid()) {
// We have the full build id uuid.
*uuid = m_uuid;
@@ -963,11 +924,11 @@ bool ObjectFileELF::GetUUID(lldb_private::UUID *uuid) {
core_notes_crc = CalculateELFNotesSegmentsCRC32(m_program_headers, m_data);
if (core_notes_crc) {
- // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make it
- // look different form .gnu_debuglink crc - followed by 4 bytes of note
+ // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make it look
+ // different form .gnu_debuglink crc - followed by 4 bytes of note
// segments crc.
- uint32_t uuidt[4] = {g_core_uuid_magic, core_notes_crc, 0, 0};
- m_uuid.SetBytes(uuidt, sizeof(uuidt));
+ u32le data[] = {u32le(g_core_uuid_magic), u32le(core_notes_crc)};
+ m_uuid = UUID::fromData(data, sizeof(data));
}
} else {
if (!m_gnu_debuglink_crc)
@@ -975,8 +936,8 @@ bool ObjectFileELF::GetUUID(lldb_private::UUID *uuid) {
calc_gnu_debuglink_crc32(m_data.GetDataStart(), m_data.GetByteSize());
if (m_gnu_debuglink_crc) {
// Use 4 bytes of crc from the .gnu_debuglink section.
- uint32_t uuidt[4] = {m_gnu_debuglink_crc, 0, 0, 0};
- m_uuid.SetBytes(uuidt, sizeof(uuidt));
+ u32le data(m_gnu_debuglink_crc);
+ m_uuid = UUID::fromData(&data, sizeof(data));
}
}
@@ -1034,8 +995,8 @@ Address ObjectFileELF::GetImageInfoAddress(Target *target) {
ELFDynamic &symbol = m_dynamic_symbols[i];
if (symbol.d_tag == DT_DEBUG) {
- // Compute the offset as the number of previous entries plus the
- // size of d_tag.
+ // Compute the offset as the number of previous entries plus the size of
+ // d_tag.
addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
return Address(dynsym_section_sp, offset);
}
@@ -1314,18 +1275,16 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
// Only bother processing this if we don't already have the uuid set.
if (!uuid.IsValid()) {
// 16 bytes is UUID|MD5, 20 bytes is SHA1. Other linkers may produce a
- // build-id of a different
- // length. Accept it as long as it's at least 4 bytes as it will be
- // better than our own crc32.
- if (note.n_descsz >= 4 && note.n_descsz <= 20) {
- uint8_t uuidbuf[20];
- if (data.GetU8(&offset, &uuidbuf, note.n_descsz) == nullptr) {
+ // build-id of a different length. Accept it as long as it's at least
+ // 4 bytes as it will be better than our own crc32.
+ if (note.n_descsz >= 4) {
+ if (const uint8_t *buf = data.PeekData(offset, note.n_descsz)) {
+ // Save the build id as the UUID for the module.
+ uuid = UUID::fromData(buf, note.n_descsz);
+ } else {
error.SetErrorString("failed to read GNU_BUILD_ID note payload");
return error;
}
-
- // Save the build id as the UUID for the module.
- uuid.SetBytes(uuidbuf, note.n_descsz);
}
}
break;
@@ -1368,8 +1327,8 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::CSR);
// TODO At some point the description string could be processed.
- // It could provide a steer towards the kalimba variant which
- // this ELF targets.
+ // It could provide a steer towards the kalimba variant which this ELF
+ // targets.
if (note.n_descsz) {
const char *cstr =
data.GetCStr(&offset, llvm::alignTo(note.n_descsz, 4));
@@ -1384,36 +1343,28 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
// register info
arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
} else if (note.n_name == LLDB_NT_OWNER_CORE) {
- // Parse the NT_FILE to look for stuff in paths to shared libraries
- // As the contents look like this in a 64 bit ELF core file:
- // count = 0x000000000000000a (10)
- // page_size = 0x0000000000001000 (4096)
- // Index start end file_ofs path
- // ===== ------------------ ------------------ ------------------
- // -------------------------------------
- // [ 0] 0x0000000000400000 0x0000000000401000 0x0000000000000000
- // /tmp/a.out
- // [ 1] 0x0000000000600000 0x0000000000601000 0x0000000000000000
- // /tmp/a.out
- // [ 2] 0x0000000000601000 0x0000000000602000 0x0000000000000001
- // /tmp/a.out
+ // Parse the NT_FILE to look for stuff in paths to shared libraries As
+ // the contents look like this in a 64 bit ELF core file: count =
+ // 0x000000000000000a (10) page_size = 0x0000000000001000 (4096) Index
+ // start end file_ofs path =====
+ // ------------------ ------------------ ------------------
+ // ------------------------------------- [ 0] 0x0000000000400000
+ // 0x0000000000401000 0x0000000000000000 /tmp/a.out [ 1]
+ // 0x0000000000600000 0x0000000000601000 0x0000000000000000 /tmp/a.out [
+ // 2] 0x0000000000601000 0x0000000000602000 0x0000000000000001 /tmp/a.out
// [ 3] 0x00007fa79c9ed000 0x00007fa79cba8000 0x0000000000000000
- // /lib/x86_64-linux-gnu/libc-2.19.so
- // [ 4] 0x00007fa79cba8000 0x00007fa79cda7000 0x00000000000001bb
- // /lib/x86_64-linux-gnu/libc-2.19.so
- // [ 5] 0x00007fa79cda7000 0x00007fa79cdab000 0x00000000000001ba
- // /lib/x86_64-linux-gnu/libc-2.19.so
- // [ 6] 0x00007fa79cdab000 0x00007fa79cdad000 0x00000000000001be
- // /lib/x86_64-linux-gnu/libc-2.19.so
- // [ 7] 0x00007fa79cdb2000 0x00007fa79cdd5000 0x0000000000000000
- // /lib/x86_64-linux-gnu/ld-2.19.so
- // [ 8] 0x00007fa79cfd4000 0x00007fa79cfd5000 0x0000000000000022
- // /lib/x86_64-linux-gnu/ld-2.19.so
- // [ 9] 0x00007fa79cfd5000 0x00007fa79cfd6000 0x0000000000000023
- // /lib/x86_64-linux-gnu/ld-2.19.so
- // In the 32 bit ELFs the count, page_size, start, end, file_ofs are
- // uint32_t
- // For reference: see readelf source code (in binutils).
+ // /lib/x86_64-linux-gnu/libc-2.19.so [ 4] 0x00007fa79cba8000
+ // 0x00007fa79cda7000 0x00000000000001bb /lib/x86_64-linux-
+ // gnu/libc-2.19.so [ 5] 0x00007fa79cda7000 0x00007fa79cdab000
+ // 0x00000000000001ba /lib/x86_64-linux-gnu/libc-2.19.so [ 6]
+ // 0x00007fa79cdab000 0x00007fa79cdad000 0x00000000000001be /lib/x86_64
+ // -linux-gnu/libc-2.19.so [ 7] 0x00007fa79cdb2000 0x00007fa79cdd5000
+ // 0x0000000000000000 /lib/x86_64-linux-gnu/ld-2.19.so [ 8]
+ // 0x00007fa79cfd4000 0x00007fa79cfd5000 0x0000000000000022 /lib/x86_64
+ // -linux-gnu/ld-2.19.so [ 9] 0x00007fa79cfd5000 0x00007fa79cfd6000
+ // 0x0000000000000023 /lib/x86_64-linux-gnu/ld-2.19.so In the 32 bit ELFs
+ // the count, page_size, start, end, file_ofs are uint32_t For reference:
+ // see readelf source code (in binutils).
if (note.n_type == NT_FILE) {
uint64_t count = data.GetAddress(&offset);
const char *cstr;
@@ -1437,15 +1388,14 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
}
if (arch_spec.IsMIPS() &&
arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS)
- // In case of MIPSR6, the LLDB_NT_OWNER_GNU note is missing
- // for some cases (e.g. compile with -nostdlib)
- // Hence set OS to Linux
+ // In case of MIPSR6, the LLDB_NT_OWNER_GNU note is missing for some
+ // cases (e.g. compile with -nostdlib) Hence set OS to Linux
arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
}
}
- // Calculate the offset of the next note just in case "offset" has been used
- // to poke at the contents of the note data
+ // Calculate the offset of the next note just in case "offset" has been
+ // used to poke at the contents of the note data
offset = note_offset + note.GetByteSize();
}
@@ -1545,13 +1495,12 @@ size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
arch_spec.SetArchitecture(eArchTypeELF, header.e_machine, sub_type,
header.e_ident[EI_OSABI]);
- // Validate if it is ok to remove GetOsFromOSABI.
- // Note, that now the OS is determined based on EI_OSABI flag and
- // the info extracted from ELF notes (see RefineModuleDetailsFromNote).
- // However in some cases that still might be not enough: for example
- // a shared library might not have any notes at all
- // and have EI_OSABI flag set to System V,
- // as result the OS will be set to UnknownOS.
+ // Validate if it is ok to remove GetOsFromOSABI. Note, that now the OS is
+ // determined based on EI_OSABI flag and the info extracted from ELF notes
+ // (see RefineModuleDetailsFromNote). However in some cases that still
+ // might be not enough: for example a shared library might not have any
+ // notes at all and have EI_OSABI flag set to System V, as result the OS
+ // will be set to UnknownOS.
GetOsFromOSABI(header.e_ident[EI_OSABI], ostype);
spec_ostype = arch_spec.GetTriple().getOS();
assert(spec_ostype == ostype);
@@ -1842,6 +1791,7 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
static ConstString g_sect_name_dwarf_debug_loc(".debug_loc");
static ConstString g_sect_name_dwarf_debug_macinfo(".debug_macinfo");
static ConstString g_sect_name_dwarf_debug_macro(".debug_macro");
+ static ConstString g_sect_name_dwarf_debug_names(".debug_names");
static ConstString g_sect_name_dwarf_debug_pubnames(".debug_pubnames");
static ConstString g_sect_name_dwarf_debug_pubtypes(".debug_pubtypes");
static ConstString g_sect_name_dwarf_debug_ranges(".debug_ranges");
@@ -1857,10 +1807,12 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
static ConstString g_sect_name_dwarf_debug_str_dwo(".debug_str.dwo");
static ConstString g_sect_name_dwarf_debug_str_offsets_dwo(
".debug_str_offsets.dwo");
+ static ConstString g_sect_name_dwarf_debug_types(".debug_types");
static ConstString g_sect_name_eh_frame(".eh_frame");
static ConstString g_sect_name_arm_exidx(".ARM.exidx");
static ConstString g_sect_name_arm_extab(".ARM.extab");
static ConstString g_sect_name_go_symtab(".gosymtab");
+ static ConstString g_sect_name_dwarf_gnu_debugaltlink(".gnu_debugaltlink");
SectionType sect_type = eSectionTypeOther;
@@ -1881,23 +1833,19 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
}
// .debug_abbrev – Abbreviations used in the .debug_info section
// .debug_aranges – Lookup table for mapping addresses to compilation
- // units
- // .debug_frame – Call frame information
- // .debug_info – The core DWARF information section
- // .debug_line – Line number information
+ // units .debug_frame – Call frame information .debug_info – The core
+ // DWARF information section .debug_line – Line number information
// .debug_loc – Location lists used in DW_AT_location attributes
- // .debug_macinfo – Macro information
- // .debug_pubnames – Lookup table for mapping object and function names to
- // compilation units
+ // .debug_macinfo – Macro information .debug_pubnames – Lookup table
+ // for mapping object and function names to compilation units
// .debug_pubtypes – Lookup table for mapping type names to compilation
- // units
- // .debug_ranges – Address ranges used in DW_AT_ranges attributes
- // .debug_str – String table used in .debug_info
- // MISSING? .gnu_debugdata - "mini debuginfo / MiniDebugInfo" section,
- // http://sourceware.org/gdb/onlinedocs/gdb/MiniDebugInfo.html
- // MISSING? .debug-index -
- // http://src.chromium.org/viewvc/chrome/trunk/src/build/gdb-add-index?pathrev=144644
- // MISSING? .debug_types - Type descriptions from DWARF 4? See
+ // units .debug_ranges – Address ranges used in DW_AT_ranges attributes
+ // .debug_str – String table used in .debug_info MISSING?
+ // .gnu_debugdata - "mini debuginfo / MiniDebugInfo" section,
+ // http://sourceware.org/gdb/onlinedocs/gdb/MiniDebugInfo.html MISSING?
+ // .debug-index - http://src.chromium.org/viewvc/chrome/trunk/src/build
+ // /gdb-add-index?pathrev=144644 MISSING? .debug_types - Type
+ // descriptions from DWARF 4? See
// http://gcc.gnu.org/wiki/DwarfSeparateTypeInfo
else if (name == g_sect_name_dwarf_debug_abbrev)
sect_type = eSectionTypeDWARFDebugAbbrev;
@@ -1919,6 +1867,8 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
sect_type = eSectionTypeDWARFDebugMacInfo;
else if (name == g_sect_name_dwarf_debug_macro)
sect_type = eSectionTypeDWARFDebugMacro;
+ else if (name == g_sect_name_dwarf_debug_names)
+ sect_type = eSectionTypeDWARFDebugNames;
else if (name == g_sect_name_dwarf_debug_pubnames)
sect_type = eSectionTypeDWARFDebugPubNames;
else if (name == g_sect_name_dwarf_debug_pubtypes)
@@ -1927,6 +1877,8 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
sect_type = eSectionTypeDWARFDebugRanges;
else if (name == g_sect_name_dwarf_debug_str)
sect_type = eSectionTypeDWARFDebugStr;
+ else if (name == g_sect_name_dwarf_debug_types)
+ sect_type = eSectionTypeDWARFDebugTypes;
else if (name == g_sect_name_dwarf_debug_str_offsets)
sect_type = eSectionTypeDWARFDebugStrOffsets;
else if (name == g_sect_name_dwarf_debug_abbrev_dwo)
@@ -1951,6 +1903,8 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
sect_type = eSectionTypeARMextab;
else if (name == g_sect_name_go_symtab)
sect_type = eSectionTypeGoSymtab;
+ else if (name == g_sect_name_dwarf_gnu_debugaltlink)
+ sect_type = eSectionTypeDWARFGNUDebugAltLink;
const uint32_t permissions =
((header.sh_flags & SHF_ALLOC) ? ePermissionsReadable : 0u) |
@@ -1978,13 +1932,21 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
if (eSectionTypeOther == sect_type) {
// the kalimba toolchain assumes that ELF section names are free-form.
- // It does
- // support linkscripts which (can) give rise to various arbitrarily
- // named
- // sections being "Code" or "Data".
+ // It does support linkscripts which (can) give rise to various
+ // arbitrarily named sections being "Code" or "Data".
sect_type = kalimbaSectionType(m_header, header);
}
+ // In common case ELF code section can have arbitrary name (for example,
+ // we can specify it using section attribute for particular function) so
+ // assume that section is a code section if it has SHF_EXECINSTR flag set
+ // and has SHT_PROGBITS type.
+ if (eSectionTypeOther == sect_type &&
+ llvm::ELF::SHT_PROGBITS == header.sh_type &&
+ (header.sh_flags & SHF_EXECINSTR)) {
+ sect_type = eSectionTypeCode;
+ }
+
const uint32_t target_bytes_size =
(eSectionTypeData == sect_type || eSectionTypeZeroFill == sect_type)
? m_arch_spec.GetDataByteSize()
@@ -2024,46 +1986,16 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
}
}
- if (m_sections_ap.get()) {
- if (GetType() == eTypeDebugInfo) {
- static const SectionType g_sections[] = {
- eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr,
- eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugCuIndex,
- eSectionTypeDWARFDebugFrame, eSectionTypeDWARFDebugInfo,
- eSectionTypeDWARFDebugLine, eSectionTypeDWARFDebugLoc,
- eSectionTypeDWARFDebugMacInfo, eSectionTypeDWARFDebugPubNames,
- eSectionTypeDWARFDebugPubTypes, eSectionTypeDWARFDebugRanges,
- eSectionTypeDWARFDebugStr, eSectionTypeDWARFDebugStrOffsets,
- eSectionTypeELFSymbolTable,
- };
- SectionList *elf_section_list = m_sections_ap.get();
- for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]);
- ++idx) {
- SectionType section_type = g_sections[idx];
- SectionSP section_sp(
- elf_section_list->FindSectionByType(section_type, true));
- if (section_sp) {
- SectionSP module_section_sp(
- unified_section_list.FindSectionByType(section_type, true));
- if (module_section_sp)
- unified_section_list.ReplaceSection(module_section_sp->GetID(),
- section_sp);
- else
- unified_section_list.AddSection(section_sp);
- }
- }
- } else {
- unified_section_list = *m_sections_ap;
- }
- }
+ // For eTypeDebugInfo files, the Symbol Vendor will take care of updating the
+ // unified section list.
+ if (GetType() != eTypeDebugInfo)
+ unified_section_list = *m_sections_ap;
}
// Find the arm/aarch64 mapping symbol character in the given symbol name.
-// Mapping symbols have the
-// form of "$<char>[.<any>]*". Additionally we recognize cases when the mapping
-// symbol prefixed by
-// an arbitrary string because if a symbol prefix added to each symbol in the
-// object file with
+// Mapping symbols have the form of "$<char>[.<any>]*". Additionally we
+// recognize cases when the mapping symbol prefixed by an arbitrary string
+// because if a symbol prefix added to each symbol in the object file with
// objcopy then the mapping symbols are also prefixed.
static char FindArmAarch64MappingSymbol(const char *symbol_name) {
if (!symbol_name)
@@ -2105,22 +2037,18 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
static ConstString opd_section_name(".opd"); // For ppc64
// On Android the oatdata and the oatexec symbols in the oat and odex files
- // covers the full
- // .text section what causes issues with displaying unusable symbol name to
- // the user and very
- // slow unwinding speed because the instruction emulation based unwind plans
- // try to emulate all
- // instructions in these symbols. Don't add these symbols to the symbol list
- // as they have no
- // use for the debugger and they are causing a lot of trouble.
- // Filtering can't be restricted to Android because this special object file
- // don't contain the
- // note section specifying the environment to Android but the custom extension
- // and file name
- // makes it highly unlikely that this will collide with anything else.
+ // covers the full .text section what causes issues with displaying unusable
+ // symbol name to the user and very slow unwinding speed because the
+ // instruction emulation based unwind plans try to emulate all instructions
+ // in these symbols. Don't add these symbols to the symbol list as they have
+ // no use for the debugger and they are causing a lot of trouble. Filtering
+ // can't be restricted to Android because this special object file don't
+ // contain the note section specifying the environment to Android but the
+ // custom extension and file name makes it highly unlikely that this will
+ // collide with anything else.
ConstString file_extension = m_file.GetFileNameExtension();
- bool skip_oatdata_oatexec = file_extension == ConstString("oat") ||
- file_extension == ConstString("odex");
+ bool skip_oatdata_oatexec = file_extension == ConstString(".oat") ||
+ file_extension == ConstString(".odex");
ArchSpec arch;
GetArchitecture(arch);
@@ -2129,8 +2057,8 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
module_sp ? module_sp->GetSectionList() : nullptr;
// Local cache to avoid doing a FindSectionByName for each symbol. The "const
- // char*" key must
- // came from a ConstString object so they can be compared by pointer
+ // char*" key must came from a ConstString object so they can be compared by
+ // pointer
std::unordered_map<const char *, lldb::SectionSP> section_name_to_section;
unsigned i;
@@ -2148,8 +2076,7 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
continue;
// Skipping oatdata and oatexec sections if it is requested. See details
- // above the
- // definition of skip_oatdata_oatexec for the reasons.
+ // above the definition of skip_oatdata_oatexec for the reasons.
if (skip_oatdata_oatexec && (::strcmp(symbol_name, "oatdata") == 0 ||
::strcmp(symbol_name, "oatexec") == 0))
continue;
@@ -2180,8 +2107,8 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
break;
case STT_OBJECT:
- // The symbol is associated with a data object, such as a variable,
- // an array, etc.
+ // The symbol is associated with a data object, such as a variable, an
+ // array, etc.
symbol_type = eSymbolTypeData;
break;
@@ -2192,13 +2119,13 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
case STT_SECTION:
// The symbol is associated with a section. Symbol table entries of
- // this type exist primarily for relocation and normally have
- // STB_LOCAL binding.
+ // this type exist primarily for relocation and normally have STB_LOCAL
+ // binding.
break;
case STT_FILE:
- // Conventionally, the symbol's name gives the name of the source
- // file associated with the object file. A file symbol has STB_LOCAL
+ // Conventionally, the symbol's name gives the name of the source file
+ // associated with the object file. A file symbol has STB_LOCAL
// binding, its section index is SHN_ABS, and it precedes the other
// STB_LOCAL symbols for the file, if it is present.
symbol_type = eSymbolTypeSourceFile;
@@ -2240,18 +2167,18 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
switch (mapping_symbol) {
case 'a':
// $a[.<any>]* - marks an ARM instruction sequence
- m_address_class_map[symbol.st_value] = eAddressClassCode;
+ m_address_class_map[symbol.st_value] = AddressClass::eCode;
break;
case 'b':
case 't':
// $b[.<any>]* - marks a THUMB BL instruction sequence
// $t[.<any>]* - marks a THUMB instruction sequence
m_address_class_map[symbol.st_value] =
- eAddressClassCodeAlternateISA;
+ AddressClass::eCodeAlternateISA;
break;
case 'd':
// $d[.<any>]* - marks a data item sequence (e.g. lit pool)
- m_address_class_map[symbol.st_value] = eAddressClassData;
+ m_address_class_map[symbol.st_value] = AddressClass::eData;
break;
}
}
@@ -2265,11 +2192,11 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
switch (mapping_symbol) {
case 'x':
// $x[.<any>]* - marks an A64 instruction sequence
- m_address_class_map[symbol.st_value] = eAddressClassCode;
+ m_address_class_map[symbol.st_value] = AddressClass::eCode;
break;
case 'd':
// $d[.<any>]* - marks a data item sequence (e.g. lit pool)
- m_address_class_map[symbol.st_value] = eAddressClassData;
+ m_address_class_map[symbol.st_value] = AddressClass::eData;
break;
}
}
@@ -2281,18 +2208,17 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
if (arch.GetMachine() == llvm::Triple::arm) {
if (symbol_type == eSymbolTypeCode) {
if (symbol.st_value & 1) {
- // Subtracting 1 from the address effectively unsets
- // the low order bit, which results in the address
- // actually pointing to the beginning of the symbol.
- // This delta will be used below in conjunction with
- // symbol.st_value to produce the final symbol_value
- // that we store in the symtab.
+ // Subtracting 1 from the address effectively unsets the low order
+ // bit, which results in the address actually pointing to the
+ // beginning of the symbol. This delta will be used below in
+ // conjunction with symbol.st_value to produce the final
+ // symbol_value that we store in the symtab.
symbol_value_offset = -1;
m_address_class_map[symbol.st_value ^ 1] =
- eAddressClassCodeAlternateISA;
+ AddressClass::eCodeAlternateISA;
} else {
// This address is ARM
- m_address_class_map[symbol.st_value] = eAddressClassCode;
+ m_address_class_map[symbol.st_value] = AddressClass::eCode;
}
}
}
@@ -2317,36 +2243,32 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
llvm_arch == llvm::Triple::mips64 ||
llvm_arch == llvm::Triple::mips64el) {
if (IS_MICROMIPS(symbol.st_other))
- m_address_class_map[symbol.st_value] = eAddressClassCodeAlternateISA;
+ m_address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA;
else if ((symbol.st_value & 1) && (symbol_type == eSymbolTypeCode)) {
symbol.st_value = symbol.st_value & (~1ull);
- m_address_class_map[symbol.st_value] = eAddressClassCodeAlternateISA;
+ m_address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA;
} else {
if (symbol_type == eSymbolTypeCode)
- m_address_class_map[symbol.st_value] = eAddressClassCode;
+ m_address_class_map[symbol.st_value] = AddressClass::eCode;
else if (symbol_type == eSymbolTypeData)
- m_address_class_map[symbol.st_value] = eAddressClassData;
+ m_address_class_map[symbol.st_value] = AddressClass::eData;
else
- m_address_class_map[symbol.st_value] = eAddressClassUnknown;
+ m_address_class_map[symbol.st_value] = AddressClass::eUnknown;
}
}
}
// symbol_value_offset may contain 0 for ARM symbols or -1 for THUMB
- // symbols. See above for
- // more details.
+ // symbols. See above for more details.
uint64_t symbol_value = symbol.st_value + symbol_value_offset;
if (symbol_section_sp == nullptr && section_idx == SHN_ABS &&
symbol.st_size != 0) {
// We don't have a section for a symbol with non-zero size. Create a new
- // section for it
- // so the address range covered by the symbol is also covered by the
- // module (represented
- // through the section list). It is needed so module lookup for the
- // addresses covered
- // by this symbol will be successfull. This case happens for absolute
- // symbols.
+ // section for it so the address range covered by the symbol is also
+ // covered by the module (represented through the section list). It is
+ // needed so module lookup for the addresses covered by this symbol will
+ // be successfull. This case happens for absolute symbols.
ConstString fake_section_name(std::string(".absolute.") + symbol_name);
symbol_section_sp =
std::make_shared<Section>(module_sp, this, SHN_ABS, fake_section_name,
@@ -2389,8 +2311,7 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
Mangled mangled(ConstString(symbol_bare), is_mangled);
// Now append the suffix back to mangled and unmangled names. Only do it if
- // the
- // demangling was successful (string is not empty).
+ // the demangling was successful (string is not empty).
if (has_suffix) {
llvm::StringRef suffix = symbol_ref.substr(version_pos);
@@ -2406,12 +2327,10 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
}
// In ELF all symbol should have a valid size but it is not true for some
- // function symbols
- // coming from hand written assembly. As none of the function symbol should
- // have 0 size we
- // try to calculate the size for these symbols in the symtab with saying
- // that their original
- // size is not valid.
+ // function symbols coming from hand written assembly. As none of the
+ // function symbol should have 0 size we try to calculate the size for
+ // these symbols in the symtab with saying that their original size is not
+ // valid.
bool symbol_size_valid =
symbol.st_size != 0 || symbol.getType() != STT_FUNC;
@@ -2440,8 +2359,7 @@ unsigned ObjectFileELF::ParseSymbolTable(Symtab *symbol_table,
lldb_private::Section *symtab) {
if (symtab->GetObjectFile() != this) {
// If the symbol table section is owned by a different object file, have it
- // do the
- // parsing.
+ // do the parsing.
ObjectFileELF *obj_file_elf =
static_cast<ObjectFileELF *>(symtab->GetObjectFile());
return obj_file_elf->ParseSymbolTable(symbol_table, start_id, symtab);
@@ -2457,8 +2375,8 @@ unsigned ObjectFileELF::ParseSymbolTable(Symtab *symbol_table,
assert(symtab_hdr->sh_type == SHT_SYMTAB ||
symtab_hdr->sh_type == SHT_DYNSYM);
- // sh_link: section header index of associated string table.
- // Section ID's are ones based.
+ // sh_link: section header index of associated string table. Section ID's are
+ // ones based.
user_id_t strtab_id = symtab_hdr->sh_link + 1;
Section *strtab = section_list->FindSectionByID(strtab_id).get();
@@ -2543,19 +2461,17 @@ unsigned ObjectFileELF::PLTRelocationType() {
return 0;
}
-// Returns the size of the normal plt entries and the offset of the first normal
-// plt entry. The
-// 0th entry in the plt table is usually a resolution entry which have different
-// size in some
-// architectures then the rest of the plt entries.
+// Returns the size of the normal plt entries and the offset of the first
+// normal plt entry. The 0th entry in the plt table is usually a resolution
+// entry which have different size in some architectures then the rest of the
+// plt entries.
static std::pair<uint64_t, uint64_t>
GetPltEntrySizeAndOffset(const ELFSectionHeader *rel_hdr,
const ELFSectionHeader *plt_hdr) {
const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
- // Clang 3.3 sets entsize to 4 for 32-bit binaries, but the plt entries are 16
- // bytes.
- // So round the entsize up by the alignment if addralign is set.
+ // Clang 3.3 sets entsize to 4 for 32-bit binaries, but the plt entries are
+ // 16 bytes. So round the entsize up by the alignment if addralign is set.
elf_xword plt_entsize =
plt_hdr->sh_addralign
? llvm::alignTo(plt_hdr->sh_entsize, plt_hdr->sh_addralign)
@@ -2567,12 +2483,10 @@ GetPltEntrySizeAndOffset(const ELFSectionHeader *rel_hdr,
// just in case.
if (plt_entsize <= 4) {
// The linker haven't set the plt_hdr->sh_entsize field. Try to guess the
- // size of the plt
- // entries based on the number of entries and the size of the plt section
- // with the
- // assumption that the size of the 0th entry is at least as big as the size
- // of the normal
- // entries and it isn't much bigger then that.
+ // size of the plt entries based on the number of entries and the size of
+ // the plt section with the assumption that the size of the 0th entry is at
+ // least as big as the size of the normal entries and it isn't much bigger
+ // then that.
if (plt_hdr->sh_addralign)
plt_entsize = plt_hdr->sh_size / plt_hdr->sh_addralign /
(num_relocations + 1) * plt_hdr->sh_addralign;
@@ -2865,8 +2779,7 @@ Symtab *ObjectFileELF::GetSymtab() {
return NULL;
// We always want to use the main object file so we (hopefully) only have one
- // cached copy
- // of our symtab, dynamic sections, etc.
+ // cached copy of our symtab, dynamic sections, etc.
ObjectFile *module_obj_file = module_sp->GetObjectFile();
if (module_obj_file && module_obj_file != this)
return module_obj_file->GetSymtab();
@@ -2881,18 +2794,15 @@ Symtab *ObjectFileELF::GetSymtab() {
// Sharable objects and dynamic executables usually have 2 distinct symbol
// tables, one named ".symtab", and the other ".dynsym". The dynsym is a
- // smaller
- // version of the symtab that only contains global symbols. The information
- // found
- // in the dynsym is therefore also found in the symtab, while the reverse is
- // not
- // necessarily true.
+ // smaller version of the symtab that only contains global symbols. The
+ // information found in the dynsym is therefore also found in the symtab,
+ // while the reverse is not necessarily true.
Section *symtab =
section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get();
if (!symtab) {
// The symtab section is non-allocable and can be stripped, so if it
- // doesn't exist
- // then use the dynsym section which should always be there.
+ // doesn't exist then use the dynsym section which should always be
+ // there.
symtab =
section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
.get();
@@ -2939,8 +2849,7 @@ Symtab *ObjectFileELF::GetSymtab() {
}
// If we still don't have any symtab then create an empty instance to avoid
- // do the section
- // lookup next time.
+ // do the section lookup next time.
if (m_symtab_ap == nullptr)
m_symtab_ap.reset(new Symtab(this));
@@ -2954,8 +2863,8 @@ void ObjectFileELF::RelocateSection(lldb_private::Section *section)
{
static const char *debug_prefix = ".debug";
- // Set relocated bit so we stop getting called, regardless of
- // whether we actually relocate.
+ // Set relocated bit so we stop getting called, regardless of whether we
+ // actually relocate.
section->SetIsRelocated(true);
// We only relocate in ELF relocatable files
@@ -2998,12 +2907,10 @@ void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table,
return;
// First we save the new symbols into a separate list and add them to the
- // symbol table after
- // we colleced all symbols we want to add. This is neccessary because adding a
- // new symbol
- // invalidates the internal index of the symtab what causing the next lookup
- // to be slow because
- // it have to recalculate the index first.
+ // symbol table after we colleced all symbols we want to add. This is
+ // neccessary because adding a new symbol invalidates the internal index of
+ // the symtab what causing the next lookup to be slow because it have to
+ // recalculate the index first.
std::vector<Symbol> new_symbols;
eh_frame->ForEachFDEEntries([this, symbol_table, section_list, &new_symbols](
@@ -3197,8 +3104,8 @@ void ObjectFileELF::DumpELFProgramHeader(Stream *s,
//----------------------------------------------------------------------
// DumpELFProgramHeader_p_type
//
-// Dump an token value for the ELF program header member p_type which
-// describes the type of the program header
+// Dump an token value for the ELF program header member p_type which describes
+// the type of the program header
// ----------------------------------------------------------------------
void ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type) {
const int kStrWidth = 15;
@@ -3369,8 +3276,7 @@ bool ObjectFileELF::GetArchitecture(ArchSpec &arch) {
if (CalculateType() == eTypeCoreFile &&
m_arch_spec.TripleOSIsUnspecifiedUnknown()) {
// Core files don't have section headers yet they have PT_NOTE program
- // headers
- // that might shed more light on the architecture
+ // headers that might shed more light on the architecture
if (ParseProgramHeaders()) {
for (size_t i = 1, count = GetProgramHeaderCount(); i <= count; ++i) {
const elf::ELFProgramHeader *header = GetProgramHeaderByIndex(i);
@@ -3431,22 +3337,22 @@ ObjectFile::Strata ObjectFileELF::CalculateStrata() {
case llvm::ELF::ET_EXEC:
// 2 - Executable file
// TODO: is there any way to detect that an executable is a kernel
- // related executable by inspecting the program headers, section
- // headers, symbols, or any other flag bits???
+ // related executable by inspecting the program headers, section headers,
+ // symbols, or any other flag bits???
return eStrataUser;
case llvm::ELF::ET_DYN:
// 3 - Shared object file
// TODO: is there any way to detect that an shared library is a kernel
- // related executable by inspecting the program headers, section
- // headers, symbols, or any other flag bits???
+ // related executable by inspecting the program headers, section headers,
+ // symbols, or any other flag bits???
return eStrataUnknown;
case ET_CORE:
// 4 - Core file
// TODO: is there any way to detect that an core file is a kernel
- // related executable by inspecting the program headers, section
- // headers, symbols, or any other flag bits???
+ // related executable by inspecting the program headers, section headers,
+ // symbols, or any other flag bits???
return eStrataUnknown;
default:
@@ -3491,8 +3397,9 @@ size_t ObjectFileELF::ReadSectionData(Section *section,
size_t(section_data.GetByteSize())},
GetByteOrder() == eByteOrderLittle, GetAddressByteSize() == 8);
if (!Decompressor) {
- LLDB_LOG(log, "Unable to initialize decompressor for section {0}: {1}",
- section->GetName(), llvm::toString(Decompressor.takeError()));
+ LLDB_LOG_ERROR(log, Decompressor.takeError(),
+ "Unable to initialize decompressor for section {0}",
+ section->GetName());
return result;
}
auto buffer_sp =
@@ -3500,10 +3407,45 @@ size_t ObjectFileELF::ReadSectionData(Section *section,
if (auto Error = Decompressor->decompress(
{reinterpret_cast<char *>(buffer_sp->GetBytes()),
size_t(buffer_sp->GetByteSize())})) {
- LLDB_LOG(log, "Decompression of section {0} failed: {1}",
- section->GetName(), llvm::toString(std::move(Error)));
+ LLDB_LOG_ERROR(log, std::move(Error), "Decompression of section {0} failed",
+ section->GetName());
return result;
}
section_data.SetData(buffer_sp);
return buffer_sp->GetByteSize();
}
+
+bool ObjectFileELF::AnySegmentHasPhysicalAddress() {
+ size_t header_count = ParseProgramHeaders();
+ for (size_t i = 1; i <= header_count; ++i) {
+ auto header = GetProgramHeaderByIndex(i);
+ if (header->p_paddr != 0)
+ return true;
+ }
+ return false;
+}
+
+std::vector<ObjectFile::LoadableData>
+ObjectFileELF::GetLoadableData(Target &target) {
+ // Create a list of loadable data from loadable segments, using physical
+ // addresses if they aren't all null
+ std::vector<LoadableData> loadables;
+ size_t header_count = ParseProgramHeaders();
+ bool should_use_paddr = AnySegmentHasPhysicalAddress();
+ for (size_t i = 1; i <= header_count; ++i) {
+ LoadableData loadable;
+ auto header = GetProgramHeaderByIndex(i);
+ if (header->p_type != llvm::ELF::PT_LOAD)
+ continue;
+ loadable.Dest = should_use_paddr ? header->p_paddr : header->p_vaddr;
+ if (loadable.Dest == LLDB_INVALID_ADDRESS)
+ continue;
+ if (header->p_filesz == 0)
+ continue;
+ auto segment_data = GetSegmentDataByIndex(i);
+ loadable.Contents = llvm::ArrayRef<uint8_t>(segment_data.GetDataStart(),
+ segment_data.GetByteSize());
+ loadables.push_back(loadable);
+ }
+ return loadables;
+}
diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
index 2909f4e52e4a..2664595fd81d 100644
--- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -54,10 +54,10 @@ struct ELFNote {
//------------------------------------------------------------------------------
/// @class ObjectFileELF
-/// @brief Generic ELF object file reader.
+/// Generic ELF object file reader.
///
-/// This class provides a generic ELF (32/64 bit) reader plugin implementing the
-/// ObjectFile protocol.
+/// This class provides a generic ELF (32/64 bit) reader plugin implementing
+/// the ObjectFile protocol.
class ObjectFileELF : public lldb_private::ObjectFile {
public:
~ObjectFileELF() override;
@@ -113,7 +113,7 @@ public:
uint32_t GetAddressByteSize() const override;
- lldb::AddressClass GetAddressClass(lldb::addr_t file_addr) override;
+ lldb_private::AddressClass GetAddressClass(lldb::addr_t file_addr) override;
lldb_private::Symtab *GetSymtab() override;
@@ -161,6 +161,11 @@ public:
void RelocateSection(lldb_private::Section *section) override;
+protected:
+
+ std::vector<LoadableData>
+ GetLoadableData(lldb_private::Target &target) override;
+
private:
ObjectFileELF(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
lldb::offset_t data_offset, const lldb_private::FileSpec *file,
@@ -186,7 +191,7 @@ private:
typedef DynamicSymbolColl::iterator DynamicSymbolCollIter;
typedef DynamicSymbolColl::const_iterator DynamicSymbolCollConstIter;
- typedef std::map<lldb::addr_t, lldb::AddressClass>
+ typedef std::map<lldb::addr_t, lldb_private::AddressClass>
FileAddressToAddressClassMap;
/// Version of this reader common to all plugins based on this class.
@@ -255,8 +260,8 @@ private:
uint64_t length,
lldb_private::ArchSpec &arch_spec);
- /// Parses the elf section headers and returns the uuid, debug link name, crc,
- /// archspec.
+ /// Parses the elf section headers and returns the uuid, debug link name,
+ /// crc, archspec.
static size_t GetSectionHeaderInfo(SectionHeaderColl &section_headers,
lldb_private::DataExtractor &object_data,
const elf::ELFHeader &header,
@@ -383,6 +388,8 @@ private:
RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
lldb_private::ArchSpec &arch_spec,
lldb_private::UUID &uuid);
+
+ bool AnySegmentHasPhysicalAddress();
};
#endif // liblldb_ObjectFileELF_h_
diff --git a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
index a9ab366fbf53..af040322ec52 100644
--- a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
+++ b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
@@ -65,8 +65,8 @@ ObjectFile *ObjectFileJIT::CreateInstance(const lldb::ModuleSP &module_sp,
const FileSpec *file,
lldb::offset_t file_offset,
lldb::offset_t length) {
- // JIT'ed object file is backed by the ObjectFileJITDelegate, never
- // read from a file
+ // JIT'ed object file is backed by the ObjectFileJITDelegate, never read from
+ // a file
return NULL;
}
@@ -74,8 +74,8 @@ ObjectFile *ObjectFileJIT::CreateMemoryInstance(const lldb::ModuleSP &module_sp,
DataBufferSP &data_sp,
const ProcessSP &process_sp,
lldb::addr_t header_addr) {
- // JIT'ed object file is backed by the ObjectFileJITDelegate, never
- // read from memory
+ // JIT'ed object file is backed by the ObjectFileJITDelegate, never read from
+ // memory
return NULL;
}
@@ -214,9 +214,8 @@ bool ObjectFileJIT::SetLoadAddress(Target &target, lldb::addr_t value,
const size_t num_sections = section_list->GetSize();
// "value" is an offset to apply to each top level segment
for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
- // Iterate through the object file sections to find all
- // of the sections that size on disk (to avoid __PAGEZERO)
- // and load them
+ // Iterate through the object file sections to find all of the sections
+ // that size on disk (to avoid __PAGEZERO) and load them
SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
if (section_sp && section_sp->GetFileSize() > 0 &&
section_sp->IsThreadSpecific() == false) {
diff --git a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index e6941c9f6ed6..91e7f3353270 100644
--- a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -161,8 +161,7 @@ public:
case 7:
case 8:
case 9:
- // fancy flavors that encapsulate of the above
- // flavors...
+ // fancy flavors that encapsulate of the above flavors...
break;
default:
@@ -393,8 +392,7 @@ public:
case 7:
case 8:
case 9:
- // fancy flavors that encapsulate of the above
- // flavors...
+ // fancy flavors that encapsulate of the above flavors...
break;
default:
@@ -517,8 +515,7 @@ public:
}
// Note that gpr.cpsr is also copied by the above loop; this loop
- // technically extends
- // one element past the end of the gpr.r[] array.
+ // technically extends one element past the end of the gpr.r[] array.
SetError(GPRRegSet, Read, 0);
offset = next_thread_state;
@@ -1164,19 +1161,19 @@ AddressClass ObjectFileMachO::GetAddressClass(lldb::addr_t file_addr) {
const lldb::SectionType section_type = section_sp->GetType();
switch (section_type) {
case eSectionTypeInvalid:
- return eAddressClassUnknown;
+ return AddressClass::eUnknown;
case eSectionTypeCode:
if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM) {
- // For ARM we have a bit in the n_desc field of the symbol
- // that tells us ARM/Thumb which is bit 0x0008.
+ // For ARM we have a bit in the n_desc field of the symbol that
+ // tells us ARM/Thumb which is bit 0x0008.
if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
- return eAddressClassCodeAlternateISA;
+ return AddressClass::eCodeAlternateISA;
}
- return eAddressClassCode;
+ return AddressClass::eCode;
case eSectionTypeContainer:
- return eAddressClassUnknown;
+ return AddressClass::eUnknown;
case eSectionTypeData:
case eSectionTypeDataCString:
@@ -1190,7 +1187,7 @@ AddressClass ObjectFileMachO::GetAddressClass(lldb::addr_t file_addr) {
case eSectionTypeDataObjCMessageRefs:
case eSectionTypeDataObjCCFStrings:
case eSectionTypeGoSymtab:
- return eAddressClassData;
+ return AddressClass::eData;
case eSectionTypeDebug:
case eSectionTypeDWARFDebugAbbrev:
@@ -1203,22 +1200,25 @@ AddressClass ObjectFileMachO::GetAddressClass(lldb::addr_t file_addr) {
case eSectionTypeDWARFDebugLoc:
case eSectionTypeDWARFDebugMacInfo:
case eSectionTypeDWARFDebugMacro:
+ case eSectionTypeDWARFDebugNames:
case eSectionTypeDWARFDebugPubNames:
case eSectionTypeDWARFDebugPubTypes:
case eSectionTypeDWARFDebugRanges:
case eSectionTypeDWARFDebugStr:
case eSectionTypeDWARFDebugStrOffsets:
+ case eSectionTypeDWARFDebugTypes:
case eSectionTypeDWARFAppleNames:
case eSectionTypeDWARFAppleTypes:
case eSectionTypeDWARFAppleNamespaces:
case eSectionTypeDWARFAppleObjC:
- return eAddressClassDebug;
+ case eSectionTypeDWARFGNUDebugAltLink:
+ return AddressClass::eDebug;
case eSectionTypeEHFrame:
case eSectionTypeARMexidx:
case eSectionTypeARMextab:
case eSectionTypeCompactUnwind:
- return eAddressClassRuntime;
+ return AddressClass::eRuntime;
case eSectionTypeAbsoluteAddress:
case eSectionTypeELFSymbolTable:
@@ -1226,7 +1226,7 @@ AddressClass ObjectFileMachO::GetAddressClass(lldb::addr_t file_addr) {
case eSectionTypeELFRelocationEntries:
case eSectionTypeELFDynamicLinkInfo:
case eSectionTypeOther:
- return eAddressClassUnknown;
+ return AddressClass::eUnknown;
}
}
}
@@ -1234,73 +1234,73 @@ AddressClass ObjectFileMachO::GetAddressClass(lldb::addr_t file_addr) {
const SymbolType symbol_type = symbol->GetType();
switch (symbol_type) {
case eSymbolTypeAny:
- return eAddressClassUnknown;
+ return AddressClass::eUnknown;
case eSymbolTypeAbsolute:
- return eAddressClassUnknown;
+ return AddressClass::eUnknown;
case eSymbolTypeCode:
case eSymbolTypeTrampoline:
case eSymbolTypeResolver:
if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM) {
- // For ARM we have a bit in the n_desc field of the symbol
- // that tells us ARM/Thumb which is bit 0x0008.
+ // For ARM we have a bit in the n_desc field of the symbol that tells
+ // us ARM/Thumb which is bit 0x0008.
if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
- return eAddressClassCodeAlternateISA;
+ return AddressClass::eCodeAlternateISA;
}
- return eAddressClassCode;
+ return AddressClass::eCode;
case eSymbolTypeData:
- return eAddressClassData;
+ return AddressClass::eData;
case eSymbolTypeRuntime:
- return eAddressClassRuntime;
+ return AddressClass::eRuntime;
case eSymbolTypeException:
- return eAddressClassRuntime;
+ return AddressClass::eRuntime;
case eSymbolTypeSourceFile:
- return eAddressClassDebug;
+ return AddressClass::eDebug;
case eSymbolTypeHeaderFile:
- return eAddressClassDebug;
+ return AddressClass::eDebug;
case eSymbolTypeObjectFile:
- return eAddressClassDebug;
+ return AddressClass::eDebug;
case eSymbolTypeCommonBlock:
- return eAddressClassDebug;
+ return AddressClass::eDebug;
case eSymbolTypeBlock:
- return eAddressClassDebug;
+ return AddressClass::eDebug;
case eSymbolTypeLocal:
- return eAddressClassData;
+ return AddressClass::eData;
case eSymbolTypeParam:
- return eAddressClassData;
+ return AddressClass::eData;
case eSymbolTypeVariable:
- return eAddressClassData;
+ return AddressClass::eData;
case eSymbolTypeVariableType:
- return eAddressClassDebug;
+ return AddressClass::eDebug;
case eSymbolTypeLineEntry:
- return eAddressClassDebug;
+ return AddressClass::eDebug;
case eSymbolTypeLineHeader:
- return eAddressClassDebug;
+ return AddressClass::eDebug;
case eSymbolTypeScopeBegin:
- return eAddressClassDebug;
+ return AddressClass::eDebug;
case eSymbolTypeScopeEnd:
- return eAddressClassDebug;
+ return AddressClass::eDebug;
case eSymbolTypeAdditional:
- return eAddressClassUnknown;
+ return AddressClass::eUnknown;
case eSymbolTypeCompiler:
- return eAddressClassDebug;
+ return AddressClass::eDebug;
case eSymbolTypeInstrumentation:
- return eAddressClassDebug;
+ return AddressClass::eDebug;
case eSymbolTypeUndefined:
- return eAddressClassUnknown;
+ return AddressClass::eUnknown;
case eSymbolTypeObjCClass:
- return eAddressClassRuntime;
+ return AddressClass::eRuntime;
case eSymbolTypeObjCMetaClass:
- return eAddressClassRuntime;
+ return AddressClass::eRuntime;
case eSymbolTypeObjCIVar:
- return eAddressClassRuntime;
+ return AddressClass::eRuntime;
case eSymbolTypeReExported:
- return eAddressClassRuntime;
+ return AddressClass::eRuntime;
}
}
}
- return eAddressClassUnknown;
+ return AddressClass::eUnknown;
}
Symtab *ObjectFileMachO::GetSymtab() {
@@ -1349,586 +1349,565 @@ bool ObjectFileMachO::IsStripped() {
return false;
}
-void ObjectFileMachO::CreateSections(SectionList &unified_section_list) {
- if (!m_sections_ap.get()) {
- m_sections_ap.reset(new SectionList());
+ObjectFileMachO::EncryptedFileRanges ObjectFileMachO::GetEncryptedFileRanges() {
+ EncryptedFileRanges result;
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
- const bool is_dsym = (m_header.filetype == MH_DSYM);
- lldb::user_id_t segID = 0;
- lldb::user_id_t sectID = 0;
- lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
- uint32_t i;
- const bool is_core = GetType() == eTypeCoreFile;
- // bool dump_sections = false;
- ModuleSP module_sp(GetModule());
- // First look up any LC_ENCRYPTION_INFO load commands
- typedef RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges;
- EncryptedFileRanges encrypted_file_ranges;
- encryption_info_command encryption_cmd;
- for (i = 0; i < m_header.ncmds; ++i) {
- const lldb::offset_t load_cmd_offset = offset;
- if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL)
- break;
+ encryption_info_command encryption_cmd;
+ for (uint32_t i = 0; i < m_header.ncmds; ++i) {
+ const lldb::offset_t load_cmd_offset = offset;
+ if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL)
+ break;
- // LC_ENCRYPTION_INFO and LC_ENCRYPTION_INFO_64 have the same sizes for
- // the 3 fields we care about, so treat them the same.
- if (encryption_cmd.cmd == LC_ENCRYPTION_INFO ||
- encryption_cmd.cmd == LC_ENCRYPTION_INFO_64) {
- if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3)) {
- if (encryption_cmd.cryptid != 0) {
- EncryptedFileRanges::Entry entry;
- entry.SetRangeBase(encryption_cmd.cryptoff);
- entry.SetByteSize(encryption_cmd.cryptsize);
- encrypted_file_ranges.Append(entry);
- }
+ // LC_ENCRYPTION_INFO and LC_ENCRYPTION_INFO_64 have the same sizes for the
+ // 3 fields we care about, so treat them the same.
+ if (encryption_cmd.cmd == LC_ENCRYPTION_INFO ||
+ encryption_cmd.cmd == LC_ENCRYPTION_INFO_64) {
+ if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3)) {
+ if (encryption_cmd.cryptid != 0) {
+ EncryptedFileRanges::Entry entry;
+ entry.SetRangeBase(encryption_cmd.cryptoff);
+ entry.SetByteSize(encryption_cmd.cryptsize);
+ result.Append(entry);
}
}
- offset = load_cmd_offset + encryption_cmd.cmdsize;
}
+ offset = load_cmd_offset + encryption_cmd.cmdsize;
+ }
- bool section_file_addresses_changed = false;
+ return result;
+}
- offset = MachHeaderSizeFromMagic(m_header.magic);
+void ObjectFileMachO::SanitizeSegmentCommand(segment_command_64 &seg_cmd,
+ uint32_t cmd_idx) {
+ if (m_length == 0 || seg_cmd.filesize == 0)
+ return;
- struct segment_command_64 load_cmd;
- for (i = 0; i < m_header.ncmds; ++i) {
- const lldb::offset_t load_cmd_offset = offset;
- if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
- break;
+ if (seg_cmd.fileoff > m_length) {
+ // We have a load command that says it extends past the end of the file.
+ // This is likely a corrupt file. We don't have any way to return an error
+ // condition here (this method was likely invoked from something like
+ // ObjectFile::GetSectionList()), so we just null out the section contents,
+ // and dump a message to stdout. The most common case here is core file
+ // debugging with a truncated file.
+ const char *lc_segment_name =
+ seg_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
+ GetModule()->ReportWarning(
+ "load command %u %s has a fileoff (0x%" PRIx64
+ ") that extends beyond the end of the file (0x%" PRIx64
+ "), ignoring this section",
+ cmd_idx, lc_segment_name, seg_cmd.fileoff, m_length);
- if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64) {
- if (m_data.GetU8(&offset, (uint8_t *)load_cmd.segname, 16)) {
- bool add_section = true;
- bool add_to_unified = true;
- ConstString const_segname(load_cmd.segname,
- std::min<size_t>(strlen(load_cmd.segname),
- sizeof(load_cmd.segname)));
+ seg_cmd.fileoff = 0;
+ seg_cmd.filesize = 0;
+ }
- SectionSP unified_section_sp(
- unified_section_list.FindSectionByName(const_segname));
- if (is_dsym && unified_section_sp) {
- if (const_segname == GetSegmentNameLINKEDIT()) {
- // We need to keep the __LINKEDIT segment private to this object
- // file only
- add_to_unified = false;
- } else {
- // This is the dSYM file and this section has already been created
- // by
- // the object file, no need to create it.
- add_section = false;
- }
- }
- load_cmd.vmaddr = m_data.GetAddress(&offset);
- load_cmd.vmsize = m_data.GetAddress(&offset);
- load_cmd.fileoff = m_data.GetAddress(&offset);
- load_cmd.filesize = m_data.GetAddress(&offset);
- if (m_length != 0 && load_cmd.filesize != 0) {
- if (load_cmd.fileoff > m_length) {
- // We have a load command that says it extends past the end of the
- // file. This is likely
- // a corrupt file. We don't have any way to return an error
- // condition here (this method
- // was likely invoked from something like
- // ObjectFile::GetSectionList()) -- all we can do
- // is null out the SectionList vector and if a process has been
- // set up, dump a message
- // to stdout. The most common case here is core file debugging
- // with a truncated file.
- const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64
- ? "LC_SEGMENT_64"
- : "LC_SEGMENT";
- module_sp->ReportWarning(
- "load command %u %s has a fileoff (0x%" PRIx64
- ") that extends beyond the end of the file (0x%" PRIx64
- "), ignoring this section",
- i, lc_segment_name, load_cmd.fileoff, m_length);
+ if (seg_cmd.fileoff + seg_cmd.filesize > m_length) {
+ // We have a load command that says it extends past the end of the file.
+ // This is likely a corrupt file. We don't have any way to return an error
+ // condition here (this method was likely invoked from something like
+ // ObjectFile::GetSectionList()), so we just null out the section contents,
+ // and dump a message to stdout. The most common case here is core file
+ // debugging with a truncated file.
+ const char *lc_segment_name =
+ seg_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
+ GetModule()->ReportWarning(
+ "load command %u %s has a fileoff + filesize (0x%" PRIx64
+ ") that extends beyond the end of the file (0x%" PRIx64
+ "), the segment will be truncated to match",
+ cmd_idx, lc_segment_name, seg_cmd.fileoff + seg_cmd.filesize, m_length);
- load_cmd.fileoff = 0;
- load_cmd.filesize = 0;
- }
+ // Truncate the length
+ seg_cmd.filesize = m_length - seg_cmd.fileoff;
+ }
+}
- if (load_cmd.fileoff + load_cmd.filesize > m_length) {
- // We have a load command that says it extends past the end of the
- // file. This is likely
- // a corrupt file. We don't have any way to return an error
- // condition here (this method
- // was likely invoked from something like
- // ObjectFile::GetSectionList()) -- all we can do
- // is null out the SectionList vector and if a process has been
- // set up, dump a message
- // to stdout. The most common case here is core file debugging
- // with a truncated file.
- const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64
- ? "LC_SEGMENT_64"
- : "LC_SEGMENT";
- GetModule()->ReportWarning(
- "load command %u %s has a fileoff + filesize (0x%" PRIx64
- ") that extends beyond the end of the file (0x%" PRIx64
- "), the segment will be truncated to match",
- i, lc_segment_name, load_cmd.fileoff + load_cmd.filesize,
- m_length);
+static uint32_t GetSegmentPermissions(const segment_command_64 &seg_cmd) {
+ uint32_t result = 0;
+ if (seg_cmd.initprot & VM_PROT_READ)
+ result |= ePermissionsReadable;
+ if (seg_cmd.initprot & VM_PROT_WRITE)
+ result |= ePermissionsWritable;
+ if (seg_cmd.initprot & VM_PROT_EXECUTE)
+ result |= ePermissionsExecutable;
+ return result;
+}
- // Tuncase the length
- load_cmd.filesize = m_length - load_cmd.fileoff;
- }
- }
- if (m_data.GetU32(&offset, &load_cmd.maxprot, 4)) {
- uint32_t segment_permissions = 0;
- if (load_cmd.initprot & VM_PROT_READ)
- segment_permissions |= ePermissionsReadable;
- if (load_cmd.initprot & VM_PROT_WRITE)
- segment_permissions |= ePermissionsWritable;
- if (load_cmd.initprot & VM_PROT_EXECUTE)
- segment_permissions |= ePermissionsExecutable;
+static lldb::SectionType GetSectionType(uint32_t flags,
+ ConstString section_name) {
- const bool segment_is_encrypted =
- (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0;
+ if (flags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS))
+ return eSectionTypeCode;
- // Keep a list of mach segments around in case we need to
- // get at data that isn't stored in the abstracted Sections.
- m_mach_segments.push_back(load_cmd);
+ uint32_t mach_sect_type = flags & SECTION_TYPE;
+ static ConstString g_sect_name_objc_data("__objc_data");
+ static ConstString g_sect_name_objc_msgrefs("__objc_msgrefs");
+ static ConstString g_sect_name_objc_selrefs("__objc_selrefs");
+ static ConstString g_sect_name_objc_classrefs("__objc_classrefs");
+ static ConstString g_sect_name_objc_superrefs("__objc_superrefs");
+ static ConstString g_sect_name_objc_const("__objc_const");
+ static ConstString g_sect_name_objc_classlist("__objc_classlist");
+ static ConstString g_sect_name_cfstring("__cfstring");
- // Use a segment ID of the segment index shifted left by 8 so they
- // never conflict with any of the sections.
- SectionSP segment_sp;
- if (add_section && (const_segname || is_core)) {
- segment_sp.reset(new Section(
- module_sp, // Module to which this section belongs
- this, // Object file to which this sections belongs
- ++segID << 8, // Section ID is the 1 based segment index
- // shifted right by 8 bits as not to collide
- // with any of the 256 section IDs that are
- // possible
- const_segname, // Name of this section
- eSectionTypeContainer, // This section is a container of other
- // sections.
- load_cmd.vmaddr, // File VM address == addresses as they are
- // found in the object file
- load_cmd.vmsize, // VM size in bytes of this section
- load_cmd.fileoff, // Offset to the data for this section in
- // the file
- load_cmd.filesize, // Size in bytes of this section as found
- // in the file
- 0, // Segments have no alignment information
- load_cmd.flags)); // Flags for this section
+ static ConstString g_sect_name_dwarf_debug_abbrev("__debug_abbrev");
+ static ConstString g_sect_name_dwarf_debug_aranges("__debug_aranges");
+ static ConstString g_sect_name_dwarf_debug_frame("__debug_frame");
+ static ConstString g_sect_name_dwarf_debug_info("__debug_info");
+ static ConstString g_sect_name_dwarf_debug_line("__debug_line");
+ static ConstString g_sect_name_dwarf_debug_loc("__debug_loc");
+ static ConstString g_sect_name_dwarf_debug_macinfo("__debug_macinfo");
+ static ConstString g_sect_name_dwarf_debug_names("__debug_names");
+ static ConstString g_sect_name_dwarf_debug_pubnames("__debug_pubnames");
+ static ConstString g_sect_name_dwarf_debug_pubtypes("__debug_pubtypes");
+ static ConstString g_sect_name_dwarf_debug_ranges("__debug_ranges");
+ static ConstString g_sect_name_dwarf_debug_str("__debug_str");
+ static ConstString g_sect_name_dwarf_debug_types("__debug_types");
+ static ConstString g_sect_name_dwarf_apple_names("__apple_names");
+ static ConstString g_sect_name_dwarf_apple_types("__apple_types");
+ static ConstString g_sect_name_dwarf_apple_namespaces("__apple_namespac");
+ static ConstString g_sect_name_dwarf_apple_objc("__apple_objc");
+ static ConstString g_sect_name_eh_frame("__eh_frame");
+ static ConstString g_sect_name_compact_unwind("__unwind_info");
+ static ConstString g_sect_name_text("__text");
+ static ConstString g_sect_name_data("__data");
+ static ConstString g_sect_name_go_symtab("__gosymtab");
- segment_sp->SetIsEncrypted(segment_is_encrypted);
- m_sections_ap->AddSection(segment_sp);
- segment_sp->SetPermissions(segment_permissions);
- if (add_to_unified)
- unified_section_list.AddSection(segment_sp);
- } else if (unified_section_sp) {
- if (is_dsym &&
- unified_section_sp->GetFileAddress() != load_cmd.vmaddr) {
- // Check to see if the module was read from memory?
- if (module_sp->GetObjectFile()->GetHeaderAddress().IsValid()) {
- // We have a module that is in memory and needs to have its
- // file address adjusted. We need to do this because when we
- // load a file from memory, its addresses will be slid
- // already,
- // yet the addresses in the new symbol file will still be
- // unslid.
- // Since everything is stored as section offset, this
- // shouldn't
- // cause any problems.
+ if (section_name == g_sect_name_dwarf_debug_abbrev)
+ return eSectionTypeDWARFDebugAbbrev;
+ if (section_name == g_sect_name_dwarf_debug_aranges)
+ return eSectionTypeDWARFDebugAranges;
+ if (section_name == g_sect_name_dwarf_debug_frame)
+ return eSectionTypeDWARFDebugFrame;
+ if (section_name == g_sect_name_dwarf_debug_info)
+ return eSectionTypeDWARFDebugInfo;
+ if (section_name == g_sect_name_dwarf_debug_line)
+ return eSectionTypeDWARFDebugLine;
+ if (section_name == g_sect_name_dwarf_debug_loc)
+ return eSectionTypeDWARFDebugLoc;
+ if (section_name == g_sect_name_dwarf_debug_macinfo)
+ return eSectionTypeDWARFDebugMacInfo;
+ if (section_name == g_sect_name_dwarf_debug_names)
+ return eSectionTypeDWARFDebugNames;
+ if (section_name == g_sect_name_dwarf_debug_pubnames)
+ return eSectionTypeDWARFDebugPubNames;
+ if (section_name == g_sect_name_dwarf_debug_pubtypes)
+ return eSectionTypeDWARFDebugPubTypes;
+ if (section_name == g_sect_name_dwarf_debug_ranges)
+ return eSectionTypeDWARFDebugRanges;
+ if (section_name == g_sect_name_dwarf_debug_str)
+ return eSectionTypeDWARFDebugStr;
+ if (section_name == g_sect_name_dwarf_debug_types)
+ return eSectionTypeDWARFDebugTypes;
+ if (section_name == g_sect_name_dwarf_apple_names)
+ return eSectionTypeDWARFAppleNames;
+ if (section_name == g_sect_name_dwarf_apple_types)
+ return eSectionTypeDWARFAppleTypes;
+ if (section_name == g_sect_name_dwarf_apple_namespaces)
+ return eSectionTypeDWARFAppleNamespaces;
+ if (section_name == g_sect_name_dwarf_apple_objc)
+ return eSectionTypeDWARFAppleObjC;
+ if (section_name == g_sect_name_objc_selrefs)
+ return eSectionTypeDataCStringPointers;
+ if (section_name == g_sect_name_objc_msgrefs)
+ return eSectionTypeDataObjCMessageRefs;
+ if (section_name == g_sect_name_eh_frame)
+ return eSectionTypeEHFrame;
+ if (section_name == g_sect_name_compact_unwind)
+ return eSectionTypeCompactUnwind;
+ if (section_name == g_sect_name_cfstring)
+ return eSectionTypeDataObjCCFStrings;
+ if (section_name == g_sect_name_go_symtab)
+ return eSectionTypeGoSymtab;
+ if (section_name == g_sect_name_objc_data ||
+ section_name == g_sect_name_objc_classrefs ||
+ section_name == g_sect_name_objc_superrefs ||
+ section_name == g_sect_name_objc_const ||
+ section_name == g_sect_name_objc_classlist) {
+ return eSectionTypeDataPointers;
+ }
- // Make sure we've parsed the symbol table from the
- // ObjectFile before we go around changing its Sections.
- module_sp->GetObjectFile()->GetSymtab();
- // eh_frame would present the same problems but we parse that
- // on
- // a per-function basis as-needed so it's more difficult to
- // remove its use of the Sections. Realistically, the
- // environments
- // where this code path will be taken will not have eh_frame
- // sections.
+ switch (mach_sect_type) {
+ // TODO: categorize sections by other flags for regular sections
+ case S_REGULAR:
+ if (section_name == g_sect_name_text)
+ return eSectionTypeCode;
+ if (section_name == g_sect_name_data)
+ return eSectionTypeData;
+ return eSectionTypeOther;
+ case S_ZEROFILL:
+ return eSectionTypeZeroFill;
+ case S_CSTRING_LITERALS: // section with only literal C strings
+ return eSectionTypeDataCString;
+ case S_4BYTE_LITERALS: // section with only 4 byte literals
+ return eSectionTypeData4;
+ case S_8BYTE_LITERALS: // section with only 8 byte literals
+ return eSectionTypeData8;
+ case S_LITERAL_POINTERS: // section with only pointers to literals
+ return eSectionTypeDataPointers;
+ case S_NON_LAZY_SYMBOL_POINTERS: // section with only non-lazy symbol pointers
+ return eSectionTypeDataPointers;
+ case S_LAZY_SYMBOL_POINTERS: // section with only lazy symbol pointers
+ return eSectionTypeDataPointers;
+ case S_SYMBOL_STUBS: // section with only symbol stubs, byte size of stub in
+ // the reserved2 field
+ return eSectionTypeCode;
+ case S_MOD_INIT_FUNC_POINTERS: // section with only function pointers for
+ // initialization
+ return eSectionTypeDataPointers;
+ case S_MOD_TERM_FUNC_POINTERS: // section with only function pointers for
+ // termination
+ return eSectionTypeDataPointers;
+ case S_COALESCED:
+ return eSectionTypeOther;
+ case S_GB_ZEROFILL:
+ return eSectionTypeZeroFill;
+ case S_INTERPOSING: // section with only pairs of function pointers for
+ // interposing
+ return eSectionTypeCode;
+ case S_16BYTE_LITERALS: // section with only 16 byte literals
+ return eSectionTypeData16;
+ case S_DTRACE_DOF:
+ return eSectionTypeDebug;
+ case S_LAZY_DYLIB_SYMBOL_POINTERS:
+ return eSectionTypeDataPointers;
+ default:
+ return eSectionTypeOther;
+ }
+}
- unified_section_sp->SetFileAddress(load_cmd.vmaddr);
+struct ObjectFileMachO::SegmentParsingContext {
+ const EncryptedFileRanges EncryptedRanges;
+ lldb_private::SectionList &UnifiedList;
+ uint32_t NextSegmentIdx = 0;
+ uint32_t NextSectionIdx = 0;
+ bool FileAddressesChanged = false;
- // Notify the module that the section addresses have been
- // changed once
- // we're done so any file-address caches can be updated.
- section_file_addresses_changed = true;
- }
- }
- m_sections_ap->AddSection(unified_section_sp);
- }
+ SegmentParsingContext(EncryptedFileRanges EncryptedRanges,
+ lldb_private::SectionList &UnifiedList)
+ : EncryptedRanges(std::move(EncryptedRanges)), UnifiedList(UnifiedList) {}
+};
- struct section_64 sect64;
- ::memset(&sect64, 0, sizeof(sect64));
- // Push a section into our mach sections for the section at
- // index zero (NO_SECT) if we don't have any mach sections yet...
- if (m_mach_sections.empty())
- m_mach_sections.push_back(sect64);
- uint32_t segment_sect_idx;
- const lldb::user_id_t first_segment_sectID = sectID + 1;
+void ObjectFileMachO::ProcessSegmentCommand(const load_command &load_cmd_,
+ lldb::offset_t offset,
+ uint32_t cmd_idx,
+ SegmentParsingContext &context) {
+ segment_command_64 load_cmd;
+ memcpy(&load_cmd, &load_cmd_, sizeof(load_cmd_));
- const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8;
- for (segment_sect_idx = 0; segment_sect_idx < load_cmd.nsects;
- ++segment_sect_idx) {
- if (m_data.GetU8(&offset, (uint8_t *)sect64.sectname,
- sizeof(sect64.sectname)) == NULL)
- break;
- if (m_data.GetU8(&offset, (uint8_t *)sect64.segname,
- sizeof(sect64.segname)) == NULL)
- break;
- sect64.addr = m_data.GetAddress(&offset);
- sect64.size = m_data.GetAddress(&offset);
+ if (!m_data.GetU8(&offset, (uint8_t *)load_cmd.segname, 16))
+ return;
- if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL)
- break;
+ ModuleSP module_sp = GetModule();
+ const bool is_core = GetType() == eTypeCoreFile;
+ const bool is_dsym = (m_header.filetype == MH_DSYM);
+ bool add_section = true;
+ bool add_to_unified = true;
+ ConstString const_segname(
+ load_cmd.segname,
+ std::min<size_t>(strlen(load_cmd.segname), sizeof(load_cmd.segname)));
- // Keep a list of mach sections around in case we need to
- // get at data that isn't stored in the abstracted Sections.
- m_mach_sections.push_back(sect64);
+ SectionSP unified_section_sp(
+ context.UnifiedList.FindSectionByName(const_segname));
+ if (is_dsym && unified_section_sp) {
+ if (const_segname == GetSegmentNameLINKEDIT()) {
+ // We need to keep the __LINKEDIT segment private to this object file
+ // only
+ add_to_unified = false;
+ } else {
+ // This is the dSYM file and this section has already been created by the
+ // object file, no need to create it.
+ add_section = false;
+ }
+ }
+ load_cmd.vmaddr = m_data.GetAddress(&offset);
+ load_cmd.vmsize = m_data.GetAddress(&offset);
+ load_cmd.fileoff = m_data.GetAddress(&offset);
+ load_cmd.filesize = m_data.GetAddress(&offset);
+ if (!m_data.GetU32(&offset, &load_cmd.maxprot, 4))
+ return;
- if (add_section) {
- ConstString section_name(
- sect64.sectname, std::min<size_t>(strlen(sect64.sectname),
- sizeof(sect64.sectname)));
- if (!const_segname) {
- // We have a segment with no name so we need to conjure up
- // segments that correspond to the section's segname if there
- // isn't already such a section. If there is such a section,
- // we resize the section so that it spans all sections.
- // We also mark these sections as fake so address matches
- // don't
- // hit if they land in the gaps between the child sections.
- const_segname.SetTrimmedCStringWithLength(
- sect64.segname, sizeof(sect64.segname));
- segment_sp =
- unified_section_list.FindSectionByName(const_segname);
- if (segment_sp.get()) {
- Section *segment = segment_sp.get();
- // Grow the section size as needed.
- const lldb::addr_t sect64_min_addr = sect64.addr;
- const lldb::addr_t sect64_max_addr =
- sect64_min_addr + sect64.size;
- const lldb::addr_t curr_seg_byte_size =
- segment->GetByteSize();
- const lldb::addr_t curr_seg_min_addr =
- segment->GetFileAddress();
- const lldb::addr_t curr_seg_max_addr =
- curr_seg_min_addr + curr_seg_byte_size;
- if (sect64_min_addr >= curr_seg_min_addr) {
- const lldb::addr_t new_seg_byte_size =
- sect64_max_addr - curr_seg_min_addr;
- // Only grow the section size if needed
- if (new_seg_byte_size > curr_seg_byte_size)
- segment->SetByteSize(new_seg_byte_size);
- } else {
- // We need to change the base address of the segment and
- // adjust the child section offsets for all existing
- // children.
- const lldb::addr_t slide_amount =
- sect64_min_addr - curr_seg_min_addr;
- segment->Slide(slide_amount, false);
- segment->GetChildren().Slide(-slide_amount, false);
- segment->SetByteSize(curr_seg_max_addr - sect64_min_addr);
- }
+ SanitizeSegmentCommand(load_cmd, cmd_idx);
- // Grow the section size as needed.
- if (sect64.offset) {
- const lldb::addr_t segment_min_file_offset =
- segment->GetFileOffset();
- const lldb::addr_t segment_max_file_offset =
- segment_min_file_offset + segment->GetFileSize();
+ const uint32_t segment_permissions = GetSegmentPermissions(load_cmd);
+ const bool segment_is_encrypted =
+ (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0;
- const lldb::addr_t section_min_file_offset =
- sect64.offset;
- const lldb::addr_t section_max_file_offset =
- section_min_file_offset + sect64.size;
- const lldb::addr_t new_file_offset = std::min(
- section_min_file_offset, segment_min_file_offset);
- const lldb::addr_t new_file_size =
- std::max(section_max_file_offset,
- segment_max_file_offset) -
- new_file_offset;
- segment->SetFileOffset(new_file_offset);
- segment->SetFileSize(new_file_size);
- }
- } else {
- // Create a fake section for the section's named segment
- segment_sp.reset(new Section(
- segment_sp, // Parent section
- module_sp, // Module to which this section belongs
- this, // Object file to which this section belongs
- ++segID << 8, // Section ID is the 1 based segment index
- // shifted right by 8 bits as not to
- // collide with any of the 256 section IDs
- // that are possible
- const_segname, // Name of this section
- eSectionTypeContainer, // This section is a container of
- // other sections.
- sect64.addr, // File VM address == addresses as they are
- // found in the object file
- sect64.size, // VM size in bytes of this section
- sect64.offset, // Offset to the data for this section in
- // the file
- sect64.offset ? sect64.size : 0, // Size in bytes of
- // this section as
- // found in the file
- sect64.align,
- load_cmd.flags)); // Flags for this section
- segment_sp->SetIsFake(true);
- segment_sp->SetPermissions(segment_permissions);
- m_sections_ap->AddSection(segment_sp);
- if (add_to_unified)
- unified_section_list.AddSection(segment_sp);
- segment_sp->SetIsEncrypted(segment_is_encrypted);
- }
- }
- assert(segment_sp.get());
+ // Keep a list of mach segments around in case we need to get at data that
+ // isn't stored in the abstracted Sections.
+ m_mach_segments.push_back(load_cmd);
- lldb::SectionType sect_type = eSectionTypeOther;
+ // Use a segment ID of the segment index shifted left by 8 so they never
+ // conflict with any of the sections.
+ SectionSP segment_sp;
+ if (add_section && (const_segname || is_core)) {
+ segment_sp.reset(new Section(
+ module_sp, // Module to which this section belongs
+ this, // Object file to which this sections belongs
+ ++context.NextSegmentIdx
+ << 8, // Section ID is the 1 based segment index
+ // shifted right by 8 bits as not to collide with any of the 256
+ // section IDs that are possible
+ const_segname, // Name of this section
+ eSectionTypeContainer, // This section is a container of other
+ // sections.
+ load_cmd.vmaddr, // File VM address == addresses as they are
+ // found in the object file
+ load_cmd.vmsize, // VM size in bytes of this section
+ load_cmd.fileoff, // Offset to the data for this section in
+ // the file
+ load_cmd.filesize, // Size in bytes of this section as found
+ // in the file
+ 0, // Segments have no alignment information
+ load_cmd.flags)); // Flags for this section
- if (sect64.flags &
- (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS))
- sect_type = eSectionTypeCode;
- else {
- uint32_t mach_sect_type = sect64.flags & SECTION_TYPE;
- static ConstString g_sect_name_objc_data("__objc_data");
- static ConstString g_sect_name_objc_msgrefs("__objc_msgrefs");
- static ConstString g_sect_name_objc_selrefs("__objc_selrefs");
- static ConstString g_sect_name_objc_classrefs(
- "__objc_classrefs");
- static ConstString g_sect_name_objc_superrefs(
- "__objc_superrefs");
- static ConstString g_sect_name_objc_const("__objc_const");
- static ConstString g_sect_name_objc_classlist(
- "__objc_classlist");
- static ConstString g_sect_name_cfstring("__cfstring");
+ segment_sp->SetIsEncrypted(segment_is_encrypted);
+ m_sections_ap->AddSection(segment_sp);
+ segment_sp->SetPermissions(segment_permissions);
+ if (add_to_unified)
+ context.UnifiedList.AddSection(segment_sp);
+ } else if (unified_section_sp) {
+ if (is_dsym && unified_section_sp->GetFileAddress() != load_cmd.vmaddr) {
+ // Check to see if the module was read from memory?
+ if (module_sp->GetObjectFile()->GetHeaderAddress().IsValid()) {
+ // We have a module that is in memory and needs to have its file
+ // address adjusted. We need to do this because when we load a file
+ // from memory, its addresses will be slid already, yet the addresses
+ // in the new symbol file will still be unslid. Since everything is
+ // stored as section offset, this shouldn't cause any problems.
- static ConstString g_sect_name_dwarf_debug_abbrev(
- "__debug_abbrev");
- static ConstString g_sect_name_dwarf_debug_aranges(
- "__debug_aranges");
- static ConstString g_sect_name_dwarf_debug_frame(
- "__debug_frame");
- static ConstString g_sect_name_dwarf_debug_info(
- "__debug_info");
- static ConstString g_sect_name_dwarf_debug_line(
- "__debug_line");
- static ConstString g_sect_name_dwarf_debug_loc("__debug_loc");
- static ConstString g_sect_name_dwarf_debug_macinfo(
- "__debug_macinfo");
- static ConstString g_sect_name_dwarf_debug_pubnames(
- "__debug_pubnames");
- static ConstString g_sect_name_dwarf_debug_pubtypes(
- "__debug_pubtypes");
- static ConstString g_sect_name_dwarf_debug_ranges(
- "__debug_ranges");
- static ConstString g_sect_name_dwarf_debug_str("__debug_str");
- static ConstString g_sect_name_dwarf_apple_names(
- "__apple_names");
- static ConstString g_sect_name_dwarf_apple_types(
- "__apple_types");
- static ConstString g_sect_name_dwarf_apple_namespaces(
- "__apple_namespac");
- static ConstString g_sect_name_dwarf_apple_objc(
- "__apple_objc");
- static ConstString g_sect_name_eh_frame("__eh_frame");
- static ConstString g_sect_name_compact_unwind(
- "__unwind_info");
- static ConstString g_sect_name_text("__text");
- static ConstString g_sect_name_data("__data");
- static ConstString g_sect_name_go_symtab("__gosymtab");
+ // Make sure we've parsed the symbol table from the ObjectFile before
+ // we go around changing its Sections.
+ module_sp->GetObjectFile()->GetSymtab();
+ // eh_frame would present the same problems but we parse that on a per-
+ // function basis as-needed so it's more difficult to remove its use of
+ // the Sections. Realistically, the environments where this code path
+ // will be taken will not have eh_frame sections.
- if (section_name == g_sect_name_dwarf_debug_abbrev)
- sect_type = eSectionTypeDWARFDebugAbbrev;
- else if (section_name == g_sect_name_dwarf_debug_aranges)
- sect_type = eSectionTypeDWARFDebugAranges;
- else if (section_name == g_sect_name_dwarf_debug_frame)
- sect_type = eSectionTypeDWARFDebugFrame;
- else if (section_name == g_sect_name_dwarf_debug_info)
- sect_type = eSectionTypeDWARFDebugInfo;
- else if (section_name == g_sect_name_dwarf_debug_line)
- sect_type = eSectionTypeDWARFDebugLine;
- else if (section_name == g_sect_name_dwarf_debug_loc)
- sect_type = eSectionTypeDWARFDebugLoc;
- else if (section_name == g_sect_name_dwarf_debug_macinfo)
- sect_type = eSectionTypeDWARFDebugMacInfo;
- else if (section_name == g_sect_name_dwarf_debug_pubnames)
- sect_type = eSectionTypeDWARFDebugPubNames;
- else if (section_name == g_sect_name_dwarf_debug_pubtypes)
- sect_type = eSectionTypeDWARFDebugPubTypes;
- else if (section_name == g_sect_name_dwarf_debug_ranges)
- sect_type = eSectionTypeDWARFDebugRanges;
- else if (section_name == g_sect_name_dwarf_debug_str)
- sect_type = eSectionTypeDWARFDebugStr;
- else if (section_name == g_sect_name_dwarf_apple_names)
- sect_type = eSectionTypeDWARFAppleNames;
- else if (section_name == g_sect_name_dwarf_apple_types)
- sect_type = eSectionTypeDWARFAppleTypes;
- else if (section_name == g_sect_name_dwarf_apple_namespaces)
- sect_type = eSectionTypeDWARFAppleNamespaces;
- else if (section_name == g_sect_name_dwarf_apple_objc)
- sect_type = eSectionTypeDWARFAppleObjC;
- else if (section_name == g_sect_name_objc_selrefs)
- sect_type = eSectionTypeDataCStringPointers;
- else if (section_name == g_sect_name_objc_msgrefs)
- sect_type = eSectionTypeDataObjCMessageRefs;
- else if (section_name == g_sect_name_eh_frame)
- sect_type = eSectionTypeEHFrame;
- else if (section_name == g_sect_name_compact_unwind)
- sect_type = eSectionTypeCompactUnwind;
- else if (section_name == g_sect_name_cfstring)
- sect_type = eSectionTypeDataObjCCFStrings;
- else if (section_name == g_sect_name_go_symtab)
- sect_type = eSectionTypeGoSymtab;
- else if (section_name == g_sect_name_objc_data ||
- section_name == g_sect_name_objc_classrefs ||
- section_name == g_sect_name_objc_superrefs ||
- section_name == g_sect_name_objc_const ||
- section_name == g_sect_name_objc_classlist) {
- sect_type = eSectionTypeDataPointers;
- }
+ unified_section_sp->SetFileAddress(load_cmd.vmaddr);
- if (sect_type == eSectionTypeOther) {
- switch (mach_sect_type) {
- // TODO: categorize sections by other flags for regular
- // sections
- case S_REGULAR:
- if (section_name == g_sect_name_text)
- sect_type = eSectionTypeCode;
- else if (section_name == g_sect_name_data)
- sect_type = eSectionTypeData;
- else
- sect_type = eSectionTypeOther;
- break;
- case S_ZEROFILL:
- sect_type = eSectionTypeZeroFill;
- break;
- case S_CSTRING_LITERALS:
- sect_type = eSectionTypeDataCString;
- break; // section with only literal C strings
- case S_4BYTE_LITERALS:
- sect_type = eSectionTypeData4;
- break; // section with only 4 byte literals
- case S_8BYTE_LITERALS:
- sect_type = eSectionTypeData8;
- break; // section with only 8 byte literals
- case S_LITERAL_POINTERS:
- sect_type = eSectionTypeDataPointers;
- break; // section with only pointers to literals
- case S_NON_LAZY_SYMBOL_POINTERS:
- sect_type = eSectionTypeDataPointers;
- break; // section with only non-lazy symbol pointers
- case S_LAZY_SYMBOL_POINTERS:
- sect_type = eSectionTypeDataPointers;
- break; // section with only lazy symbol pointers
- case S_SYMBOL_STUBS:
- sect_type = eSectionTypeCode;
- break; // section with only symbol stubs, byte size of
- // stub in the reserved2 field
- case S_MOD_INIT_FUNC_POINTERS:
- sect_type = eSectionTypeDataPointers;
- break; // section with only function pointers for
- // initialization
- case S_MOD_TERM_FUNC_POINTERS:
- sect_type = eSectionTypeDataPointers;
- break; // section with only function pointers for
- // termination
- case S_COALESCED:
- sect_type = eSectionTypeOther;
- break;
- case S_GB_ZEROFILL:
- sect_type = eSectionTypeZeroFill;
- break;
- case S_INTERPOSING:
- sect_type = eSectionTypeCode;
- break; // section with only pairs of function pointers for
- // interposing
- case S_16BYTE_LITERALS:
- sect_type = eSectionTypeData16;
- break; // section with only 16 byte literals
- case S_DTRACE_DOF:
- sect_type = eSectionTypeDebug;
- break;
- case S_LAZY_DYLIB_SYMBOL_POINTERS:
- sect_type = eSectionTypeDataPointers;
- break;
- default:
- break;
- }
- }
- }
+ // Notify the module that the section addresses have been changed once
+ // we're done so any file-address caches can be updated.
+ context.FileAddressesChanged = true;
+ }
+ }
+ m_sections_ap->AddSection(unified_section_sp);
+ }
- SectionSP section_sp(new Section(
- segment_sp, module_sp, this, ++sectID, section_name,
- sect_type, sect64.addr - segment_sp->GetFileAddress(),
- sect64.size, sect64.offset,
- sect64.offset == 0 ? 0 : sect64.size, sect64.align,
- sect64.flags));
- // Set the section to be encrypted to match the segment
+ struct section_64 sect64;
+ ::memset(&sect64, 0, sizeof(sect64));
+ // Push a section into our mach sections for the section at index zero
+ // (NO_SECT) if we don't have any mach sections yet...
+ if (m_mach_sections.empty())
+ m_mach_sections.push_back(sect64);
+ uint32_t segment_sect_idx;
+ const lldb::user_id_t first_segment_sectID = context.NextSectionIdx + 1;
- bool section_is_encrypted = false;
- if (!segment_is_encrypted && load_cmd.filesize != 0)
- section_is_encrypted =
- encrypted_file_ranges.FindEntryThatContains(
- sect64.offset) != NULL;
+ const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8;
+ for (segment_sect_idx = 0; segment_sect_idx < load_cmd.nsects;
+ ++segment_sect_idx) {
+ if (m_data.GetU8(&offset, (uint8_t *)sect64.sectname,
+ sizeof(sect64.sectname)) == NULL)
+ break;
+ if (m_data.GetU8(&offset, (uint8_t *)sect64.segname,
+ sizeof(sect64.segname)) == NULL)
+ break;
+ sect64.addr = m_data.GetAddress(&offset);
+ sect64.size = m_data.GetAddress(&offset);
- section_sp->SetIsEncrypted(segment_is_encrypted ||
- section_is_encrypted);
- section_sp->SetPermissions(segment_permissions);
- segment_sp->GetChildren().AddSection(section_sp);
+ if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL)
+ break;
- if (segment_sp->IsFake()) {
- segment_sp.reset();
- const_segname.Clear();
- }
- }
- }
- if (segment_sp && is_dsym) {
- if (first_segment_sectID <= sectID) {
- lldb::user_id_t sect_uid;
- for (sect_uid = first_segment_sectID; sect_uid <= sectID;
- ++sect_uid) {
- SectionSP curr_section_sp(
- segment_sp->GetChildren().FindSectionByID(sect_uid));
- SectionSP next_section_sp;
- if (sect_uid + 1 <= sectID)
- next_section_sp =
- segment_sp->GetChildren().FindSectionByID(sect_uid + 1);
+ // Keep a list of mach sections around in case we need to get at data that
+ // isn't stored in the abstracted Sections.
+ m_mach_sections.push_back(sect64);
- if (curr_section_sp.get()) {
- if (curr_section_sp->GetByteSize() == 0) {
- if (next_section_sp.get() != NULL)
- curr_section_sp->SetByteSize(
- next_section_sp->GetFileAddress() -
- curr_section_sp->GetFileAddress());
- else
- curr_section_sp->SetByteSize(load_cmd.vmsize);
- }
- }
- }
- }
- }
+ if (add_section) {
+ ConstString section_name(
+ sect64.sectname,
+ std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname)));
+ if (!const_segname) {
+ // We have a segment with no name so we need to conjure up segments
+ // that correspond to the section's segname if there isn't already such
+ // a section. If there is such a section, we resize the section so that
+ // it spans all sections. We also mark these sections as fake so
+ // address matches don't hit if they land in the gaps between the child
+ // sections.
+ const_segname.SetTrimmedCStringWithLength(sect64.segname,
+ sizeof(sect64.segname));
+ segment_sp = context.UnifiedList.FindSectionByName(const_segname);
+ if (segment_sp.get()) {
+ Section *segment = segment_sp.get();
+ // Grow the section size as needed.
+ const lldb::addr_t sect64_min_addr = sect64.addr;
+ const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
+ const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();
+ const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();
+ const lldb::addr_t curr_seg_max_addr =
+ curr_seg_min_addr + curr_seg_byte_size;
+ if (sect64_min_addr >= curr_seg_min_addr) {
+ const lldb::addr_t new_seg_byte_size =
+ sect64_max_addr - curr_seg_min_addr;
+ // Only grow the section size if needed
+ if (new_seg_byte_size > curr_seg_byte_size)
+ segment->SetByteSize(new_seg_byte_size);
+ } else {
+ // We need to change the base address of the segment and adjust the
+ // child section offsets for all existing children.
+ const lldb::addr_t slide_amount =
+ sect64_min_addr - curr_seg_min_addr;
+ segment->Slide(slide_amount, false);
+ segment->GetChildren().Slide(-slide_amount, false);
+ segment->SetByteSize(curr_seg_max_addr - sect64_min_addr);
}
+
+ // Grow the section size as needed.
+ if (sect64.offset) {
+ const lldb::addr_t segment_min_file_offset =
+ segment->GetFileOffset();
+ const lldb::addr_t segment_max_file_offset =
+ segment_min_file_offset + segment->GetFileSize();
+
+ const lldb::addr_t section_min_file_offset = sect64.offset;
+ const lldb::addr_t section_max_file_offset =
+ section_min_file_offset + sect64.size;
+ const lldb::addr_t new_file_offset =
+ std::min(section_min_file_offset, segment_min_file_offset);
+ const lldb::addr_t new_file_size =
+ std::max(section_max_file_offset, segment_max_file_offset) -
+ new_file_offset;
+ segment->SetFileOffset(new_file_offset);
+ segment->SetFileSize(new_file_size);
+ }
+ } else {
+ // Create a fake section for the section's named segment
+ segment_sp.reset(new Section(
+ segment_sp, // Parent section
+ module_sp, // Module to which this section belongs
+ this, // Object file to which this section belongs
+ ++context.NextSegmentIdx
+ << 8, // Section ID is the 1 based segment index
+ // shifted right by 8 bits as not to
+ // collide with any of the 256 section IDs
+ // that are possible
+ const_segname, // Name of this section
+ eSectionTypeContainer, // This section is a container of
+ // other sections.
+ sect64.addr, // File VM address == addresses as they are
+ // found in the object file
+ sect64.size, // VM size in bytes of this section
+ sect64.offset, // Offset to the data for this section in
+ // the file
+ sect64.offset ? sect64.size : 0, // Size in bytes of
+ // this section as
+ // found in the file
+ sect64.align,
+ load_cmd.flags)); // Flags for this section
+ segment_sp->SetIsFake(true);
+ segment_sp->SetPermissions(segment_permissions);
+ m_sections_ap->AddSection(segment_sp);
+ if (add_to_unified)
+ context.UnifiedList.AddSection(segment_sp);
+ segment_sp->SetIsEncrypted(segment_is_encrypted);
}
- } else if (load_cmd.cmd == LC_DYSYMTAB) {
- m_dysymtab.cmd = load_cmd.cmd;
- m_dysymtab.cmdsize = load_cmd.cmdsize;
- m_data.GetU32(&offset, &m_dysymtab.ilocalsym,
- (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
}
+ assert(segment_sp.get());
+
+ lldb::SectionType sect_type = GetSectionType(sect64.flags, section_name);
- offset = load_cmd_offset + load_cmd.cmdsize;
+ SectionSP section_sp(new Section(
+ segment_sp, module_sp, this, ++context.NextSectionIdx, section_name,
+ sect_type, sect64.addr - segment_sp->GetFileAddress(), sect64.size,
+ sect64.offset, sect64.offset == 0 ? 0 : sect64.size, sect64.align,
+ sect64.flags));
+ // Set the section to be encrypted to match the segment
+
+ bool section_is_encrypted = false;
+ if (!segment_is_encrypted && load_cmd.filesize != 0)
+ section_is_encrypted = context.EncryptedRanges.FindEntryThatContains(
+ sect64.offset) != NULL;
+
+ section_sp->SetIsEncrypted(segment_is_encrypted || section_is_encrypted);
+ section_sp->SetPermissions(segment_permissions);
+ segment_sp->GetChildren().AddSection(section_sp);
+
+ if (segment_sp->IsFake()) {
+ segment_sp.reset();
+ const_segname.Clear();
+ }
}
+ }
+ if (segment_sp && is_dsym) {
+ if (first_segment_sectID <= context.NextSectionIdx) {
+ lldb::user_id_t sect_uid;
+ for (sect_uid = first_segment_sectID; sect_uid <= context.NextSectionIdx;
+ ++sect_uid) {
+ SectionSP curr_section_sp(
+ segment_sp->GetChildren().FindSectionByID(sect_uid));
+ SectionSP next_section_sp;
+ if (sect_uid + 1 <= context.NextSectionIdx)
+ next_section_sp =
+ segment_sp->GetChildren().FindSectionByID(sect_uid + 1);
- if (section_file_addresses_changed && module_sp.get()) {
- module_sp->SectionFileAddressesChanged();
+ if (curr_section_sp.get()) {
+ if (curr_section_sp->GetByteSize() == 0) {
+ if (next_section_sp.get() != NULL)
+ curr_section_sp->SetByteSize(next_section_sp->GetFileAddress() -
+ curr_section_sp->GetFileAddress());
+ else
+ curr_section_sp->SetByteSize(load_cmd.vmsize);
+ }
+ }
+ }
}
}
}
+void ObjectFileMachO::ProcessDysymtabCommand(const load_command &load_cmd,
+ lldb::offset_t offset) {
+ m_dysymtab.cmd = load_cmd.cmd;
+ m_dysymtab.cmdsize = load_cmd.cmdsize;
+ m_data.GetU32(&offset, &m_dysymtab.ilocalsym,
+ (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
+}
+
+void ObjectFileMachO::CreateSections(SectionList &unified_section_list) {
+ if (m_sections_ap)
+ return;
+
+ m_sections_ap.reset(new SectionList());
+
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ // bool dump_sections = false;
+ ModuleSP module_sp(GetModule());
+
+ offset = MachHeaderSizeFromMagic(m_header.magic);
+
+ SegmentParsingContext context(GetEncryptedFileRanges(), unified_section_list);
+ struct load_command load_cmd;
+ for (uint32_t i = 0; i < m_header.ncmds; ++i) {
+ const lldb::offset_t load_cmd_offset = offset;
+ if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
+ break;
+
+ if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64)
+ ProcessSegmentCommand(load_cmd, offset, i, context);
+ else if (load_cmd.cmd == LC_DYSYMTAB)
+ ProcessDysymtabCommand(load_cmd, offset);
+
+ offset = load_cmd_offset + load_cmd.cmdsize;
+ }
+
+ if (context.FileAddressesChanged && module_sp)
+ module_sp->SectionFileAddressesChanged();
+}
+
class MachSymtabSectionInfo {
public:
MachSymtabSectionInfo(SectionList *section_list)
: m_section_list(section_list), m_section_infos() {
- // Get the number of sections down to a depth of 1 to include
- // all segments and their sections, but no other sections that
- // may be added for debug map or
+ // Get the number of sections down to a depth of 1 to include all segments
+ // and their sections, but no other sections that may be added for debug
+ // map or
m_section_infos.resize(section_list->GetNumSections(1));
}
@@ -1956,9 +1935,9 @@ public:
} else if (m_section_infos[n_sect].vm_range.GetByteSize() == 0 &&
m_section_infos[n_sect].vm_range.GetBaseAddress() ==
file_addr) {
- // Symbol is in section with zero size, but has the same start
- // address as the section. This can happen with linker symbols
- // (symbols that start with the letter 'l' or 'L'.
+ // Symbol is in section with zero size, but has the same start address
+ // as the section. This can happen with linker symbols (symbols that
+ // start with the letter 'l' or 'L'.
return m_section_infos[n_sect].section_sp;
}
}
@@ -2108,10 +2087,13 @@ UUID ObjectFileMachO::GetSharedCacheUUID(FileSpec dyld_shared_cache,
version_str[6] = '\0';
if (strcmp(version_str, "dyld_v") == 0) {
offset = offsetof(struct lldb_copy_dyld_cache_header_v1, uuid);
- uint8_t uuid_bytes[sizeof(uuid_t)];
- memcpy(uuid_bytes, dsc_header_data.GetData(&offset, sizeof(uuid_t)),
- sizeof(uuid_t));
- dsc_uuid.SetBytes(uuid_bytes);
+ dsc_uuid = UUID::fromOptionalData(
+ dsc_header_data.GetData(&offset, sizeof(uuid_t)), sizeof(uuid_t));
+ }
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS));
+ if (log && dsc_uuid.IsValid()) {
+ log->Printf("Shared cache %s has UUID %s", dyld_shared_cache.GetPath().c_str(),
+ dsc_uuid.GetAsString().c_str());
}
return dsc_uuid;
}
@@ -2267,10 +2249,9 @@ size_t ObjectFileMachO::ParseSymtab() {
linkedit_section_sp->GetLoadBaseAddress(&target);
if (linkedit_load_addr == LLDB_INVALID_ADDRESS) {
// We might be trying to access the symbol table before the
- // __LINKEDIT's load
- // address has been set in the target. We can't fail to read the
- // symbol table,
- // so calculate the right address manually
+ // __LINKEDIT's load address has been set in the target. We can't
+ // fail to read the symbol table, so calculate the right address
+ // manually
linkedit_load_addr = CalculateSectionLoadAddressForMemoryImage(
m_memory_addr, GetMachHeaderSection(), linkedit_section_sp.get());
}
@@ -2291,8 +2272,8 @@ size_t ObjectFileMachO::ParseSymtab() {
process->GetAddressByteSize() == sizeof(void *)) {
// This mach-o memory file is in the dyld shared cache. If this
// program is not remote and this is iOS, then this process will
- // share the same shared cache as the process we are debugging and
- // we can read the entire __LINKEDIT from the address space in this
+ // share the same shared cache as the process we are debugging and we
+ // can read the entire __LINKEDIT from the address space in this
// process. This is a needed optimization that is used for local iOS
// debugging only since all shared libraries in the shared cache do
// not have corresponding files that exist in the file system of the
@@ -2301,22 +2282,21 @@ size_t ObjectFileMachO::ParseSymtab() {
// string tables from all of the __LINKEDIT sections from the shared
// libraries in the shared cache have been merged into a single large
// symbol and string table. Reading all of this symbol and string
- // table
- // data across can slow down debug launch times, so we optimize this
- // by
- // reading the memory for the __LINKEDIT section from this process.
+ // table data across can slow down debug launch times, so we optimize
+ // this by reading the memory for the __LINKEDIT section from this
+ // process.
- UUID lldb_shared_cache(GetLLDBSharedCacheUUID());
- UUID process_shared_cache(GetProcessSharedCacheUUID(process));
+ UUID lldb_shared_cache;
+ addr_t lldb_shared_cache_addr;
+ GetLLDBSharedCacheUUID (lldb_shared_cache_addr, lldb_shared_cache);
+ UUID process_shared_cache;
+ addr_t process_shared_cache_addr;
+ GetProcessSharedCacheUUID(process, process_shared_cache_addr, process_shared_cache);
bool use_lldb_cache = true;
if (lldb_shared_cache.IsValid() && process_shared_cache.IsValid() &&
- lldb_shared_cache != process_shared_cache) {
+ (lldb_shared_cache != process_shared_cache
+ || process_shared_cache_addr != lldb_shared_cache_addr)) {
use_lldb_cache = false;
- ModuleSP module_sp(GetModule());
- if (module_sp)
- module_sp->ReportWarning("shared cache in process does not match "
- "lldb's own shared cache, startup will "
- "be slow.");
}
PlatformSP platform_sp(target.GetPlatform());
@@ -2340,10 +2320,9 @@ size_t ObjectFileMachO::ParseSymtab() {
if (!data_was_read) {
// Always load dyld - the dynamic linker - from memory if we didn't
- // find a binary anywhere else.
- // lldb will not register dylib/framework/bundle loads/unloads if we
- // don't have the dyld symbols,
- // we force dyld to load from memory despite the user's
+ // find a binary anywhere else. lldb will not register
+ // dylib/framework/bundle loads/unloads if we don't have the dyld
+ // symbols, we force dyld to load from memory despite the user's
// target.memory-module-load-level setting.
if (memory_module_load_level == eMemoryModuleLoadLevelComplete ||
m_header.filetype == llvm::MachO::MH_DYLINKER) {
@@ -2353,10 +2332,9 @@ size_t ObjectFileMachO::ParseSymtab() {
nlist_data.SetData(nlist_data_sp, 0,
nlist_data_sp->GetByteSize());
// Load strings individually from memory when loading from memory
- // since shared cache
- // string tables contain strings for all symbols from all shared
- // cached libraries
- // DataBufferSP strtab_data_sp (ReadMemory (process_sp, strtab_addr,
+ // since shared cache string tables contain strings for all symbols
+ // from all shared cached libraries DataBufferSP strtab_data_sp
+ // (ReadMemory (process_sp, strtab_addr,
// strtab_data_byte_size));
// if (strtab_data_sp)
// strtab_data.SetData (strtab_data_sp, 0,
@@ -2460,11 +2438,9 @@ size_t ObjectFileMachO::ParseSymtab() {
const bool is_arm = (m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
// lldb works best if it knows the start address of all functions in a
- // module.
- // Linker symbols or debug info are normally the best source of information
- // for start addr / size but
- // they may be stripped in a released binary.
- // Two additional sources of information exist in Mach-O binaries:
+ // module. Linker symbols or debug info are normally the best source of
+ // information for start addr / size but they may be stripped in a released
+ // binary. Two additional sources of information exist in Mach-O binaries:
// LC_FUNCTION_STARTS - a list of ULEB128 encoded offsets of each
// function's start address in the
// binary, relative to the text section.
@@ -2489,12 +2465,10 @@ size_t ObjectFileMachO::ParseSymtab() {
}
} else {
// If m_type is eTypeDebugInfo, then this is a dSYM - it will have the
- // load command claiming an eh_frame
- // but it doesn't actually have the eh_frame content. And if we have a
- // dSYM, we don't need to do any
- // of this fill-in-the-missing-symbols works anyway - the debug info
- // should give us all the functions in
- // the module.
+ // load command claiming an eh_frame but it doesn't actually have the
+ // eh_frame content. And if we have a dSYM, we don't need to do any of
+ // this fill-in-the-missing-symbols works anyway - the debug info should
+ // give us all the functions in the module.
if (text_section_sp.get() && eh_frame_section_sp.get() &&
m_type != eTypeDebugInfo) {
DWARFCallFrameInfo eh_frame(*this, eh_frame_section_sp,
@@ -2518,18 +2492,14 @@ size_t ObjectFileMachO::ParseSymtab() {
const size_t function_starts_count = function_starts.GetSize();
// For user process binaries (executables, dylibs, frameworks, bundles), if
- // we don't have
- // LC_FUNCTION_STARTS/eh_frame section in this binary, we're going to assume
- // the binary
- // has been stripped. Don't allow assembly language instruction emulation
- // because we don't
- // know proper function start boundaries.
+ // we don't have LC_FUNCTION_STARTS/eh_frame section in this binary, we're
+ // going to assume the binary has been stripped. Don't allow assembly
+ // language instruction emulation because we don't know proper function
+ // start boundaries.
//
// For all other types of binaries (kernels, stand-alone bare board
- // binaries, kexts), they
- // may not have LC_FUNCTION_STARTS / eh_frame sections - we should not make
- // any assumptions
- // about them based on that.
+ // binaries, kexts), they may not have LC_FUNCTION_STARTS / eh_frame
+ // sections - we should not make any assumptions about them based on that.
if (function_starts_count == 0 && CalculateStrata() == eStrataUser) {
m_allow_assembly_emulation_unwind_plans = false;
Log *unwind_or_symbol_log(lldb_private::GetLogIfAnyCategoriesSet(
@@ -2561,8 +2531,8 @@ size_t ObjectFileMachO::ParseSymtab() {
ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
- // Any symbols that get merged into another will get an entry
- // in this map so we know
+ // Any symbols that get merged into another will get an entry in this map
+ // so we know
NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
uint32_t nlist_idx = 0;
Symbol *symbol_ptr = NULL;
@@ -2601,21 +2571,18 @@ size_t ObjectFileMachO::ParseSymtab() {
(defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
// Some recent builds of the dyld_shared_cache (hereafter: DSC) have been
- // optimized by moving LOCAL
- // symbols out of the memory mapped portion of the DSC. The symbol
- // information has all been retained,
- // but it isn't available in the normal nlist data. However, there *are*
- // duplicate entries of *some*
+ // optimized by moving LOCAL symbols out of the memory mapped portion of
+ // the DSC. The symbol information has all been retained, but it isn't
+ // available in the normal nlist data. However, there *are* duplicate
+ // entries of *some*
// LOCAL symbols in the normal nlist data. To handle this situation
// correctly, we must first attempt
// to parse any DSC unmapped symbol information. If we find any, we set a
- // flag that tells the normal
- // nlist parser to ignore all LOCAL symbols.
+ // flag that tells the normal nlist parser to ignore all LOCAL symbols.
if (m_header.flags & 0x80000000u) {
- // Before we can start mapping the DSC, we need to make certain the target
- // process is actually
- // using the cache we can find.
+ // Before we can start mapping the DSC, we need to make certain the
+ // target process is actually using the cache we can find.
// Next we need to determine the correct path for the dyld shared cache.
@@ -2644,14 +2611,15 @@ size_t ObjectFileMachO::ParseSymtab() {
UUID dsc_uuid;
UUID process_shared_cache_uuid;
+ addr_t process_shared_cache_base_addr;
if (process) {
- process_shared_cache_uuid = GetProcessSharedCacheUUID(process);
+ GetProcessSharedCacheUUID(process, process_shared_cache_base_addr, process_shared_cache_uuid);
}
- // First see if we can find an exact match for the inferior process shared
- // cache UUID in
- // the development or non-development shared caches on disk.
+ // First see if we can find an exact match for the inferior process
+ // shared cache UUID in the development or non-development shared caches
+ // on disk.
if (process_shared_cache_uuid.IsValid()) {
if (dsc_development_filespec.Exists()) {
UUID dsc_development_uuid = GetSharedCacheUUID(
@@ -2716,8 +2684,7 @@ size_t ObjectFileMachO::ParseSymtab() {
if (process_shared_cache_uuid.IsValid() &&
dsc_uuid != process_shared_cache_uuid) {
// The on-disk dyld_shared_cache file is not the same as the one in
- // this
- // process' memory, don't use it.
+ // this process' memory, don't use it.
uuid_match = false;
ModuleSP module_sp(GetModule());
if (module_sp)
@@ -2745,11 +2712,9 @@ size_t ObjectFileMachO::ParseSymtab() {
offset = 0;
// The File addresses (from the in-memory Mach-O load commands) for
- // the shared libraries
- // in the shared library cache need to be adjusted by an offset to
- // match up with the
- // dylibOffset identifying field in the
- // dyld_cache_local_symbol_entry's. This offset is
+ // the shared libraries in the shared library cache need to be
+ // adjusted by an offset to match up with the dylibOffset identifying
+ // field in the dyld_cache_local_symbol_entry's. This offset is
// recorded in mapping_offset_value.
const uint64_t mapping_offset_value =
dsc_mapping_info_data.GetU64(&offset);
@@ -2843,8 +2808,8 @@ size_t ObjectFileMachO::ParseSymtab() {
if (symbol_name == NULL) {
// No symbol should be NULL, even the symbols with no
- // string values should have an offset zero which points
- // to an empty C-string
+ // string values should have an offset zero which
+ // points to an empty C-string
Host::SystemLog(
Host::eSystemLogError,
"error: DSC unmapped local symbol[%u] has invalid "
@@ -2879,14 +2844,13 @@ size_t ObjectFileMachO::ParseSymtab() {
// FIXME: In the .o files, we have a GSYM and a debug
// symbol for all the ObjC data. They
// have the same address, but we want to ensure that
- // we always find only the real symbol,
- // 'cause we don't currently correctly attribute the
+ // we always find only the real symbol, 'cause we
+ // don't currently correctly attribute the
// GSYM one to the ObjCClass/Ivar/MetaClass
- // symbol type. This is a temporary hack to make sure
- // the ObjectiveC symbols get treated
- // correctly. To do this right, we should coalesce
- // all the GSYM & global symbols that have the
- // same address.
+ // symbol type. This is a temporary hack to make
+ // sure the ObjectiveC symbols get treated correctly.
+ // To do this right, we should coalesce all the GSYM
+ // & global symbols that have the same address.
is_gsym = true;
sym[sym_idx].SetExternal(true);
@@ -2940,25 +2904,24 @@ size_t ObjectFileMachO::ParseSymtab() {
N_FUN_addr_to_sym_idx.insert(
std::make_pair(nlist.n_value, sym_idx));
// We use the current number of symbols in the
- // symbol table in lieu of
- // using nlist_idx in case we ever start trimming
- // entries out
+ // symbol table in lieu of using nlist_idx in case
+ // we ever start trimming entries out
N_FUN_indexes.push_back(sym_idx);
} else {
type = eSymbolTypeCompiler;
if (!N_FUN_indexes.empty()) {
- // Copy the size of the function into the original
+ // Copy the size of the function into the
+ // original
// STAB entry so we don't have
// to hunt for it later
symtab->SymbolAtIndex(N_FUN_indexes.back())
->SetByteSize(nlist.n_value);
N_FUN_indexes.pop_back();
// We don't really need the end function STAB as
- // it contains the size which
- // we already placed with the original symbol, so
- // don't add it if we want a
- // minimal symbol table
+ // it contains the size which we already placed
+ // with the original symbol, so don't add it if
+ // we want a minimal symbol table
add_nlist = false;
}
}
@@ -2985,19 +2948,17 @@ size_t ObjectFileMachO::ParseSymtab() {
case N_BNSYM:
// We use the current number of symbols in the symbol
- // table in lieu of
- // using nlist_idx in case we ever start trimming
- // entries out
- // Skip these if we want minimal symbol tables
+ // table in lieu of using nlist_idx in case we ever
+ // start trimming entries out Skip these if we want
+ // minimal symbol tables
add_nlist = false;
break;
case N_ENSYM:
// Set the size of the N_BNSYM to the terminating
- // index of this N_ENSYM
- // so that we can always skip the entire symbol if we
- // need to navigate
- // more quickly at the source level when parsing STABS
+ // index of this N_ENSYM so that we can always skip
+ // the entire symbol if we need to navigate more
+ // quickly at the source level when parsing STABS
// Skip these if we want minimal symbol tables
add_nlist = false;
break;
@@ -3031,11 +2992,9 @@ size_t ObjectFileMachO::ParseSymtab() {
add_nlist = false;
if (N_SO_index != UINT32_MAX) {
// Set the size of the N_SO to the terminating
- // index of this N_SO
- // so that we can always skip the entire N_SO if
- // we need to navigate
- // more quickly at the source level when parsing
- // STABS
+ // index of this N_SO so that we can always skip
+ // the entire N_SO if we need to navigate more
+ // quickly at the source level when parsing STABS
symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
symbol_ptr->SetByteSize(sym_idx);
symbol_ptr->SetSizeIsSibling(true);
@@ -3048,17 +3007,16 @@ size_t ObjectFileMachO::ParseSymtab() {
N_SO_index = UINT32_MAX;
} else {
// We use the current number of symbols in the
- // symbol table in lieu of
- // using nlist_idx in case we ever start trimming
- // entries out
+ // symbol table in lieu of using nlist_idx in case
+ // we ever start trimming entries out
const bool N_SO_has_full_path =
symbol_name[0] == '/';
if (N_SO_has_full_path) {
if ((N_SO_index == sym_idx - 1) &&
((sym_idx - 1) < num_syms)) {
// We have two consecutive N_SO entries where
- // the first contains a directory
- // and the second contains a full path.
+ // the first contains a directory and the
+ // second contains a full path.
sym[sym_idx - 1].GetMangled().SetValue(
ConstString(symbol_name), false);
m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
@@ -3072,9 +3030,9 @@ size_t ObjectFileMachO::ParseSymtab() {
} else if ((N_SO_index == sym_idx - 1) &&
((sym_idx - 1) < num_syms)) {
// This is usually the second N_SO entry that
- // contains just the filename,
- // so here we combine it with the first one if we
- // are minimizing the symbol table
+ // contains just the filename, so here we combine
+ // it with the first one if we are minimizing the
+ // symbol table
const char *so_path =
sym[sym_idx - 1]
.GetMangled()
@@ -3088,11 +3046,11 @@ size_t ObjectFileMachO::ParseSymtab() {
if (double_slash_pos != std::string::npos) {
// The linker has been generating bad N_SO
// entries with doubled up paths
- // in the format "%s%s" where the first string
- // in the DW_AT_comp_dir,
- // and the second is the directory for the
- // source file so you end up with
- // a path that looks like "/tmp/src//tmp/src/"
+ // in the format "%s%s" where the first
+ // string in the DW_AT_comp_dir, and the
+ // second is the directory for the source
+ // file so you end up with a path that looks
+ // like "/tmp/src//tmp/src/"
FileSpec so_dir(so_path, false);
if (!so_dir.Exists()) {
so_dir.SetFile(
@@ -3134,11 +3092,10 @@ size_t ObjectFileMachO::ParseSymtab() {
// INCL scopes
//----------------------------------------------------------------------
case N_BINCL:
- // include file beginning: name,,NO_SECT,0,sum
- // We use the current number of symbols in the symbol
- // table in lieu of
- // using nlist_idx in case we ever start trimming
- // entries out
+ // include file beginning: name,,NO_SECT,0,sum We use
+ // the current number of symbols in the symbol table
+ // in lieu of using nlist_idx in case we ever start
+ // trimming entries out
N_INCL_indexes.push_back(sym_idx);
type = eSymbolTypeScopeBegin;
break;
@@ -3146,10 +3103,9 @@ size_t ObjectFileMachO::ParseSymtab() {
case N_EINCL:
// include file end: name,,NO_SECT,0,0
// Set the size of the N_BINCL to the terminating
- // index of this N_EINCL
- // so that we can always skip the entire symbol if we
- // need to navigate
- // more quickly at the source level when parsing STABS
+ // index of this N_EINCL so that we can always skip
+ // the entire symbol if we need to navigate more
+ // quickly at the source level when parsing STABS
if (!N_INCL_indexes.empty()) {
symbol_ptr =
symtab->SymbolAtIndex(N_INCL_indexes.back());
@@ -3199,11 +3155,10 @@ size_t ObjectFileMachO::ParseSymtab() {
// Left and Right Braces
//----------------------------------------------------------------------
case N_LBRAC:
- // left bracket: 0,,NO_SECT,nesting level,address
- // We use the current number of symbols in the symbol
- // table in lieu of
- // using nlist_idx in case we ever start trimming
- // entries out
+ // left bracket: 0,,NO_SECT,nesting level,address We
+ // use the current number of symbols in the symbol
+ // table in lieu of using nlist_idx in case we ever
+ // start trimming entries out
symbol_section = section_info.GetSection(
nlist.n_sect, nlist.n_value);
N_BRAC_indexes.push_back(sym_idx);
@@ -3213,10 +3168,9 @@ size_t ObjectFileMachO::ParseSymtab() {
case N_RBRAC:
// right bracket: 0,,NO_SECT,nesting level,address
// Set the size of the N_LBRAC to the terminating
- // index of this N_RBRAC
- // so that we can always skip the entire symbol if we
- // need to navigate
- // more quickly at the source level when parsing STABS
+ // index of this N_RBRAC so that we can always skip
+ // the entire symbol if we need to navigate more
+ // quickly at the source level when parsing STABS
symbol_section = section_info.GetSection(
nlist.n_sect, nlist.n_value);
if (!N_BRAC_indexes.empty()) {
@@ -3240,9 +3194,8 @@ size_t ObjectFileMachO::ParseSymtab() {
case N_BCOMM:
// begin common: name,,NO_SECT,0,0
// We use the current number of symbols in the symbol
- // table in lieu of
- // using nlist_idx in case we ever start trimming
- // entries out
+ // table in lieu of using nlist_idx in case we ever
+ // start trimming entries out
type = eSymbolTypeScopeBegin;
N_COMM_indexes.push_back(sym_idx);
break;
@@ -3256,10 +3209,10 @@ size_t ObjectFileMachO::ParseSymtab() {
case N_ECOMM:
// end common: name,,n_sect,0,0
// Set the size of the N_BCOMM to the terminating
- // index of this N_ECOMM/N_ECOML
- // so that we can always skip the entire symbol if we
- // need to navigate
- // more quickly at the source level when parsing STABS
+ // index of this N_ECOMM/N_ECOML so that we can
+ // always skip the entire symbol if we need to
+ // navigate more quickly at the source level when
+ // parsing STABS
if (!N_COMM_indexes.empty()) {
symbol_ptr =
symtab->SymbolAtIndex(N_COMM_indexes.back());
@@ -3549,16 +3502,16 @@ size_t ObjectFileMachO::ParseSymtab() {
function_starts_count > 0) {
addr_t symbol_lookup_file_addr = nlist.n_value;
// Do an exact address match for non-ARM addresses,
- // else get the closest since
- // the symbol might be a thumb symbol which has an
- // address with bit zero set
+ // else get the closest since the symbol might be a
+ // thumb symbol which has an address with bit zero
+ // set
FunctionStarts::Entry *func_start_entry =
function_starts.FindEntry(
symbol_lookup_file_addr, !is_arm);
if (is_arm && func_start_entry) {
// Verify that the function start address is the
- // symbol address (ARM)
- // or the symbol address + 1 (thumb)
+ // symbol address (ARM) or the symbol address + 1
+ // (thumb)
if (func_start_entry->addr !=
symbol_lookup_file_addr &&
func_start_entry->addr !=
@@ -3590,8 +3543,8 @@ size_t ObjectFileMachO::ParseSymtab() {
addr_t next_symbol_file_addr =
next_func_start_entry->addr;
// Be sure the clear the Thumb address bit when
- // we calculate the size
- // from the current and next address
+ // we calculate the size from the current and
+ // next address
if (is_arm)
next_symbol_file_addr &=
THUMB_ADDRESS_BIT_MASK;
@@ -3610,12 +3563,10 @@ size_t ObjectFileMachO::ParseSymtab() {
if (is_debug == false) {
if (type == eSymbolTypeCode) {
// See if we can find a N_FUN entry for any code
- // symbols.
- // If we do find a match, and the name matches, then
- // we
- // can merge the two into just the function symbol
- // to avoid
- // duplicate entries in the symbol table
+ // symbols. If we do find a match, and the name
+ // matches, then we can merge the two into just the
+ // function symbol to avoid duplicate entries in
+ // the symbol table
std::pair<ValueToSymbolIndexMap::const_iterator,
ValueToSymbolIndexMap::const_iterator>
range;
@@ -3663,12 +3614,10 @@ size_t ObjectFileMachO::ParseSymtab() {
type == eSymbolTypeObjCMetaClass ||
type == eSymbolTypeObjCIVar) {
// See if we can find a N_STSYM entry for any data
- // symbols.
- // If we do find a match, and the name matches, then
- // we
- // can merge the two into just the Static symbol to
- // avoid
- // duplicate entries in the symbol table
+ // symbols. If we do find a match, and the name
+ // matches, then we can merge the two into just the
+ // Static symbol to avoid duplicate entries in the
+ // symbol table
std::pair<ValueToSymbolIndexMap::const_iterator,
ValueToSymbolIndexMap::const_iterator>
range;
@@ -3710,8 +3659,8 @@ size_t ObjectFileMachO::ParseSymtab() {
Mangled::ePreferMangled)
.GetCString();
if (gsym_name) {
- // Combine N_GSYM stab entries with the non stab
- // symbol
+ // Combine N_GSYM stab entries with the non
+ // stab symbol
ConstNameToSymbolIndexMap::const_iterator pos =
N_GSYM_name_to_sym_idx.find(gsym_name);
if (pos != N_GSYM_name_to_sym_idx.end()) {
@@ -3827,9 +3776,8 @@ size_t ObjectFileMachO::ParseSymtab() {
symbol_name = strtab_data.PeekCStr(nlist.n_strx);
if (symbol_name == NULL) {
- // No symbol should be NULL, even the symbols with no
- // string values should have an offset zero which points
- // to an empty C-string
+ // No symbol should be NULL, even the symbols with no string values
+ // should have an offset zero which points to an empty C-string
Host::SystemLog(Host::eSystemLogError,
"error: symbol[%u] has invalid string table offset "
"0x%x in %s, ignoring symbol\n",
@@ -3868,14 +3816,12 @@ size_t ObjectFileMachO::ParseSymtab() {
// FIXME: In the .o files, we have a GSYM and a debug symbol for all
// the ObjC data. They
// have the same address, but we want to ensure that we always find
- // only the real symbol,
- // 'cause we don't currently correctly attribute the GSYM one to the
- // ObjCClass/Ivar/MetaClass
- // symbol type. This is a temporary hack to make sure the
- // ObjectiveC symbols get treated
- // correctly. To do this right, we should coalesce all the GSYM &
- // global symbols that have the
- // same address.
+ // only the real symbol, 'cause we don't currently correctly
+ // attribute the GSYM one to the ObjCClass/Ivar/MetaClass symbol
+ // type. This is a temporary hack to make sure the ObjectiveC
+ // symbols get treated correctly. To do this right, we should
+ // coalesce all the GSYM & global symbols that have the same
+ // address.
is_gsym = true;
sym[sym_idx].SetExternal(true);
@@ -3922,24 +3868,21 @@ size_t ObjectFileMachO::ParseSymtab() {
N_FUN_addr_to_sym_idx.insert(
std::make_pair(nlist.n_value, sym_idx));
// We use the current number of symbols in the symbol table in
- // lieu of
- // using nlist_idx in case we ever start trimming entries out
+ // lieu of using nlist_idx in case we ever start trimming entries
+ // out
N_FUN_indexes.push_back(sym_idx);
} else {
type = eSymbolTypeCompiler;
if (!N_FUN_indexes.empty()) {
- // Copy the size of the function into the original STAB entry so
- // we don't have
- // to hunt for it later
+ // Copy the size of the function into the original STAB entry
+ // so we don't have to hunt for it later
symtab->SymbolAtIndex(N_FUN_indexes.back())
->SetByteSize(nlist.n_value);
N_FUN_indexes.pop_back();
- // We don't really need the end function STAB as it contains the
- // size which
- // we already placed with the original symbol, so don't add it
- // if we want a
- // minimal symbol table
+ // We don't really need the end function STAB as it contains
+ // the size which we already placed with the original symbol,
+ // so don't add it if we want a minimal symbol table
add_nlist = false;
}
}
@@ -3966,18 +3909,15 @@ size_t ObjectFileMachO::ParseSymtab() {
case N_BNSYM:
// We use the current number of symbols in the symbol table in lieu
- // of
- // using nlist_idx in case we ever start trimming entries out
+ // of using nlist_idx in case we ever start trimming entries out
// Skip these if we want minimal symbol tables
add_nlist = false;
break;
case N_ENSYM:
// Set the size of the N_BNSYM to the terminating index of this
- // N_ENSYM
- // so that we can always skip the entire symbol if we need to
- // navigate
- // more quickly at the source level when parsing STABS
+ // N_ENSYM so that we can always skip the entire symbol if we need
+ // to navigate more quickly at the source level when parsing STABS
// Skip these if we want minimal symbol tables
add_nlist = false;
break;
@@ -4011,10 +3951,9 @@ size_t ObjectFileMachO::ParseSymtab() {
add_nlist = false;
if (N_SO_index != UINT32_MAX) {
// Set the size of the N_SO to the terminating index of this
- // N_SO
- // so that we can always skip the entire N_SO if we need to
- // navigate
- // more quickly at the source level when parsing STABS
+ // N_SO so that we can always skip the entire N_SO if we need
+ // to navigate more quickly at the source level when parsing
+ // STABS
symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
symbol_ptr->SetByteSize(sym_idx);
symbol_ptr->SetSizeIsSibling(true);
@@ -4027,30 +3966,27 @@ size_t ObjectFileMachO::ParseSymtab() {
N_SO_index = UINT32_MAX;
} else {
// We use the current number of symbols in the symbol table in
- // lieu of
- // using nlist_idx in case we ever start trimming entries out
+ // lieu of using nlist_idx in case we ever start trimming entries
+ // out
const bool N_SO_has_full_path = symbol_name[0] == '/';
if (N_SO_has_full_path) {
if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
// We have two consecutive N_SO entries where the first
- // contains a directory
- // and the second contains a full path.
+ // contains a directory and the second contains a full path.
sym[sym_idx - 1].GetMangled().SetValue(
ConstString(symbol_name), false);
m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
add_nlist = false;
} else {
- // This is the first entry in a N_SO that contains a directory
- // or
- // a full path to the source file
+ // This is the first entry in a N_SO that contains a
+ // directory or a full path to the source file
N_SO_index = sym_idx;
}
} else if ((N_SO_index == sym_idx - 1) &&
((sym_idx - 1) < num_syms)) {
// This is usually the second N_SO entry that contains just the
- // filename,
- // so here we combine it with the first one if we are minimizing
- // the symbol table
+ // filename, so here we combine it with the first one if we are
+ // minimizing the symbol table
const char *so_path =
sym[sym_idx - 1]
.GetMangled()
@@ -4061,16 +3997,14 @@ size_t ObjectFileMachO::ParseSymtab() {
const size_t double_slash_pos = full_so_path.find("//");
if (double_slash_pos != std::string::npos) {
// The linker has been generating bad N_SO entries with
- // doubled up paths
- // in the format "%s%s" where the first string in the
- // DW_AT_comp_dir,
- // and the second is the directory for the source file so
- // you end up with
- // a path that looks like "/tmp/src//tmp/src/"
+ // doubled up paths in the format "%s%s" where the first
+ // string in the DW_AT_comp_dir, and the second is the
+ // directory for the source file so you end up with a path
+ // that looks like "/tmp/src//tmp/src/"
FileSpec so_dir(so_path, false);
if (!so_dir.Exists()) {
- so_dir.SetFile(&full_so_path[double_slash_pos + 1],
- false);
+ so_dir.SetFile(&full_so_path[double_slash_pos + 1], false,
+ FileSpec::Style::native);
if (so_dir.Exists()) {
// Trim off the incorrect path
full_so_path.erase(0, double_slash_pos + 1);
@@ -4106,10 +4040,9 @@ size_t ObjectFileMachO::ParseSymtab() {
// INCL scopes
//----------------------------------------------------------------------
case N_BINCL:
- // include file beginning: name,,NO_SECT,0,sum
- // We use the current number of symbols in the symbol table in lieu
- // of
- // using nlist_idx in case we ever start trimming entries out
+ // include file beginning: name,,NO_SECT,0,sum We use the current
+ // number of symbols in the symbol table in lieu of using nlist_idx
+ // in case we ever start trimming entries out
N_INCL_indexes.push_back(sym_idx);
type = eSymbolTypeScopeBegin;
break;
@@ -4117,10 +4050,8 @@ size_t ObjectFileMachO::ParseSymtab() {
case N_EINCL:
// include file end: name,,NO_SECT,0,0
// Set the size of the N_BINCL to the terminating index of this
- // N_EINCL
- // so that we can always skip the entire symbol if we need to
- // navigate
- // more quickly at the source level when parsing STABS
+ // N_EINCL so that we can always skip the entire symbol if we need
+ // to navigate more quickly at the source level when parsing STABS
if (!N_INCL_indexes.empty()) {
symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
symbol_ptr->SetByteSize(sym_idx + 1);
@@ -4169,10 +4100,9 @@ size_t ObjectFileMachO::ParseSymtab() {
// Left and Right Braces
//----------------------------------------------------------------------
case N_LBRAC:
- // left bracket: 0,,NO_SECT,nesting level,address
- // We use the current number of symbols in the symbol table in lieu
- // of
- // using nlist_idx in case we ever start trimming entries out
+ // left bracket: 0,,NO_SECT,nesting level,address We use the
+ // current number of symbols in the symbol table in lieu of using
+ // nlist_idx in case we ever start trimming entries out
symbol_section =
section_info.GetSection(nlist.n_sect, nlist.n_value);
N_BRAC_indexes.push_back(sym_idx);
@@ -4180,12 +4110,10 @@ size_t ObjectFileMachO::ParseSymtab() {
break;
case N_RBRAC:
- // right bracket: 0,,NO_SECT,nesting level,address
- // Set the size of the N_LBRAC to the terminating index of this
- // N_RBRAC
- // so that we can always skip the entire symbol if we need to
- // navigate
- // more quickly at the source level when parsing STABS
+ // right bracket: 0,,NO_SECT,nesting level,address Set the size of
+ // the N_LBRAC to the terminating index of this N_RBRAC so that we
+ // can always skip the entire symbol if we need to navigate more
+ // quickly at the source level when parsing STABS
symbol_section =
section_info.GetSection(nlist.n_sect, nlist.n_value);
if (!N_BRAC_indexes.empty()) {
@@ -4208,8 +4136,7 @@ size_t ObjectFileMachO::ParseSymtab() {
case N_BCOMM:
// begin common: name,,NO_SECT,0,0
// We use the current number of symbols in the symbol table in lieu
- // of
- // using nlist_idx in case we ever start trimming entries out
+ // of using nlist_idx in case we ever start trimming entries out
type = eSymbolTypeScopeBegin;
N_COMM_indexes.push_back(sym_idx);
break;
@@ -4223,10 +4150,9 @@ size_t ObjectFileMachO::ParseSymtab() {
case N_ECOMM:
// end common: name,,n_sect,0,0
// Set the size of the N_BCOMM to the terminating index of this
- // N_ECOMM/N_ECOML
- // so that we can always skip the entire symbol if we need to
- // navigate
- // more quickly at the source level when parsing STABS
+ // N_ECOMM/N_ECOML so that we can always skip the entire symbol if
+ // we need to navigate more quickly at the source level when
+ // parsing STABS
if (!N_COMM_indexes.empty()) {
symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
symbol_ptr->SetByteSize(sym_idx + 1);
@@ -4486,15 +4412,13 @@ size_t ObjectFileMachO::ParseSymtab() {
if (symbol_byte_size == 0 && function_starts_count > 0) {
addr_t symbol_lookup_file_addr = nlist.n_value;
// Do an exact address match for non-ARM addresses, else get the
- // closest since
- // the symbol might be a thumb symbol which has an address with
- // bit zero set
+ // closest since the symbol might be a thumb symbol which has an
+ // address with bit zero set
FunctionStarts::Entry *func_start_entry =
function_starts.FindEntry(symbol_lookup_file_addr, !is_arm);
if (is_arm && func_start_entry) {
// Verify that the function start address is the symbol address
- // (ARM)
- // or the symbol address + 1 (thumb)
+ // (ARM) or the symbol address + 1 (thumb)
if (func_start_entry->addr != symbol_lookup_file_addr &&
func_start_entry->addr != (symbol_lookup_file_addr + 1)) {
// Not the right entry, NULL it out...
@@ -4515,8 +4439,7 @@ size_t ObjectFileMachO::ParseSymtab() {
if (next_func_start_entry) {
addr_t next_symbol_file_addr = next_func_start_entry->addr;
// Be sure the clear the Thumb address bit when we calculate
- // the size
- // from the current and next address
+ // the size from the current and next address
if (is_arm)
next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
symbol_byte_size = std::min<lldb::addr_t>(
@@ -4532,10 +4455,10 @@ size_t ObjectFileMachO::ParseSymtab() {
if (is_debug == false) {
if (type == eSymbolTypeCode) {
- // See if we can find a N_FUN entry for any code symbols.
- // If we do find a match, and the name matches, then we
- // can merge the two into just the function symbol to avoid
- // duplicate entries in the symbol table
+ // See if we can find a N_FUN entry for any code symbols. If we
+ // do find a match, and the name matches, then we can merge the
+ // two into just the function symbol to avoid duplicate entries
+ // in the symbol table
std::pair<ValueToSymbolIndexMap::const_iterator,
ValueToSymbolIndexMap::const_iterator>
range;
@@ -4552,9 +4475,8 @@ size_t ObjectFileMachO::ParseSymtab() {
Mangled::ePreferMangled)) {
m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
// We just need the flags from the linker symbol, so put
- // these flags
- // into the N_FUN flags to avoid duplicate symbols in the
- // symbol table
+ // these flags into the N_FUN flags to avoid duplicate
+ // symbols in the symbol table
sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
sym[pos->second].SetFlags(nlist.n_type << 16 |
nlist.n_desc);
@@ -4577,10 +4499,10 @@ size_t ObjectFileMachO::ParseSymtab() {
type == eSymbolTypeObjCClass ||
type == eSymbolTypeObjCMetaClass ||
type == eSymbolTypeObjCIVar) {
- // See if we can find a N_STSYM entry for any data symbols.
- // If we do find a match, and the name matches, then we
- // can merge the two into just the Static symbol to avoid
- // duplicate entries in the symbol table
+ // See if we can find a N_STSYM entry for any data symbols. If we
+ // do find a match, and the name matches, then we can merge the
+ // two into just the Static symbol to avoid duplicate entries in
+ // the symbol table
std::pair<ValueToSymbolIndexMap::const_iterator,
ValueToSymbolIndexMap::const_iterator>
range;
@@ -4597,9 +4519,8 @@ size_t ObjectFileMachO::ParseSymtab() {
Mangled::ePreferMangled)) {
m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
// We just need the flags from the linker symbol, so put
- // these flags
- // into the N_STSYM flags to avoid duplicate symbols in the
- // symbol table
+ // these flags into the N_STSYM flags to avoid duplicate
+ // symbols in the symbol table
sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
sym[pos->second].SetFlags(nlist.n_type << 16 |
nlist.n_desc);
@@ -4623,16 +4544,15 @@ size_t ObjectFileMachO::ParseSymtab() {
if (pos != N_GSYM_name_to_sym_idx.end()) {
const uint32_t GSYM_sym_idx = pos->second;
m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
- // Copy the address, because often the N_GSYM address has an
- // invalid address of zero
- // when the global is a common symbol
+ // Copy the address, because often the N_GSYM address has
+ // an invalid address of zero when the global is a common
+ // symbol
sym[GSYM_sym_idx].GetAddressRef().SetSection(
symbol_section);
sym[GSYM_sym_idx].GetAddressRef().SetOffset(symbol_value);
// We just need the flags from the linker symbol, so put
- // these flags
- // into the N_GSYM flags to avoid duplicate symbols in the
- // symbol table
+ // these flags into the N_GSYM flags to avoid duplicate
+ // symbols in the symbol table
sym[GSYM_sym_idx].SetFlags(nlist.n_type << 16 |
nlist.n_desc);
sym[sym_idx].Clear();
@@ -4739,8 +4659,8 @@ size_t ObjectFileMachO::ParseSymtab() {
}
}
- // Trim our symbols down to just what we ended up with after
- // removing any symbols.
+ // Trim our symbols down to just what we ended up with after removing any
+ // symbols.
if (sym_idx < num_syms) {
num_syms = sym_idx;
sym = symtab->Resize(num_syms);
@@ -4788,13 +4708,12 @@ size_t ObjectFileMachO::ParseSymtab() {
m_nlist_idx_to_sym_idx.find(stub_sym_id);
Symbol *stub_symbol = NULL;
if (index_pos != end_index_pos) {
- // We have a remapping from the original nlist index to
- // a current symbol index, so just look this up by index
+ // We have a remapping from the original nlist index to a
+ // current symbol index, so just look this up by index
stub_symbol = symtab->SymbolAtIndex(index_pos->second);
} else {
- // We need to lookup a symbol using the original nlist
- // symbol index since this index is coming from the
- // S_SYMBOL_STUBS
+ // We need to lookup a symbol using the original nlist symbol
+ // index since this index is coming from the S_SYMBOL_STUBS
stub_symbol = symtab->FindSymbolByID(stub_sym_id);
}
@@ -4803,12 +4722,9 @@ size_t ObjectFileMachO::ParseSymtab() {
if (stub_symbol->GetType() == eSymbolTypeUndefined) {
// Change the external symbol into a trampoline that makes
- // sense
- // These symbols were N_UNDF N_EXT, and are useless to us,
- // so we
- // can re-use them so we don't have to make up a synthetic
- // symbol
- // for no good reason.
+ // sense These symbols were N_UNDF N_EXT, and are useless
+ // to us, so we can re-use them so we don't have to make up
+ // a synthetic symbol for no good reason.
if (resolver_addresses.find(symbol_stub_addr) ==
resolver_addresses.end())
stub_symbol->SetType(eSymbolTypeTrampoline);
@@ -4853,8 +4769,8 @@ size_t ObjectFileMachO::ParseSymtab() {
if (!trie_entries.empty()) {
for (const auto &e : trie_entries) {
if (e.entry.import_name) {
- // Only add indirect symbols from the Trie entries if we
- // didn't have a N_INDR nlist entry for this already
+ // Only add indirect symbols from the Trie entries if we didn't have
+ // a N_INDR nlist entry for this already
if (indirect_symbol_names.find(e.entry.name) ==
indirect_symbol_names.end()) {
// Make a synthetic symbol to describe re-exported symbol.
@@ -4905,7 +4821,7 @@ void ObjectFileMachO::Dump(Stream *s) {
GetArchitecture(header_arch);
*s << ", file = '" << m_file
- << "', arch = " << header_arch.GetArchitectureName() << "\n";
+ << "', triple = " << header_arch.GetTriple().getTriple() << "\n";
SectionList *sections = GetSectionList();
if (sections)
@@ -4943,7 +4859,7 @@ bool ObjectFileMachO::GetUUID(const llvm::MachO::mach_header &header,
if (!memcmp(uuid_bytes, opencl_uuid, 16))
return false;
- uuid.SetBytes(uuid_bytes);
+ uuid = UUID::fromOptionalData(uuid_bytes, 16);
return true;
}
return false;
@@ -4953,6 +4869,21 @@ bool ObjectFileMachO::GetUUID(const llvm::MachO::mach_header &header,
return false;
}
+static const char *GetOSName(uint32_t cmd) {
+ switch (cmd) {
+ case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
+ return "ios";
+ case llvm::MachO::LC_VERSION_MIN_MACOSX:
+ return "macosx";
+ case llvm::MachO::LC_VERSION_MIN_TVOS:
+ return "tvos";
+ case llvm::MachO::LC_VERSION_MIN_WATCHOS:
+ return "watchos";
+ default:
+ llvm_unreachable("unexpected LC_VERSION load command");
+ }
+}
+
bool ObjectFileMachO::GetArchitecture(const llvm::MachO::mach_header &header,
const lldb_private::DataExtractor &data,
lldb::offset_t lc_offset,
@@ -4968,16 +4899,16 @@ bool ObjectFileMachO::GetArchitecture(const llvm::MachO::mach_header &header,
if (header.filetype == MH_PRELOAD) {
if (header.cputype == CPU_TYPE_ARM) {
- // If this is a 32-bit arm binary, and it's a standalone binary,
- // force the Vendor to Apple so we don't accidentally pick up
- // the generic armv7 ABI at runtime. Apple's armv7 ABI always uses
- // r7 for the frame pointer register; most other armv7 ABIs use a
- // combination of r7 and r11.
+ // If this is a 32-bit arm binary, and it's a standalone binary, force
+ // the Vendor to Apple so we don't accidentally pick up the generic
+ // armv7 ABI at runtime. Apple's armv7 ABI always uses r7 for the
+ // frame pointer register; most other armv7 ABIs use a combination of
+ // r7 and r11.
triple.setVendor(llvm::Triple::Apple);
} else {
// Set vendor to an unspecified unknown or a "*" so it can match any
- // vendor
- // This is required for correct behavior of EFI debugging on x86_64
+ // vendor This is required for correct behavior of EFI debugging on
+ // x86_64
triple.setVendor(llvm::Triple::UnknownVendor);
triple.setVendorName(llvm::StringRef());
}
@@ -4991,23 +4922,29 @@ bool ObjectFileMachO::GetArchitecture(const llvm::MachO::mach_header &header,
if (data.GetU32(&offset, &load_cmd, 2) == NULL)
break;
+ uint32_t major, minor, patch;
+ struct version_min_command version_min;
+
+ llvm::SmallString<16> os_name;
+ llvm::raw_svector_ostream os(os_name);
+
switch (load_cmd.cmd) {
case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
- triple.setOS(llvm::Triple::IOS);
- return true;
-
case llvm::MachO::LC_VERSION_MIN_MACOSX:
- triple.setOS(llvm::Triple::MacOSX);
- return true;
-
case llvm::MachO::LC_VERSION_MIN_TVOS:
- triple.setOS(llvm::Triple::TvOS);
- return true;
-
case llvm::MachO::LC_VERSION_MIN_WATCHOS:
- triple.setOS(llvm::Triple::WatchOS);
+ if (load_cmd.cmdsize != sizeof(version_min))
+ break;
+ data.ExtractBytes(cmd_offset,
+ sizeof(version_min), data.GetByteOrder(),
+ &version_min);
+ major = version_min.version >> 16;
+ minor = (version_min.version >> 8) & 0xffu;
+ patch = version_min.version & 0xffu;
+ os << GetOSName(load_cmd.cmd) << major << '.' << minor << '.'
+ << patch;
+ triple.setOSName(os.str());
return true;
-
default:
break;
}
@@ -5048,7 +4985,8 @@ uint32_t ObjectFileMachO::GetDependentModules(FileSpecList &files) {
std::vector<std::string> rpath_relative_paths;
std::vector<std::string> at_exec_relative_paths;
const bool resolve_path = false; // Don't resolve the dependent file paths
- // since they may not reside on this system
+ // since they may not reside on this
+ // system
uint32_t i;
for (i = 0; i < m_header.ncmds; ++i) {
const uint32_t cmd_offset = offset;
@@ -5112,12 +5050,9 @@ uint32_t ObjectFileMachO::GetDependentModules(FileSpecList &files) {
for (const auto &rpath : rpath_paths) {
std::string path = rpath;
path += rpath_relative_path;
- // It is OK to resolve this path because we must find a file on
- // disk for us to accept it anyway if it is rpath relative.
+ // It is OK to resolve this path because we must find a file on disk
+ // for us to accept it anyway if it is rpath relative.
FileSpec file_spec(path, true);
- // Remove any redundant parts of the path (like "../foo") since
- // LC_RPATH values often contain "..".
- file_spec = file_spec.GetNormalizedPath();
if (file_spec.Exists() && files.AppendIfUnique(file_spec)) {
count++;
break;
@@ -5135,11 +5070,8 @@ uint32_t ObjectFileMachO::GetDependentModules(FileSpecList &files) {
for (const auto &at_exec_relative_path : at_exec_relative_paths) {
FileSpec file_spec =
exec_dir.CopyByAppendingPathComponent(at_exec_relative_path);
- file_spec = file_spec.GetNormalizedPath();
- if (file_spec.Exists() && files.AppendIfUnique(file_spec)) {
+ if (file_spec.Exists() && files.AppendIfUnique(file_spec))
count++;
- break;
- }
}
}
}
@@ -5148,17 +5080,15 @@ uint32_t ObjectFileMachO::GetDependentModules(FileSpecList &files) {
lldb_private::Address ObjectFileMachO::GetEntryPointAddress() {
// If the object file is not an executable it can't hold the entry point.
- // m_entry_point_address
- // is initialized to an invalid address, so we can just return that.
- // If m_entry_point_address is valid it means we've found it already, so
- // return the cached value.
+ // m_entry_point_address is initialized to an invalid address, so we can just
+ // return that. If m_entry_point_address is valid it means we've found it
+ // already, so return the cached value.
if (!IsExecutable() || m_entry_point_address.IsValid())
return m_entry_point_address;
// Otherwise, look for the UnixThread or Thread command. The data for the
- // Thread command is given in
- // /usr/include/mach-o.h, but it is basically:
+ // Thread command is given in /usr/include/mach-o.h, but it is basically:
//
// uint32_t flavor - this is the flavor argument you would pass to
// thread_get_state
@@ -5172,9 +5102,9 @@ lldb_private::Address ObjectFileMachO::GetEntryPointAddress() {
// FIXME: We will need to have a "RegisterContext data provider" class at some
// point that can get all the registers
// out of data in this form & attach them to a given thread. That should
- // underlie the MacOS X User process plugin,
- // and we'll also need it for the MacOS X Core File process plugin. When we
- // have that we can also use it here.
+ // underlie the MacOS X User process plugin, and we'll also need it for the
+ // MacOS X Core File process plugin. When we have that we can also use it
+ // here.
//
// For now we hard-code the offsets and flavors we need:
//
@@ -5279,16 +5209,14 @@ lldb_private::Address ObjectFileMachO::GetEntryPointAddress() {
if (start_address != LLDB_INVALID_ADDRESS) {
// We got the start address from the load commands, so now resolve that
- // address in the sections
- // of this ObjectFile:
+ // address in the sections of this ObjectFile:
if (!m_entry_point_address.ResolveAddressUsingFileSections(
start_address, GetSectionList())) {
m_entry_point_address.Clear();
}
} else {
// We couldn't read the UnixThread load command - maybe it wasn't there.
- // As a fallback look for the
- // "start" symbol in the main executable.
+ // As a fallback look for the "start" symbol in the main executable.
ModuleSP module_sp(GetModule());
@@ -5353,8 +5281,8 @@ std::string ObjectFileMachO::GetIdentifierString() {
if (module_sp) {
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- // First, look over the load commands for an LC_NOTE load command
- // with data_owner string "kern ver str" & use that if found.
+ // First, look over the load commands for an LC_NOTE load command with
+ // data_owner string "kern ver str" & use that if found.
lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
for (uint32_t i = 0; i < m_header.ncmds; ++i) {
const uint32_t cmd_offset = offset;
@@ -5370,8 +5298,8 @@ std::string ObjectFileMachO::GetIdentifierString() {
uint64_t fileoff = m_data.GetU64_unchecked (&offset);
uint64_t size = m_data.GetU64_unchecked (&offset);
- // "kern ver str" has a uint32_t version and then a
- // nul terminated c-string.
+ // "kern ver str" has a uint32_t version and then a nul terminated
+ // c-string.
if (strcmp ("kern ver str", data_owner) == 0)
{
offset = fileoff;
@@ -5398,8 +5326,8 @@ std::string ObjectFileMachO::GetIdentifierString() {
offset = cmd_offset + lc.cmdsize;
}
- // Second, make a pass over the load commands looking for an
- // obsolete LC_IDENT load command.
+ // Second, make a pass over the load commands looking for an obsolete
+ // LC_IDENT load command.
offset = MachHeaderSizeFromMagic(m_header.magic);
for (uint32_t i = 0; i < m_header.ncmds; ++i) {
const uint32_t cmd_offset = offset;
@@ -5444,7 +5372,8 @@ bool ObjectFileMachO::GetCorefileMainBinaryInfo (addr_t &address, UUID &uuid) {
uint64_t fileoff = m_data.GetU64_unchecked (&offset);
uint64_t size = m_data.GetU64_unchecked (&offset);
- // "main bin spec" (main binary specification) data payload is formatted:
+ // "main bin spec" (main binary specification) data payload is
+ // formatted:
// uint32_t version [currently 1]
// uint32_t type [0 == unspecified, 1 == kernel, 2 == user process]
// uint64_t address [ UINT64_MAX if address not specified ]
@@ -5461,12 +5390,11 @@ bool ObjectFileMachO::GetCorefileMainBinaryInfo (addr_t &address, UUID &uuid) {
uuid_t raw_uuid;
memset (raw_uuid, 0, sizeof (uuid_t));
- if (m_data.GetU32 (&offset, &type, 1)
- && m_data.GetU64 (&offset, &address, 1)
- && m_data.CopyData (offset, sizeof (uuid_t), raw_uuid) != 0
- && uuid.SetBytes (raw_uuid, sizeof (uuid_t)))
- {
- return true;
+ if (m_data.GetU32(&offset, &type, 1) &&
+ m_data.GetU64(&offset, &address, 1) &&
+ m_data.CopyData(offset, sizeof(uuid_t), raw_uuid) != 0) {
+ uuid = UUID::fromOptionalData(raw_uuid, sizeof(uuid_t));
+ return true;
}
}
}
@@ -5525,9 +5453,9 @@ ObjectFile::Type ObjectFileMachO::CalculateType() {
// UUID load command.
UUID uuid;
if (GetUUID(&uuid)) {
- // this checking for the UUID load command is not enough
- // we could eventually look for the symbol named
- // "OSKextGetCurrentIdentifier" as this is required of kexts
+ // this checking for the UUID load command is not enough we could
+ // eventually look for the symbol named "OSKextGetCurrentIdentifier" as
+ // this is required of kexts
if (m_strata == eStrataInvalid)
m_strata = eStrataKernel;
return eTypeSharedLibrary;
@@ -5569,9 +5497,9 @@ ObjectFile::Strata ObjectFileMachO::CalculateStrata() {
// UUID load command.
UUID uuid;
if (GetUUID(&uuid)) {
- // this checking for the UUID load command is not enough
- // we could eventually look for the symbol named
- // "OSKextGetCurrentIdentifier" as this is required of kexts
+ // this checking for the UUID load command is not enough we could
+ // eventually look for the symbol named "OSKextGetCurrentIdentifier" as
+ // this is required of kexts
if (m_type == eTypeInvalid)
m_type = eTypeSharedLibrary;
@@ -5618,8 +5546,7 @@ ObjectFile::Strata ObjectFileMachO::CalculateStrata() {
return eStrataUnknown;
}
-uint32_t ObjectFileMachO::GetVersion(uint32_t *versions,
- uint32_t num_versions) {
+llvm::VersionTuple ObjectFileMachO::GetVersion() {
ModuleSP module_sp(GetModule());
if (module_sp) {
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
@@ -5647,23 +5574,13 @@ uint32_t ObjectFileMachO::GetVersion(uint32_t *versions,
}
if (version_cmd == LC_ID_DYLIB) {
- if (versions != NULL && num_versions > 0) {
- if (num_versions > 0)
- versions[0] = (version & 0xFFFF0000ull) >> 16;
- if (num_versions > 1)
- versions[1] = (version & 0x0000FF00ull) >> 8;
- if (num_versions > 2)
- versions[2] = (version & 0x000000FFull);
- // Fill in an remaining version numbers with invalid values
- for (i = 3; i < num_versions; ++i)
- versions[i] = UINT32_MAX;
- }
- // The LC_ID_DYLIB load command has a version with 3 version numbers
- // in it, so always return 3
- return 3;
+ unsigned major = (version & 0xFFFF0000ull) >> 16;
+ unsigned minor = (version & 0x0000FF00ull) >> 8;
+ unsigned subminor = (version & 0x000000FFull);
+ return llvm::VersionTuple(major, minor, subminor);
}
}
- return false;
+ return llvm::VersionTuple();
}
bool ObjectFileMachO::GetArchitecture(ArchSpec &arch) {
@@ -5676,21 +5593,40 @@ bool ObjectFileMachO::GetArchitecture(ArchSpec &arch) {
return false;
}
-UUID ObjectFileMachO::GetProcessSharedCacheUUID(Process *process) {
- UUID uuid;
+void ObjectFileMachO::GetProcessSharedCacheUUID(Process *process, addr_t &base_addr, UUID &uuid) {
+ uuid.Clear();
+ base_addr = LLDB_INVALID_ADDRESS;
if (process && process->GetDynamicLoader()) {
DynamicLoader *dl = process->GetDynamicLoader();
- addr_t load_address;
LazyBool using_shared_cache;
LazyBool private_shared_cache;
- dl->GetSharedCacheInformation(load_address, uuid, using_shared_cache,
+ dl->GetSharedCacheInformation(base_addr, uuid, using_shared_cache,
private_shared_cache);
}
- return uuid;
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS | LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("inferior process shared cache has a UUID of %s, base address 0x%" PRIx64 , uuid.GetAsString().c_str(), base_addr);
}
-UUID ObjectFileMachO::GetLLDBSharedCacheUUID() {
- UUID uuid;
+// From dyld SPI header dyld_process_info.h
+typedef void *dyld_process_info;
+struct lldb_copy__dyld_process_cache_info {
+ uuid_t cacheUUID; // UUID of cache used by process
+ uint64_t cacheBaseAddress; // load address of dyld shared cache
+ bool noCache; // process is running without a dyld cache
+ bool privateCache; // process is using a private copy of its dyld cache
+};
+
+// #including mach/mach.h pulls in machine.h & CPU_TYPE_ARM etc conflicts with llvm
+// enum definitions llvm::MachO::CPU_TYPE_ARM turning them into compile errors.
+// So we need to use the actual underlying types of task_t and kern_return_t
+// below.
+extern "C" unsigned int /*task_t*/ mach_task_self();
+
+void ObjectFileMachO::GetLLDBSharedCacheUUID(addr_t &base_addr, UUID &uuid) {
+ uuid.Clear();
+ base_addr = LLDB_INVALID_ADDRESS;
+
#if defined(__APPLE__) && \
(defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
uint8_t *(*dyld_get_all_image_infos)(void);
@@ -5708,25 +5644,60 @@ UUID ObjectFileMachO::GetLLDBSharedCacheUUID() {
sharedCacheUUID_address =
(uuid_t *)((uint8_t *)dyld_all_image_infos_address +
160); // sharedCacheUUID <mach-o/dyld_images.h>
+ if (*version >= 15)
+ base_addr = *(uint64_t *) ((uint8_t *) dyld_all_image_infos_address
+ + 176); // sharedCacheBaseAddress <mach-o/dyld_images.h>
} else {
sharedCacheUUID_address =
(uuid_t *)((uint8_t *)dyld_all_image_infos_address +
84); // sharedCacheUUID <mach-o/dyld_images.h>
+ if (*version >= 15) {
+ base_addr = 0;
+ base_addr = *(uint32_t *) ((uint8_t *) dyld_all_image_infos_address
+ + 100); // sharedCacheBaseAddress <mach-o/dyld_images.h>
+ }
+ }
+ uuid = UUID::fromOptionalData(sharedCacheUUID_address, sizeof(uuid_t));
+ }
+ }
+ } else {
+ // Exists in macOS 10.12 and later, iOS 10.0 and later - dyld SPI
+ dyld_process_info (*dyld_process_info_create)(unsigned int /* task_t */ task, uint64_t timestamp, unsigned int /*kern_return_t*/ *kernelError);
+ void (*dyld_process_info_get_cache)(void *info, void *cacheInfo);
+ void (*dyld_process_info_release)(dyld_process_info info);
+
+ dyld_process_info_create = (void *(*)(unsigned int /* task_t */, uint64_t, unsigned int /*kern_return_t*/ *))
+ dlsym (RTLD_DEFAULT, "_dyld_process_info_create");
+ dyld_process_info_get_cache = (void (*)(void *, void *))
+ dlsym (RTLD_DEFAULT, "_dyld_process_info_get_cache");
+ dyld_process_info_release = (void (*)(void *))
+ dlsym (RTLD_DEFAULT, "_dyld_process_info_release");
+
+ if (dyld_process_info_create && dyld_process_info_get_cache) {
+ unsigned int /*kern_return_t */ kern_ret;
+ dyld_process_info process_info = dyld_process_info_create(::mach_task_self(), 0, &kern_ret);
+ if (process_info) {
+ struct lldb_copy__dyld_process_cache_info sc_info;
+ memset (&sc_info, 0, sizeof (struct lldb_copy__dyld_process_cache_info));
+ dyld_process_info_get_cache (process_info, &sc_info);
+ if (sc_info.cacheBaseAddress != 0) {
+ base_addr = sc_info.cacheBaseAddress;
+ uuid = UUID::fromOptionalData(sc_info.cacheUUID, sizeof(uuid_t));
}
- uuid.SetBytes(sharedCacheUUID_address);
+ dyld_process_info_release (process_info);
}
}
}
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS | LIBLLDB_LOG_PROCESS));
+ if (log && uuid.IsValid())
+ log->Printf("lldb's in-memory shared cache has a UUID of %s base address of 0x%" PRIx64, uuid.GetAsString().c_str(), base_addr);
#endif
- return uuid;
}
-uint32_t ObjectFileMachO::GetMinimumOSVersion(uint32_t *versions,
- uint32_t num_versions) {
- if (m_min_os_versions.empty()) {
+llvm::VersionTuple ObjectFileMachO::GetMinimumOSVersion() {
+ if (!m_min_os_version) {
lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
- bool success = false;
- for (uint32_t i = 0; success == false && i < m_header.ncmds; ++i) {
+ for (uint32_t i = 0; i < m_header.ncmds; ++i) {
const lldb::offset_t load_cmd_offset = offset;
version_min_command lc;
@@ -5742,35 +5713,21 @@ uint32_t ObjectFileMachO::GetMinimumOSVersion(uint32_t *versions,
const uint32_t yy = (lc.version >> 8) & 0xffu;
const uint32_t zz = lc.version & 0xffu;
if (xxxx) {
- m_min_os_versions.push_back(xxxx);
- m_min_os_versions.push_back(yy);
- m_min_os_versions.push_back(zz);
+ m_min_os_version = llvm::VersionTuple(xxxx, yy, zz);
+ break;
}
- success = true;
}
}
offset = load_cmd_offset + lc.cmdsize;
}
- if (success == false) {
- // Push an invalid value so we don't keep trying to
- m_min_os_versions.push_back(UINT32_MAX);
+ if (!m_min_os_version) {
+ // Set version to an empty value so we don't keep trying to
+ m_min_os_version = llvm::VersionTuple();
}
}
- if (m_min_os_versions.size() > 1 || m_min_os_versions[0] != UINT32_MAX) {
- if (versions != NULL && num_versions > 0) {
- for (size_t i = 0; i < num_versions; ++i) {
- if (i < m_min_os_versions.size())
- versions[i] = m_min_os_versions[i];
- else
- versions[i] = 0;
- }
- }
- return m_min_os_versions.size();
- }
- // Call the superclasses version that will empty out the data
- return ObjectFile::GetMinimumOSVersion(versions, num_versions);
+ return *m_min_os_version;
}
uint32_t ObjectFileMachO::GetSDKVersion(uint32_t *versions,
@@ -5797,20 +5754,29 @@ uint32_t ObjectFileMachO::GetSDKVersion(uint32_t *versions,
m_sdk_versions.push_back(xxxx);
m_sdk_versions.push_back(yy);
m_sdk_versions.push_back(zz);
+ success = true;
+ } else {
+ GetModule()->ReportWarning(
+ "minimum OS version load command with invalid (0) version found.");
}
- success = true;
}
}
offset = load_cmd_offset + lc.cmdsize;
}
if (success == false) {
- // Push an invalid value so we don't keep trying to
+ // Push an invalid value so we don't try to find
+ // the version # again on the next call to this
+ // method.
m_sdk_versions.push_back(UINT32_MAX);
}
}
- if (m_sdk_versions.size() > 1 || m_sdk_versions[0] != UINT32_MAX) {
+ // Legitimate version numbers will have 3 entries pushed
+ // on to m_sdk_versions. If we only have one value, it's
+ // the sentinel value indicating that this object file
+ // does not have a valid minimum os version #.
+ if (m_sdk_versions.size() > 1) {
if (versions != NULL && num_versions > 0) {
for (size_t i = 0; i < num_versions; ++i) {
if (i < m_sdk_versions.size())
@@ -5843,9 +5809,9 @@ lldb_private::ConstString ObjectFileMachO::GetPluginName() {
uint32_t ObjectFileMachO::GetPluginVersion() { return 1; }
Section *ObjectFileMachO::GetMachHeaderSection() {
- // Find the first address of the mach header which is the first non-zero
- // file sized section whose file offset is zero. This is the base file address
- // of the mach-o file which can be subtracted from the vmaddr of the other
+ // Find the first address of the mach header which is the first non-zero file
+ // sized section whose file offset is zero. This is the base file address of
+ // the mach-o file which can be subtracted from the vmaddr of the other
// segments found in memory and added to the load address
ModuleSP module_sp = GetModule();
if (module_sp) {
@@ -5883,8 +5849,8 @@ lldb::addr_t ObjectFileMachO::CalculateSectionLoadAddressForMemoryImage(
module_sp.get() == section->GetModule().get()) {
// Ignore __LINKEDIT and __DWARF segments
if (section->GetName() == GetSegmentNameLINKEDIT()) {
- // Only map __LINKEDIT if we have an in memory image and this isn't
- // a kernel binary like a kext or mach_kernel.
+ // Only map __LINKEDIT if we have an in memory image and this isn't a
+ // kernel binary like a kext or mach_kernel.
const bool is_memory_image = (bool)m_process_wp.lock();
const Strata strata = GetStrata();
if (is_memory_image == false || strata == eStrataKernel)
@@ -5910,9 +5876,8 @@ bool ObjectFileMachO::SetLoadAddress(Target &target, lldb::addr_t value,
if (value_is_offset) {
// "value" is an offset to apply to each top level segment
for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
- // Iterate through the object file sections to find all
- // of the sections that size on disk (to avoid __PAGEZERO)
- // and load them
+ // Iterate through the object file sections to find all of the
+ // sections that size on disk (to avoid __PAGEZERO) and load them
SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
if (section_sp && section_sp->GetFileSize() > 0 &&
section_sp->IsThreadSpecific() == false &&
@@ -5920,8 +5885,7 @@ bool ObjectFileMachO::SetLoadAddress(Target &target, lldb::addr_t value,
// Ignore __LINKEDIT and __DWARF segments
if (section_sp->GetName() == GetSegmentNameLINKEDIT()) {
// Only map __LINKEDIT if we have an in memory image and this
- // isn't
- // a kernel binary like a kext or mach_kernel.
+ // isn't a kernel binary like a kext or mach_kernel.
const bool is_memory_image = (bool)m_process_wp.lock();
const Strata strata = GetStrata();
if (is_memory_image == false || strata == eStrataKernel)
@@ -6071,10 +6035,10 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
ThreadList &thread_list = process_sp->GetThreadList();
const uint32_t num_threads = thread_list.GetSize();
- // Make an array of LC_THREAD data items. Each one contains
- // the contents of the LC_THREAD load command. The data doesn't
- // contain the load command + load command size, we will
- // add the load command and load command size as we emit the data.
+ // Make an array of LC_THREAD data items. Each one contains the
+ // contents of the LC_THREAD load command. The data doesn't contain
+ // the load command + load command size, we will add the load command
+ // and load command size as we emit the data.
std::vector<StreamString> LC_THREAD_datas(num_threads);
for (auto &LC_THREAD_data : LC_THREAD_datas) {
LC_THREAD_data.GetFlags().Set(Stream::eBinary);
@@ -6234,8 +6198,8 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
bytes_left -= bytes_read;
addr += bytes_read;
} else {
- // Some pages within regions are not readable, those
- // should be zero filled
+ // Some pages within regions are not readable, those should
+ // be zero filled
memset(bytes, 0, bytes_to_read);
size_t bytes_written = bytes_to_read;
error = core_file.Write(bytes, bytes_written);
diff --git a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
index 9a42f41a4c94..be64518064b5 100644
--- a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
+++ b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
@@ -86,7 +86,7 @@ public:
uint32_t GetAddressByteSize() const override;
- lldb::AddressClass GetAddressClass(lldb::addr_t file_addr) override;
+ lldb_private::AddressClass GetAddressClass(lldb::addr_t file_addr) override;
lldb_private::Symtab *GetSymtab() override;
@@ -123,10 +123,9 @@ public:
ObjectFile::Strata CalculateStrata() override;
- uint32_t GetVersion(uint32_t *versions, uint32_t num_versions) override;
+ llvm::VersionTuple GetVersion() override;
- uint32_t GetMinimumOSVersion(uint32_t *versions,
- uint32_t num_versions) override;
+ llvm::VersionTuple GetMinimumOSVersion() override;
uint32_t GetSDKVersion(uint32_t *versions, uint32_t num_versions) override;
@@ -162,14 +161,14 @@ protected:
// with an on-disk dyld_shared_cache file. The process will record
// the shared cache UUID so the on-disk cache can be matched or rejected
// correctly.
- lldb_private::UUID GetProcessSharedCacheUUID(lldb_private::Process *);
+ void GetProcessSharedCacheUUID(lldb_private::Process *, lldb::addr_t &base_addr, lldb_private::UUID &uuid);
// Intended for same-host arm device debugging where lldb will read
// shared cache libraries out of its own memory instead of the remote
// process' memory as an optimization. If lldb's shared cache UUID
// does not match the process' shared cache UUID, this optimization
// should not be used.
- lldb_private::UUID GetLLDBSharedCacheUUID();
+ void GetLLDBSharedCacheUUID(lldb::addr_t &base_addir, lldb_private::UUID &uuid);
lldb_private::Section *GetMachHeaderSection();
@@ -185,6 +184,18 @@ protected:
size_t ParseSymtab();
+ typedef lldb_private::RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges;
+ EncryptedFileRanges GetEncryptedFileRanges();
+
+ struct SegmentParsingContext;
+ void ProcessDysymtabCommand(const llvm::MachO::load_command &load_cmd,
+ lldb::offset_t offset);
+ void ProcessSegmentCommand(const llvm::MachO::load_command &load_cmd,
+ lldb::offset_t offset, uint32_t cmd_idx,
+ SegmentParsingContext &context);
+ void SanitizeSegmentCommand(llvm::MachO::segment_command_64 &seg_cmd,
+ uint32_t cmd_idx);
+
llvm::MachO::mach_header m_header;
static const lldb_private::ConstString &GetSegmentNameTEXT();
static const lldb_private::ConstString &GetSegmentNameDATA();
@@ -197,7 +208,7 @@ protected:
llvm::MachO::dysymtab_command m_dysymtab;
std::vector<llvm::MachO::segment_command_64> m_mach_segments;
std::vector<llvm::MachO::section_64> m_mach_sections;
- std::vector<uint32_t> m_min_os_versions;
+ llvm::Optional<llvm::VersionTuple> m_min_os_version;
std::vector<uint32_t> m_sdk_versions;
typedef lldb_private::RangeVector<uint32_t, uint32_t> FileRangeArray;
lldb_private::Address m_entry_point_address;
diff --git a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
index 77bfa7fe0a64..b2967f1532ab 100644
--- a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -236,8 +236,8 @@ bool ObjectFilePECOFF::SetLoadAddress(Target &target, addr_t value,
size_t sect_idx = 0;
for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
- // Iterate through the object file sections to find all
- // of the sections that have SHF_ALLOC in their flag bits.
+ // Iterate through the object file sections to find all of the sections
+ // that have SHF_ALLOC in their flag bits.
SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
if (section_sp && !section_sp->IsThreadSpecific()) {
if (target.GetSectionLoadList().SetSectionLoadAddress(
@@ -268,8 +268,8 @@ uint32_t ObjectFilePECOFF::GetAddressByteSize() const {
//----------------------------------------------------------------------
// NeedsEndianSwap
//
-// Return true if an endian swap needs to occur when extracting data
-// from this file.
+// Return true if an endian swap needs to occur when extracting data from this
+// file.
//----------------------------------------------------------------------
bool ObjectFilePECOFF::NeedsEndianSwap() const {
#if defined(__LITTLE_ENDIAN__)
@@ -552,8 +552,8 @@ Symtab *ObjectFilePECOFF::GetSymtab() {
// are followed by a 4-byte string table offset. Else these
// 8 bytes contain the symbol name
if (symtab_data.GetU32(&offset) == 0) {
- // Long string that doesn't fit into the symbol table name,
- // so now we must read the 4 byte string table offset
+ // Long string that doesn't fit into the symbol table name, so
+ // now we must read the 4 byte string table offset
uint32_t strtab_offset = symtab_data.GetU32(&offset);
symbol_name_cstr = strtab_data.PeekCStr(strtab_offset);
symbol_name.assign(symbol_name_cstr);
@@ -692,10 +692,12 @@ void ObjectFilePECOFF::CreateSections(SectionList &unified_section_list) {
static ConstString g_sect_name_dwarf_debug_line(".debug_line");
static ConstString g_sect_name_dwarf_debug_loc(".debug_loc");
static ConstString g_sect_name_dwarf_debug_macinfo(".debug_macinfo");
+ static ConstString g_sect_name_dwarf_debug_names(".debug_names");
static ConstString g_sect_name_dwarf_debug_pubnames(".debug_pubnames");
static ConstString g_sect_name_dwarf_debug_pubtypes(".debug_pubtypes");
static ConstString g_sect_name_dwarf_debug_ranges(".debug_ranges");
static ConstString g_sect_name_dwarf_debug_str(".debug_str");
+ static ConstString g_sect_name_dwarf_debug_types(".debug_types");
static ConstString g_sect_name_eh_frame(".eh_frame");
static ConstString g_sect_name_go_symtab(".gosymtab");
SectionType section_type = eSectionTypeOther;
@@ -736,6 +738,8 @@ void ObjectFilePECOFF::CreateSections(SectionList &unified_section_list) {
section_type = eSectionTypeDWARFDebugLoc;
else if (const_sect_name == g_sect_name_dwarf_debug_macinfo)
section_type = eSectionTypeDWARFDebugMacInfo;
+ else if (const_sect_name == g_sect_name_dwarf_debug_names)
+ section_type = eSectionTypeDWARFDebugNames;
else if (const_sect_name == g_sect_name_dwarf_debug_pubnames)
section_type = eSectionTypeDWARFDebugPubNames;
else if (const_sect_name == g_sect_name_dwarf_debug_pubtypes)
@@ -744,6 +748,8 @@ void ObjectFilePECOFF::CreateSections(SectionList &unified_section_list) {
section_type = eSectionTypeDWARFDebugRanges;
else if (const_sect_name == g_sect_name_dwarf_debug_str)
section_type = eSectionTypeDWARFDebugStr;
+ else if (const_sect_name == g_sect_name_dwarf_debug_types)
+ section_type = eSectionTypeDWARFDebugTypes;
else if (const_sect_name == g_sect_name_eh_frame)
section_type = eSectionTypeEHFrame;
else if (const_sect_name == g_sect_name_go_symtab)
diff --git a/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp b/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp
index 75bc518f7538..3f6083931513 100644
--- a/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp
+++ b/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp
@@ -312,8 +312,8 @@ bool OperatingSystemGo::UpdateThreadList(ThreadList &old_thread_list,
}
std::vector<Goroutine> goroutines;
// The threads that are in "new_thread_list" upon entry are the threads from
- // the
- // lldb_private::Process subclass, no memory threads will be in this list.
+ // the lldb_private::Process subclass, no memory threads will be in this
+ // list.
Status err;
for (uint64_t i = 0; i < allglen; ++i) {
@@ -402,7 +402,6 @@ lldb::ThreadSP OperatingSystemGo::CreateThread(lldb::tid_t tid,
ValueObjectSP OperatingSystemGo::FindGlobal(TargetSP target, const char *name) {
VariableList variable_list;
- const bool append = true;
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS));
@@ -414,7 +413,7 @@ ValueObjectSP OperatingSystemGo::FindGlobal(TargetSP target, const char *name) {
}
uint32_t match_count = target->GetImages().FindGlobalVariables(
- ConstString(name), append, 1, variable_list);
+ ConstString(name), 1, variable_list);
if (match_count > 0) {
ExecutionContextScope *exe_scope = target->GetProcessSP().get();
if (exe_scope == NULL)
diff --git a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
index b71f3cf04c33..d6252c473270 100644
--- a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
+++ b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
@@ -50,8 +50,8 @@ void OperatingSystemPython::Terminate() {
OperatingSystem *OperatingSystemPython::CreateInstance(Process *process,
bool force) {
- // Python OperatingSystem plug-ins must be requested by name, so force must be
- // true
+ // Python OperatingSystem plug-ins must be requested by name, so force must
+ // be true
FileSpec python_os_plugin_spec(process->GetPythonOSPluginPath());
if (python_os_plugin_spec && python_os_plugin_spec.Exists()) {
std::unique_ptr<OperatingSystemPython> os_ap(
@@ -156,9 +156,10 @@ bool OperatingSystemPython::UpdateThreadList(ThreadList &old_thread_list,
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS));
- // First thing we have to do is to try to get the API lock, and the run lock.
- // We're going to change the thread content of the process, and we're going
- // to use python, which requires the API lock to do it.
+ // First thing we have to do is to try to get the API lock, and the
+ // interpreter lock. We're going to change the thread content of the process,
+ // and we're going to use python, which requires the API lock to do it. We
+ // need the interpreter lock to make sure thread_info_dict stays alive.
//
// If someone already has the API lock, that is ok, we just want to avoid
// external code from making new API calls while this call is happening.
@@ -166,9 +167,10 @@ bool OperatingSystemPython::UpdateThreadList(ThreadList &old_thread_list,
// This is a recursive lock so we can grant it to any Python code called on
// the stack below us.
Target &target = m_process->GetTarget();
- std::unique_lock<std::recursive_mutex> lock(target.GetAPIMutex(),
- std::defer_lock);
- lock.try_lock();
+ std::unique_lock<std::recursive_mutex> api_lock(target.GetAPIMutex(),
+ std::defer_lock);
+ api_lock.try_lock();
+ auto interpreter_lock = m_interpreter->AcquireInterpreterLock();
if (log)
log->Printf("OperatingSystemPython::UpdateThreadList() fetching thread "
@@ -176,20 +178,16 @@ bool OperatingSystemPython::UpdateThreadList(ThreadList &old_thread_list,
m_process->GetID());
// The threads that are in "new_thread_list" upon entry are the threads from
- // the
- // lldb_private::Process subclass, no memory threads will be in this list.
-
- auto interpreter_lock =
- m_interpreter
- ->AcquireInterpreterLock(); // to make sure threads_list stays alive
+ // the lldb_private::Process subclass, no memory threads will be in this
+ // list.
StructuredData::ArraySP threads_list =
m_interpreter->OSPlugin_ThreadsInfo(m_python_object_sp);
const uint32_t num_cores = core_thread_list.GetSize(false);
// Make a map so we can keep track of which cores were used from the
- // core_thread list. Any real threads/cores that weren't used should
- // later be put back into the "new_thread_list".
+ // core_thread list. Any real threads/cores that weren't used should later be
+ // put back into the "new_thread_list".
std::vector<bool> core_used_map(num_cores, false);
if (threads_list) {
if (log) {
@@ -214,8 +212,7 @@ bool OperatingSystemPython::UpdateThreadList(ThreadList &old_thread_list,
// Any real core threads that didn't end up backing a memory thread should
// still be in the main thread list, and they should be inserted at the
- // beginning
- // of the list
+ // beginning of the list
uint32_t insert_idx = 0;
for (uint32_t core_idx = 0; core_idx < num_cores; ++core_idx) {
if (core_used_map[core_idx] == false) {
@@ -256,8 +253,8 @@ ThreadSP OperatingSystemPython::CreateThreadFromThreadInfo(
// plug-in generated thread.
if (!IsOperatingSystemPluginThread(thread_sp)) {
// We have thread ID overlap between the protocol threads and the
- // operating system threads, clear the thread so we create an
- // operating system thread for this.
+ // operating system threads, clear the thread so we create an operating
+ // system thread for this.
thread_sp.reset();
}
}
@@ -301,20 +298,24 @@ OperatingSystemPython::CreateRegisterContextForThread(Thread *thread,
if (!IsOperatingSystemPluginThread(thread->shared_from_this()))
return reg_ctx_sp;
- // First thing we have to do is get the API lock, and the run lock. We're
- // going to change the thread
- // content of the process, and we're going to use python, which requires the
- // API lock to do it.
- // So get & hold that. This is a recursive lock so we can grant it to any
- // Python code called on the stack below us.
+ // First thing we have to do is to try to get the API lock, and the
+ // interpreter lock. We're going to change the thread content of the process,
+ // and we're going to use python, which requires the API lock to do it. We
+ // need the interpreter lock to make sure thread_info_dict stays alive.
+ //
+ // If someone already has the API lock, that is ok, we just want to avoid
+ // external code from making new API calls while this call is happening.
+ //
+ // This is a recursive lock so we can grant it to any Python code called on
+ // the stack below us.
Target &target = m_process->GetTarget();
- std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex());
+ std::unique_lock<std::recursive_mutex> api_lock(target.GetAPIMutex(),
+ std::defer_lock);
+ api_lock.try_lock();
+ auto interpreter_lock = m_interpreter->AcquireInterpreterLock();
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
- auto lock =
- m_interpreter
- ->AcquireInterpreterLock(); // to make sure python objects stays alive
if (reg_data_addr != LLDB_INVALID_ADDRESS) {
// The registers data is in contiguous memory, just create the register
// context using the address provided
@@ -326,8 +327,8 @@ OperatingSystemPython::CreateRegisterContextForThread(Thread *thread,
reg_ctx_sp.reset(new RegisterContextMemory(
*thread, 0, *GetDynamicRegisterInfo(), reg_data_addr));
} else {
- // No register data address is provided, query the python plug-in to let
- // it make up the data as it sees fit
+ // No register data address is provided, query the python plug-in to let it
+ // make up the data as it sees fit
if (log)
log->Printf("OperatingSystemPython::CreateRegisterContextForThread (tid "
"= 0x%" PRIx64 ", 0x%" PRIx64
@@ -383,18 +384,23 @@ lldb::ThreadSP OperatingSystemPython::CreateThread(lldb::tid_t tid,
tid, context);
if (m_interpreter && m_python_object_sp) {
- // First thing we have to do is get the API lock, and the run lock. We're
- // going to change the thread
- // content of the process, and we're going to use python, which requires the
- // API lock to do it.
- // So get & hold that. This is a recursive lock so we can grant it to any
- // Python code called on the stack below us.
+ // First thing we have to do is to try to get the API lock, and the
+ // interpreter lock. We're going to change the thread content of the
+ // process, and we're going to use python, which requires the API lock to
+ // do it. We need the interpreter lock to make sure thread_info_dict stays
+ // alive.
+ //
+ // If someone already has the API lock, that is ok, we just want to avoid
+ // external code from making new API calls while this call is happening.
+ //
+ // This is a recursive lock so we can grant it to any Python code called on
+ // the stack below us.
Target &target = m_process->GetTarget();
- std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex());
+ std::unique_lock<std::recursive_mutex> api_lock(target.GetAPIMutex(),
+ std::defer_lock);
+ api_lock.try_lock();
+ auto interpreter_lock = m_interpreter->AcquireInterpreterLock();
- auto lock = m_interpreter->AcquireInterpreterLock(); // to make sure
- // thread_info_dict
- // stays alive
StructuredData::DictionarySP thread_info_dict =
m_interpreter->OSPlugin_CreateThread(m_python_object_sp, tid, context);
std::vector<bool> core_used_map;
diff --git a/source/Plugins/Platform/Android/AdbClient.cpp b/source/Plugins/Platform/Android/AdbClient.cpp
index 6e15eb2b1dcb..4cd8c645dd76 100644
--- a/source/Plugins/Platform/Android/AdbClient.cpp
+++ b/source/Plugins/Platform/Android/AdbClient.cpp
@@ -165,8 +165,8 @@ Status AdbClient::GetDevices(DeviceIDList &device_list) {
for (const auto device : devices)
device_list.push_back(device.split('\t').first);
- // Force disconnect since ADB closes connection after host:devices
- // response is sent.
+ // Force disconnect since ADB closes connection after host:devices response
+ // is sent.
m_conn.reset();
return error;
}
diff --git a/source/Plugins/Platform/Android/PlatformAndroid.cpp b/source/Plugins/Platform/Android/PlatformAndroid.cpp
index 5b85bcdf7fdd..1cedcde97a92 100644
--- a/source/Plugins/Platform/Android/PlatformAndroid.cpp
+++ b/source/Plugins/Platform/Android/PlatformAndroid.cpp
@@ -83,9 +83,9 @@ PlatformSP PlatformAndroid::CreateInstance(bool force, const ArchSpec *arch) {
break;
#if defined(__ANDROID__)
- // Only accept "unknown" for the vendor if the host is android and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified_
+ // Only accept "unknown" for the vendor if the host is android and it
+ // "unknown" wasn't specified (it was just returned because it was NOT
+ // specified_
case llvm::Triple::VendorType::UnknownVendor:
create = !arch->TripleVendorWasSpecified();
break;
@@ -100,9 +100,9 @@ PlatformSP PlatformAndroid::CreateInstance(bool force, const ArchSpec *arch) {
break;
#if defined(__ANDROID__)
- // Only accept "unknown" for the OS if the host is android and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
+ // Only accept "unknown" for the OS if the host is android and it
+ // "unknown" wasn't specified (it was just returned because it was NOT
+ // specified)
case llvm::Triple::OSType::UnknownOS:
create = !arch->TripleOSWasSpecified();
break;
@@ -193,8 +193,7 @@ Status PlatformAndroid::GetFile(const FileSpec &source,
if (IsHost() || !m_remote_platform_sp)
return PlatformLinux::GetFile(source, destination);
- FileSpec source_spec(source.GetPath(false), false,
- FileSpec::ePathSyntaxPosix);
+ FileSpec source_spec(source.GetPath(false), false, FileSpec::Style::posix);
if (source_spec.IsRelative())
source_spec = GetRemoteWorkingDirectory().CopyByAppendingPathComponent(
source_spec.GetCString(false));
@@ -222,8 +221,8 @@ Status PlatformAndroid::GetFile(const FileSpec &source,
if (strchr(source_file, '\'') != nullptr)
return Status("Doesn't support single-quotes in filenames");
- // mode == 0 can signify that adbd cannot access the file
- // due security constraints - try "cat ..." as a fallback.
+ // mode == 0 can signify that adbd cannot access the file due security
+ // constraints - try "cat ..." as a fallback.
AdbClient adb(m_device_id);
char cmd[PATH_MAX];
@@ -239,7 +238,7 @@ Status PlatformAndroid::PutFile(const FileSpec &source,
return PlatformLinux::PutFile(source, destination, uid, gid);
FileSpec destination_spec(destination.GetPath(false), false,
- FileSpec::ePathSyntaxPosix);
+ FileSpec::Style::posix);
if (destination_spec.IsRelative())
destination_spec = GetRemoteWorkingDirectory().CopyByAppendingPathComponent(
destination_spec.GetCString(false));
@@ -306,7 +305,7 @@ Status PlatformAndroid::DownloadSymbolFile(const lldb::ModuleSP &module_sp,
const FileSpec &dst_file_spec) {
// For oat file we can try to fetch additional debug info from the device
ConstString extension = module_sp->GetFileSpec().GetFileNameExtension();
- if (extension != ConstString("oat") && extension != ConstString("odex"))
+ if (extension != ConstString(".oat") && extension != ConstString(".odex"))
return Status(
"Symbol file downloading only supported for oat and odex files");
@@ -361,10 +360,8 @@ Status PlatformAndroid::DownloadSymbolFile(const lldb::ModuleSP &module_sp,
}
bool PlatformAndroid::GetRemoteOSVersion() {
- m_major_os_version = GetSdkVersion();
- m_minor_os_version = 0;
- m_update_os_version = 0;
- return m_major_os_version != 0;
+ m_os_version = llvm::VersionTuple(GetSdkVersion());
+ return !m_os_version.empty();
}
llvm::StringRef
diff --git a/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp b/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
index dbc74833e287..2415da31daf0 100644
--- a/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
+++ b/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
@@ -180,9 +180,9 @@ Status PlatformAndroidRemoteGDBServer::MakeConnectURL(
static const int kAttempsNum = 5;
Status error;
- // There is a race possibility that somebody will occupy
- // a port while we're in between FindUnusedPort and ForwardPortWithAdb -
- // adding the loop to mitigate such problem.
+ // There is a race possibility that somebody will occupy a port while we're
+ // in between FindUnusedPort and ForwardPortWithAdb - adding the loop to
+ // mitigate such problem.
for (auto i = 0; i < kAttempsNum; ++i) {
uint16_t local_port = 0;
error = FindUnusedPort(local_port);
@@ -208,10 +208,9 @@ lldb::ProcessSP PlatformAndroidRemoteGDBServer::ConnectProcess(
lldb_private::Debugger &debugger, lldb_private::Target *target,
lldb_private::Status &error) {
// We don't have the pid of the remote gdbserver when it isn't started by us
- // but we still want
- // to store the list of port forwards we set up in our port forward map.
- // Generate a fake pid for
- // these cases what won't collide with any other valid pid on android.
+ // but we still want to store the list of port forwards we set up in our port
+ // forward map. Generate a fake pid for these cases what won't collide with
+ // any other valid pid on android.
static lldb::pid_t s_remote_gdbserver_fake_pid = 0xffffffffffffffffULL;
int remote_port;
diff --git a/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp b/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
index 73c7d21f0a06..bc8111d1078b 100644
--- a/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
+++ b/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
@@ -32,8 +32,8 @@
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
-// Define these constants from FreeBSD mman.h for use when targeting
-// remote FreeBSD systems even when host has different values.
+// Define these constants from FreeBSD mman.h for use when targeting remote
+// FreeBSD systems even when host has different values.
#define MAP_PRIVATE 0x0002
#define MAP_ANON 0x1000
@@ -60,9 +60,8 @@ PlatformSP PlatformFreeBSD::CreateInstance(bool force, const ArchSpec *arch) {
break;
#if defined(__FreeBSD__)
- // Only accept "unknown" for the OS if the host is BSD and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
+ // Only accept "unknown" for the OS if the host is BSD and it "unknown"
+ // wasn't specified (it was just returned because it was NOT specified)
case llvm::Triple::OSType::UnknownOS:
create = !arch->TripleOSWasSpecified();
break;
@@ -143,7 +142,8 @@ bool PlatformFreeBSD::GetSupportedArchitectureAtIndex(uint32_t idx,
arch = hostArch;
return arch.IsValid();
} else if (idx == 1) {
- // If the default host architecture is 64-bit, look for a 32-bit variant
+ // If the default host architecture is 64-bit, look for a 32-bit
+ // variant
if (hostArch.IsValid() && hostArch.GetTriple().isArch64Bit()) {
arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
return arch.IsValid();
@@ -187,13 +187,10 @@ bool PlatformFreeBSD::GetSupportedArchitectureAtIndex(uint32_t idx,
return false;
}
// Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the
- // vendor by
- // calling triple.SetVendorName("unknown") so that it is a "unspecified
- // unknown".
- // This means when someone calls triple.GetVendorName() it will return an
- // empty string
- // which indicates that the vendor can be set when two architectures are
- // merged
+ // vendor by calling triple.SetVendorName("unknown") so that it is a
+ // "unspecified unknown". This means when someone calls
+ // triple.GetVendorName() it will return an empty string which indicates
+ // that the vendor can be set when two architectures are merged
// Now set the triple into "arch" and return true
arch.SetTriple(triple);
@@ -228,16 +225,16 @@ PlatformFreeBSD::GetSoftwareBreakpointTrapOpcode(Target &target,
switch (target.GetArchitecture().GetMachine()) {
case llvm::Triple::arm: {
lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0));
- AddressClass addr_class = eAddressClassUnknown;
+ AddressClass addr_class = AddressClass::eUnknown;
if (bp_loc_sp) {
addr_class = bp_loc_sp->GetAddress().GetAddressClass();
- if (addr_class == eAddressClassUnknown &&
+ if (addr_class == AddressClass::eUnknown &&
(bp_loc_sp->GetAddress().GetFileAddress() & 1))
- addr_class = eAddressClassCodeAlternateISA;
+ addr_class = AddressClass::eCodeAlternateISA;
}
- if (addr_class == eAddressClassCodeAlternateISA) {
+ if (addr_class == AddressClass::eCodeAlternateISA) {
// TODO: Enable when FreeBSD supports thumb breakpoints.
// FreeBSD kernel as of 10.x, does not support thumb breakpoints
return 0;
@@ -286,9 +283,9 @@ lldb::ProcessSP PlatformFreeBSD::Attach(ProcessAttachInfo &attach_info,
if (target && error.Success()) {
debugger.GetTargetList().SetSelectedTarget(target);
- // The freebsd always currently uses the GDB remote debugger plug-in
- // so even when debugging locally we are debugging remotely!
- // Just like the darwin plugin.
+ // The freebsd always currently uses the GDB remote debugger plug-in so
+ // even when debugging locally we are debugging remotely! Just like the
+ // darwin plugin.
process_sp = target->CreateProcess(
attach_info.GetListenerForProcess(debugger), "gdb-remote", NULL);
diff --git a/source/Plugins/Platform/Linux/PlatformLinux.cpp b/source/Plugins/Platform/Linux/PlatformLinux.cpp
index 8186eae0e8c4..dbde91d7ab2d 100644
--- a/source/Plugins/Platform/Linux/PlatformLinux.cpp
+++ b/source/Plugins/Platform/Linux/PlatformLinux.cpp
@@ -30,8 +30,8 @@
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
-// Define these constants from Linux mman.h for use when targeting
-// remote linux systems even when host has different values.
+// Define these constants from Linux mman.h for use when targeting remote linux
+// systems even when host has different values.
#define MAP_PRIVATE 2
#define MAP_ANON 0x20
@@ -58,9 +58,8 @@ PlatformSP PlatformLinux::CreateInstance(bool force, const ArchSpec *arch) {
break;
#if defined(__linux__)
- // Only accept "unknown" for the OS if the host is linux and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
+ // Only accept "unknown" for the OS if the host is linux and it "unknown"
+ // wasn't specified (it was just returned because it was NOT specified)
case llvm::Triple::OSType::UnknownOS:
create = !arch->TripleOSWasSpecified();
break;
@@ -142,7 +141,8 @@ bool PlatformLinux::GetSupportedArchitectureAtIndex(uint32_t idx,
arch = hostArch;
return arch.IsValid();
} else if (idx == 1) {
- // If the default host architecture is 64-bit, look for a 32-bit variant
+ // If the default host architecture is 64-bit, look for a 32-bit
+ // variant
if (hostArch.IsValid() && hostArch.GetTriple().isArch64Bit()) {
arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
return arch.IsValid();
@@ -192,13 +192,10 @@ bool PlatformLinux::GetSupportedArchitectureAtIndex(uint32_t idx,
return false;
}
// Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the
- // vendor by
- // calling triple.SetVendorName("unknown") so that it is a "unspecified
- // unknown".
- // This means when someone calls triple.GetVendorName() it will return an
- // empty string
- // which indicates that the vendor can be set when two architectures are
- // merged
+ // vendor by calling triple.SetVendorName("unknown") so that it is a
+ // "unspecified unknown". This means when someone calls
+ // triple.GetVendorName() it will return an empty string which indicates
+ // that the vendor can be set when two architectures are merged
// Now set the triple into "arch" and return true
arch.SetTriple(triple);
@@ -212,8 +209,8 @@ void PlatformLinux::GetStatus(Stream &strm) {
#ifndef LLDB_DISABLE_POSIX
// Display local kernel information only when we are running in host mode.
- // Otherwise, we would end up printing non-Linux information (when running
- // on Mac OS for example).
+ // Otherwise, we would end up printing non-Linux information (when running on
+ // Mac OS for example).
if (IsHost()) {
struct utsname un;
@@ -272,8 +269,8 @@ bool PlatformLinux::CanDebugProcess() {
}
// For local debugging, Linux will override the debug logic to use llgs-launch
-// rather than lldb-launch, llgs-attach. This differs from current lldb-launch,
-// debugserver-attach approach on MacOSX.
+// rather than lldb-launch, llgs-attach. This differs from current lldb-
+// launch, debugserver-attach approach on MacOSX.
lldb::ProcessSP
PlatformLinux::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
Target *target, // Can be NULL, if NULL create a new
@@ -297,8 +294,8 @@ PlatformLinux::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
launch_info.GetFlags().Set(eLaunchFlagDebug);
// We always launch the process we are going to debug in a separate process
- // group, since then we can handle ^C interrupts ourselves w/o having to worry
- // about the target getting them as well.
+ // group, since then we can handle ^C interrupts ourselves w/o having to
+ // worry about the target getting them as well.
launch_info.SetLaunchInSeparateProcessGroup(true);
// Ensure we have a target.
diff --git a/source/Plugins/Platform/MacOSX/CMakeLists.txt b/source/Plugins/Platform/MacOSX/CMakeLists.txt
index f8d911b321f8..f9663559069a 100644
--- a/source/Plugins/Platform/MacOSX/CMakeLists.txt
+++ b/source/Plugins/Platform/MacOSX/CMakeLists.txt
@@ -11,13 +11,14 @@ list(APPEND PLUGIN_PLATFORM_MACOSX_SOURCES
list(APPEND PLUGIN_PLATFORM_MACOSX_DARWIN_ONLY_SOURCES
PlatformAppleSimulator.cpp
PlatformiOSSimulator.cpp
- PlatformiOSSimulatorCoreSimulatorSupport.mm
PlatformAppleTVSimulator.cpp
PlatformAppleWatchSimulator.cpp
)
if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
include_directories(${LIBXML2_INCLUDE_DIR})
+ add_subdirectory(objcxx)
+ set(OBJC_LIBS "lldbPluginPlatformMacOSXObjCXX")
list(APPEND PLUGIN_PLATFORM_MACOSX_SOURCES
${PLUGIN_PLATFORM_MACOSX_DARWIN_ONLY_SOURCES})
else()
@@ -38,6 +39,7 @@ add_lldb_library(lldbPluginPlatformMacOSX PLUGIN
lldbTarget
lldbUtility
lldbPluginPlatformPOSIX
+ ${OBJC_LIBS}
LINK_COMPONENTS
Support
)
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
index a216e3839dd9..6852097117a1 100644
--- a/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
@@ -84,8 +84,8 @@ lldb_private::Status PlatformAppleSimulator::LaunchProcess(
void PlatformAppleSimulator::GetStatus(Stream &strm) {
#if defined(__APPLE__)
- // This will get called by subclasses, so just output status on the
- // current simulator
+ // This will get called by subclasses, so just output status on the current
+ // simulator
PlatformAppleSimulator::LoadCoreSimulator();
CoreSimulatorSupport::DeviceSet devices =
@@ -183,8 +183,8 @@ lldb::ProcessSP PlatformAppleSimulator::DebugProcess(
// Make sure we stop at the entry point
launch_info.GetFlags().Set(eLaunchFlagDebug);
// We always launch the process we are going to debug in a separate process
- // group, since then we can handle ^C interrupts ourselves w/o having to worry
- // about the target getting them as well.
+ // group, since then we can handle ^C interrupts ourselves w/o having to
+ // worry about the target getting them as well.
launch_info.SetLaunchInSeparateProcessGroup(true);
error = LaunchProcess(launch_info);
@@ -201,10 +201,10 @@ lldb::ProcessSP PlatformAppleSimulator::DebugProcess(
// process if this happens.
process_sp->SetShouldDetach(false);
- // If we didn't have any file actions, the pseudo terminal might
- // have been used where the slave side was given as the file to
- // open for stdin/out/err after we have already opened the master
- // so we can read/write stdin/out/err.
+ // If we didn't have any file actions, the pseudo terminal might have
+ // been used where the slave side was given as the file to open for
+ // stdin/out/err after we have already opened the master so we can
+ // read/write stdin/out/err.
int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
if (pty_fd != PseudoTerminal::invalid_fd) {
process_sp->SetSTDIOFileDescriptor(pty_fd);
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h b/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h
index 44feb019dc73..2536854e9630 100644
--- a/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h
+++ b/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h
@@ -16,8 +16,8 @@
// Other libraries and framework includes
// Project includes
-#include "PlatformDarwin.h"
-#include "PlatformiOSSimulatorCoreSimulatorSupport.h"
+#include "Plugins/Platform/MacOSX/PlatformDarwin.h"
+#include "Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h"
#include "lldb/Utility/FileSpec.h"
#include "llvm/ADT/Optional.h"
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp
index e0558f8b200e..e55cc0f4f6a4 100644
--- a/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp
@@ -90,9 +90,9 @@ PlatformSP PlatformAppleTVSimulator::CreateInstance(bool force,
break;
#if defined(__APPLE__)
- // Only accept "unknown" for the vendor if the host is Apple and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
+ // Only accept "unknown" for the vendor if the host is Apple and it
+ // "unknown" wasn't specified (it was just returned because it was NOT
+ // specified)
case llvm::Triple::UnknownArch:
create = !arch->TripleVendorWasSpecified();
break;
@@ -107,9 +107,9 @@ PlatformSP PlatformAppleTVSimulator::CreateInstance(bool force,
break;
#if defined(__APPLE__)
- // Only accept "unknown" for the OS if the host is Apple and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
+ // Only accept "unknown" for the OS if the host is Apple and it
+ // "unknown" wasn't specified (it was just returned because it was NOT
+ // specified)
case llvm::Triple::UnknownOS:
create = !arch->TripleOSWasSpecified();
break;
@@ -199,9 +199,9 @@ Status PlatformAppleTVSimulator::ResolveExecutable(
return error;
exe_module_sp.reset();
}
- // No valid architecture was specified or the exact ARM slice wasn't
- // found so ask the platform for the architectures that we should be
- // using (in the correct order) and see if we can find a match that way
+ // No valid architecture was specified or the exact ARM slice wasn't found
+ // so ask the platform for the architectures that we should be using (in
+ // the correct order) and see if we can find a match that way
StreamString arch_names;
ArchSpec platform_arch;
for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
@@ -293,8 +293,8 @@ const char *PlatformAppleTVSimulator::GetSDKDirectoryAsCString() {
m_sdk_directory.assign(1, '\0');
}
- // We should have put a single NULL character into m_sdk_directory
- // or it should have a valid path if the code gets here
+ // We should have put a single NULL character into m_sdk_directory or it
+ // should have a valid path if the code gets here
assert(m_sdk_directory.empty() == false);
if (m_sdk_directory[0])
return m_sdk_directory.c_str();
@@ -315,12 +315,12 @@ Status PlatformAppleTVSimulator::GetSymbolFile(const FileSpec &platform_file,
platform_file_path);
// First try in the SDK and see if the file is in there
- local_file.SetFile(resolved_path, true);
+ local_file.SetFile(resolved_path, true, FileSpec::Style::native);
if (local_file.Exists())
return error;
// Else fall back to the actual path itself
- local_file.SetFile(platform_file_path, true);
+ local_file.SetFile(platform_file_path, true, FileSpec::Style::native);
if (local_file.Exists())
return error;
}
@@ -337,10 +337,9 @@ Status PlatformAppleTVSimulator::GetSharedModule(
const ModuleSpec &module_spec, lldb_private::Process *process,
ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr,
ModuleSP *old_module_sp_ptr, bool *did_create_ptr) {
- // For AppleTV, the SDK files are all cached locally on the host
- // system. So first we ask for the file in the cached SDK,
- // then we attempt to get a shared module for the right architecture
- // with the right UUID.
+ // For AppleTV, the SDK files are all cached locally on the host system. So
+ // first we ask for the file in the cached SDK, then we attempt to get a
+ // shared module for the right architecture with the right UUID.
Status error;
ModuleSpec platform_module_spec(module_spec);
const FileSpec &platform_file = module_spec.GetFileSpec();
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp
index 9b2608f68625..8bbe0af0aec2 100644
--- a/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp
@@ -89,9 +89,9 @@ PlatformSP PlatformAppleWatchSimulator::CreateInstance(bool force,
break;
#if defined(__APPLE__)
- // Only accept "unknown" for the vendor if the host is Apple and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
+ // Only accept "unknown" for the vendor if the host is Apple and it
+ // "unknown" wasn't specified (it was just returned because it was NOT
+ // specified)
case llvm::Triple::UnknownArch:
create = !arch->TripleVendorWasSpecified();
break;
@@ -106,9 +106,9 @@ PlatformSP PlatformAppleWatchSimulator::CreateInstance(bool force,
break;
#if defined(__APPLE__)
- // Only accept "unknown" for the OS if the host is Apple and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
+ // Only accept "unknown" for the OS if the host is Apple and it
+ // "unknown" wasn't specified (it was just returned because it was NOT
+ // specified)
case llvm::Triple::UnknownOS:
create = !arch->TripleOSWasSpecified();
break;
@@ -199,9 +199,9 @@ Status PlatformAppleWatchSimulator::ResolveExecutable(
return error;
exe_module_sp.reset();
}
- // No valid architecture was specified or the exact ARM slice wasn't
- // found so ask the platform for the architectures that we should be
- // using (in the correct order) and see if we can find a match that way
+ // No valid architecture was specified or the exact ARM slice wasn't found
+ // so ask the platform for the architectures that we should be using (in
+ // the correct order) and see if we can find a match that way
StreamString arch_names;
ArchSpec platform_arch;
for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
@@ -293,8 +293,8 @@ const char *PlatformAppleWatchSimulator::GetSDKDirectoryAsCString() {
m_sdk_directory.assign(1, '\0');
}
- // We should have put a single NULL character into m_sdk_directory
- // or it should have a valid path if the code gets here
+ // We should have put a single NULL character into m_sdk_directory or it
+ // should have a valid path if the code gets here
assert(m_sdk_directory.empty() == false);
if (m_sdk_directory[0])
return m_sdk_directory.c_str();
@@ -315,12 +315,12 @@ Status PlatformAppleWatchSimulator::GetSymbolFile(const FileSpec &platform_file,
platform_file_path);
// First try in the SDK and see if the file is in there
- local_file.SetFile(resolved_path, true);
+ local_file.SetFile(resolved_path, true, FileSpec::Style::native);
if (local_file.Exists())
return error;
// Else fall back to the actual path itself
- local_file.SetFile(platform_file_path, true);
+ local_file.SetFile(platform_file_path, true, FileSpec::Style::native);
if (local_file.Exists())
return error;
}
@@ -337,10 +337,9 @@ Status PlatformAppleWatchSimulator::GetSharedModule(
const ModuleSpec &module_spec, lldb_private::Process *process,
ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr,
ModuleSP *old_module_sp_ptr, bool *did_create_ptr) {
- // For AppleWatch, the SDK files are all cached locally on the host
- // system. So first we ask for the file in the cached SDK,
- // then we attempt to get a shared module for the right architecture
- // with the right UUID.
+ // For AppleWatch, the SDK files are all cached locally on the host system.
+ // So first we ask for the file in the cached SDK, then we attempt to get a
+ // shared module for the right architecture with the right UUID.
Status error;
ModuleSpec platform_module_spec(module_spec);
const FileSpec &platform_file = module_spec.GetFileSpec();
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index b04d72f755f6..886e3b6d9a05 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -16,8 +16,6 @@
#include <algorithm>
#include <mutex>
-// Other libraries and framework includes
-#include "clang/Basic/VersionTuple.h"
// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/BreakpointSite.h"
@@ -42,6 +40,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Threading.h"
+#include "llvm/Support/VersionTuple.h"
#if defined(__APPLE__)
#include <TargetConditionals.h> // for TARGET_OS_TV, TARGET_OS_WATCH
@@ -73,10 +72,9 @@ FileSpecList PlatformDarwin::LocateExecutableScriptingResources(
// NB some extensions might be meaningful and should not be stripped -
// "this.binary.file"
// should not lose ".file" but GetFileNameStrippingExtension() will do
- // precisely that.
- // Ideally, we should have a per-platform list of extensions (".exe",
- // ".app", ".dSYM", ".framework")
- // which should be stripped while leaving "this.binary.file" as-is.
+ // precisely that. Ideally, we should have a per-platform list of
+ // extensions (".exe", ".app", ".dSYM", ".framework") which should be
+ // stripped while leaving "this.binary.file" as-is.
ScriptInterpreter *script_interpreter =
target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
@@ -101,14 +99,11 @@ FileSpecList PlatformDarwin::LocateExecutableScriptingResources(
// FIXME: for Python, we cannot allow certain characters in
// module
// filenames we import. Theoretically, different scripting
- // languages may
- // have different sets of forbidden tokens in filenames, and
- // that should
- // be dealt with by each ScriptInterpreter. For now, we just
- // replace dots
- // with underscores, but if we ever support anything other than
- // Python
- // we will need to rework this
+ // languages may have different sets of forbidden tokens in
+ // filenames, and that should be dealt with by each
+ // ScriptInterpreter. For now, we just replace dots with
+ // underscores, but if we ever support anything other than
+ // Python we will need to rework this
std::replace(module_basename.begin(), module_basename.end(),
'.', '_');
std::replace(module_basename.begin(), module_basename.end(),
@@ -125,9 +120,9 @@ FileSpecList PlatformDarwin::LocateExecutableScriptingResources(
StreamString path_string;
StreamString original_path_string;
// for OSX we are going to be in
- // .dSYM/Contents/Resources/DWARF/<basename>
- // let us go to .dSYM/Contents/Resources/Python/<basename>.py
- // and see if the file exists
+ // .dSYM/Contents/Resources/DWARF/<basename> let us go to
+ // .dSYM/Contents/Resources/Python/<basename>.py and see if the
+ // file exists
path_string.Printf("%s/../Python/%s.py",
symfile_spec.GetDirectory().GetCString(),
module_basename.c_str());
@@ -140,9 +135,8 @@ FileSpecList PlatformDarwin::LocateExecutableScriptingResources(
true);
// if we did some replacements of reserved characters, and a
- // file with the untampered name
- // exists, then warn the user that the file as-is shall not be
- // loaded
+ // file with the untampered name exists, then warn the user
+ // that the file as-is shall not be loaded
if (feedback_stream) {
if (module_basename != original_module_basename &&
orig_script_fspec.Exists()) {
@@ -178,8 +172,8 @@ FileSpecList PlatformDarwin::LocateExecutableScriptingResources(
break;
}
- // If we didn't find the python file, then keep
- // stripping the extensions and try again
+ // If we didn't find the python file, then keep stripping the
+ // extensions and try again
ConstString filename_no_extension(
module_spec.GetFileNameStrippingExtension());
if (module_spec.GetFilename() == filename_no_extension)
@@ -270,8 +264,8 @@ lldb_private::Status PlatformDarwin::GetSharedModuleWithLocalCache(
FileSpec module_cache_spec(cache_path, false);
// if rsync is supported, always bring in the file - rsync will be very
- // efficient
- // when files are the same on the local and remote end of the connection
+ // efficient when files are the same on the local and remote end of the
+ // connection
if (this->GetSupportsRSync()) {
err = BringInRemoteFile(this, module_spec, module_cache_spec);
if (err.Fail())
@@ -370,8 +364,8 @@ Status PlatformDarwin::GetSharedModule(
module_sp.reset();
if (IsRemote()) {
- // If we have a remote platform always, let it try and locate
- // the shared module first.
+ // If we have a remote platform always, let it try and locate the shared
+ // module first.
if (m_remote_platform_sp) {
error = m_remote_platform_sp->GetSharedModule(
module_spec, process, module_sp, module_search_paths_ptr,
@@ -453,8 +447,8 @@ PlatformDarwin::GetSoftwareBreakpointTrapOpcode(Target &target,
switch (machine) {
case llvm::Triple::aarch64: {
// TODO: fix this with actual darwin breakpoint opcode for arm64.
- // right now debugging uses the Z packets with GDB remote so this
- // is not needed, but the size needs to be correct...
+ // right now debugging uses the Z packets with GDB remote so this is not
+ // needed, but the size needs to be correct...
static const uint8_t g_arm64_breakpoint_opcode[] = {0xFE, 0xDE, 0xFF, 0xE7};
trap_opcode = g_arm64_breakpoint_opcode;
trap_opcode_size = sizeof(g_arm64_breakpoint_opcode);
@@ -472,7 +466,7 @@ PlatformDarwin::GetSoftwareBreakpointTrapOpcode(Target &target,
lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0));
if (bp_loc_sp)
bp_is_thumb = bp_loc_sp->GetAddress().GetAddressClass() ==
- eAddressClassCodeAlternateISA;
+ AddressClass::eCodeAlternateISA;
}
if (bp_is_thumb) {
trap_opcode = g_thumb_breakpooint_opcode;
@@ -548,8 +542,8 @@ bool PlatformDarwin::x86GetSupportedArchitectureAtIndex(uint32_t idx,
HostInfo::GetArchitecture(HostInfo::eArchKind64));
if (platform_arch.IsExactMatch(platform_arch64)) {
// This macosx platform supports both 32 and 64 bit. Since we already
- // returned the 64 bit arch for idx == 0, return the 32 bit arch
- // for idx == 1
+ // returned the 64 bit arch for idx == 0, return the 32 bit arch for
+ // idx == 1
arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
return arch.IsValid();
}
@@ -558,9 +552,9 @@ bool PlatformDarwin::x86GetSupportedArchitectureAtIndex(uint32_t idx,
return false;
}
-// The architecture selection rules for arm processors
-// These cpu subtypes have distinct names (e.g. armv7f) but armv7 binaries run
-// fine on an armv7f processor.
+// The architecture selection rules for arm processors These cpu subtypes have
+// distinct names (e.g. armv7f) but armv7 binaries run fine on an armv7f
+// processor.
bool PlatformDarwin::ARMGetSupportedArchitectureAtIndex(uint32_t idx,
ArchSpec &arch) {
@@ -1138,14 +1132,15 @@ const char *PlatformDarwin::GetDeveloperDirectory() {
if (m_developer_directory.empty()) {
bool developer_dir_path_valid = false;
char developer_dir_path[PATH_MAX];
- FileSpec temp_file_spec;
// Get the lldb framework's file path, and if it exists, truncate some
// components to only the developer directory path.
- if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, temp_file_spec)) {
+ FileSpec temp_file_spec = HostInfo::GetShlibDir();
+ if (temp_file_spec) {
if (temp_file_spec.GetPath(developer_dir_path,
sizeof(developer_dir_path))) {
- // e.g. /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework
+ // e.g.
+ // /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework
char *shared_frameworks =
strstr(developer_dir_path, "/SharedFrameworks/LLDB.framework");
if (shared_frameworks) {
@@ -1153,7 +1148,8 @@ const char *PlatformDarwin::GetDeveloperDirectory() {
strncat (developer_dir_path, "/Developer", sizeof (developer_dir_path) - 1); // add /Developer on
developer_dir_path_valid = true;
} else {
- // e.g. /Applications/Xcode.app/Contents/Developer/Toolchains/iOS11.2.xctoolchain/System/Library/PrivateFrameworks/LLDB.framework
+ // e.g.
+ // /Applications/Xcode.app/Contents/Developer/Toolchains/iOS11.2.xctoolchain/System/Library/PrivateFrameworks/LLDB.framework
char *developer_toolchains =
strstr(developer_dir_path, "/Contents/Developer/Toolchains/");
if (developer_toolchains) {
@@ -1171,7 +1167,7 @@ const char *PlatformDarwin::GetDeveloperDirectory() {
if (xcode_select_prefix_dir)
xcode_dir_path.append(xcode_select_prefix_dir);
xcode_dir_path.append("/usr/share/xcode-select/xcode_dir_path");
- temp_file_spec.SetFile(xcode_dir_path, false);
+ temp_file_spec.SetFile(xcode_dir_path, false, FileSpec::Style::native);
auto dir_buffer =
DataBufferLLVM::CreateFromPath(temp_file_spec.GetPath());
if (dir_buffer && dir_buffer->GetByteSize() > 0) {
@@ -1196,7 +1192,7 @@ const char *PlatformDarwin::GetDeveloperDirectory() {
Host::RunShellCommand("/usr/bin/xcode-select --print-path",
NULL, // current working directory
&exit_status, &signo, &command_output,
- 2, // short timeout
+ std::chrono::seconds(2), // short timeout
false); // don't run in a shell
if (error.Success() && exit_status == 0 && !command_output.empty()) {
const char *cmd_output_ptr = command_output.c_str();
@@ -1219,7 +1215,8 @@ const char *PlatformDarwin::GetDeveloperDirectory() {
}
if (developer_dir_path_valid) {
- temp_file_spec.SetFile(developer_dir_path, false);
+ temp_file_spec.SetFile(developer_dir_path, false,
+ FileSpec::Style::native);
if (temp_file_spec.Exists()) {
m_developer_directory.assign(developer_dir_path);
return m_developer_directory.c_str();
@@ -1230,8 +1227,8 @@ const char *PlatformDarwin::GetDeveloperDirectory() {
m_developer_directory.assign(1, '\0');
}
- // We should have put a single NULL character into m_developer_directory
- // or it should have a valid path if the code gets here
+ // We should have put a single NULL character into m_developer_directory or
+ // it should have a valid path if the code gets here
assert(m_developer_directory.empty() == false);
if (m_developer_directory[0])
return m_developer_directory.c_str();
@@ -1279,17 +1276,11 @@ PlatformDarwin::GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) {
shell_name++;
if (strcmp(shell_name, "sh") == 0) {
- // /bin/sh re-exec's itself as /bin/bash requiring another resume.
- // But it only does this if the COMMAND_MODE environment variable
- // is set to "legacy".
- const char **envp =
- launch_info.GetEnvironmentEntries().GetConstArgumentVector();
- if (envp != NULL) {
- for (int i = 0; envp[i] != NULL; i++) {
- if (strcmp(envp[i], "COMMAND_MODE=legacy") == 0)
- return 2;
- }
- }
+ // /bin/sh re-exec's itself as /bin/bash requiring another resume. But it
+ // only does this if the COMMAND_MODE environment variable is set to
+ // "legacy".
+ if (launch_info.GetEnvironment().lookup("COMMAND_MODE") == "legacy")
+ return 2;
return 1;
} else if (strcmp(shell_name, "csh") == 0 ||
strcmp(shell_name, "tcsh") == 0 ||
@@ -1310,7 +1301,7 @@ static const char *const sdk_strings[] = {
static FileSpec CheckPathForXcode(const FileSpec &fspec) {
if (fspec.Exists()) {
- const char substr[] = ".app/Contents/";
+ const char substr[] = ".app/Contents";
std::string path_to_shlib = fspec.GetPath();
size_t pos = path_to_shlib.rfind(substr);
@@ -1339,9 +1330,8 @@ static FileSpec GetXcodeContentsPath() {
// First get the program file spec. If lldb.so or LLDB.framework is running
// in a program and that program is Xcode, the path returned with be the
- // path
- // to Xcode.app/Contents/MacOS/Xcode, so this will be the correct Xcode to
- // use.
+ // path to Xcode.app/Contents/MacOS/Xcode, so this will be the correct
+ // Xcode to use.
fspec = HostInfo::GetProgramFileSpec();
if (fspec) {
@@ -1375,7 +1365,7 @@ static FileSpec GetXcodeContentsPath() {
&signo, // Put the signal that caused the process to exit in here
&output, // Get the output from the command and place it in this
// string
- 3); // Timeout in seconds to wait for shell program to finish
+ std::chrono::seconds(3));
if (status == 0 && !output.empty()) {
size_t first_non_newline = output.find_last_not_of("\r\n");
if (first_non_newline != std::string::npos) {
@@ -1392,18 +1382,14 @@ static FileSpec GetXcodeContentsPath() {
return g_xcode_filespec;
}
-bool PlatformDarwin::SDKSupportsModules(SDKType sdk_type, uint32_t major,
- uint32_t minor, uint32_t micro) {
+bool PlatformDarwin::SDKSupportsModules(SDKType sdk_type,
+ llvm::VersionTuple version) {
switch (sdk_type) {
case SDKType::MacOSX:
- if (major > 10 || (major == 10 && minor >= 10))
- return true;
- break;
+ return version >= llvm::VersionTuple(10, 10);
case SDKType::iPhoneOS:
case SDKType::iPhoneSimulator:
- if (major >= 8)
- return true;
- break;
+ return version >= llvm::VersionTuple(8);
}
return false;
@@ -1425,32 +1411,10 @@ bool PlatformDarwin::SDKSupportsModules(SDKType desired_type,
return false;
}
- const size_t major_dot_offset = version_part.find('.');
- if (major_dot_offset == llvm::StringRef::npos)
+ llvm::VersionTuple version;
+ if (version.tryParse(version_part))
return false;
-
- const llvm::StringRef major_version =
- version_part.slice(0, major_dot_offset);
- const llvm::StringRef minor_part =
- version_part.drop_front(major_dot_offset + 1);
-
- const size_t minor_dot_offset = minor_part.find('.');
- if (minor_dot_offset == llvm::StringRef::npos)
- return false;
-
- const llvm::StringRef minor_version = minor_part.slice(0, minor_dot_offset);
-
- unsigned int major = 0;
- unsigned int minor = 0;
- unsigned int micro = 0;
-
- if (major_version.getAsInteger(10, major))
- return false;
-
- if (minor_version.getAsInteger(10, minor))
- return false;
-
- return SDKSupportsModules(desired_type, major, minor, micro);
+ return SDKSupportsModules(desired_type, version);
}
return false;
@@ -1522,18 +1486,17 @@ FileSpec PlatformDarwin::GetSDKDirectoryForModules(SDKType sdk_type) {
sdks_spec.AppendPathComponent("SDKs");
if (sdk_type == SDKType::MacOSX) {
- uint32_t major = 0;
- uint32_t minor = 0;
- uint32_t micro = 0;
+ llvm::VersionTuple version = HostInfo::GetOSVersion();
- if (HostInfo::GetOSVersion(major, minor, micro)) {
- if (SDKSupportsModules(SDKType::MacOSX, major, minor, micro)) {
+ if (!version.empty()) {
+ if (SDKSupportsModules(SDKType::MacOSX, version)) {
// We slightly prefer the exact SDK for this machine. See if it is
// there.
FileSpec native_sdk_spec = sdks_spec;
StreamString native_sdk_name;
- native_sdk_name.Printf("MacOSX%u.%u.sdk", major, minor);
+ native_sdk_name.Printf("MacOSX%u.%u.sdk", version.getMajor(),
+ version.getMinor().getValueOr(0));
native_sdk_spec.AppendPathComponent(native_sdk_name.GetString());
if (native_sdk_spec.Exists()) {
@@ -1546,14 +1509,14 @@ FileSpec PlatformDarwin::GetSDKDirectoryForModules(SDKType sdk_type) {
return FindSDKInXcodeForModules(sdk_type, sdks_spec);
}
-std::tuple<uint32_t, uint32_t, uint32_t, llvm::StringRef>
+std::tuple<llvm::VersionTuple, llvm::StringRef>
PlatformDarwin::ParseVersionBuildDir(llvm::StringRef dir) {
- uint32_t major, minor, update;
llvm::StringRef build;
llvm::StringRef version_str;
llvm::StringRef build_str;
std::tie(version_str, build_str) = dir.split(' ');
- if (Args::StringToVersion(version_str, major, minor, update) ||
+ llvm::VersionTuple version;
+ if (!version.tryParse(version_str) ||
build_str.empty()) {
if (build_str.consume_front("(")) {
size_t pos = build_str.find(')');
@@ -1561,7 +1524,7 @@ PlatformDarwin::ParseVersionBuildDir(llvm::StringRef dir) {
}
}
- return std::make_tuple(major, minor, update, build);
+ return std::make_tuple(version, build);
}
void PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
@@ -1573,7 +1536,6 @@ void PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
options.insert(options.end(), apple_arguments.begin(), apple_arguments.end());
StreamString minimum_version_option;
- uint32_t versions[3] = {0, 0, 0};
bool use_current_os_version = false;
switch (sdk_type) {
case SDKType::iPhoneOS:
@@ -1597,9 +1559,9 @@ void PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
break;
}
- bool versions_valid = false;
+ llvm::VersionTuple version;
if (use_current_os_version)
- versions_valid = GetOSVersion(versions[0], versions[1], versions[2]);
+ version = GetOSVersion();
else if (target) {
// Our OS doesn't match our executable so we need to get the min OS version
// from the object file
@@ -1607,35 +1569,23 @@ void PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
if (exe_module_sp) {
ObjectFile *object_file = exe_module_sp->GetObjectFile();
if (object_file)
- versions_valid = object_file->GetMinimumOSVersion(versions, 3) > 0;
+ version = object_file->GetMinimumOSVersion();
}
}
// Only add the version-min options if we got a version from somewhere
- if (versions_valid && versions[0] != UINT32_MAX) {
- // Make any invalid versions be zero if needed
- if (versions[1] == UINT32_MAX)
- versions[1] = 0;
- if (versions[2] == UINT32_MAX)
- versions[2] = 0;
-
+ if (!version.empty()) {
switch (sdk_type) {
case SDKType::iPhoneOS:
minimum_version_option.PutCString("-mios-version-min=");
- minimum_version_option.PutCString(
- clang::VersionTuple(versions[0], versions[1], versions[2])
- .getAsString());
+ minimum_version_option.PutCString(version.getAsString());
break;
case SDKType::iPhoneSimulator:
minimum_version_option.PutCString("-mios-simulator-version-min=");
- minimum_version_option.PutCString(
- clang::VersionTuple(versions[0], versions[1], versions[2])
- .getAsString());
+ minimum_version_option.PutCString(version.getAsString());
break;
case SDKType::MacOSX:
minimum_version_option.PutCString("-mmacosx-version-min=");
- minimum_version_option.PutCString(
- clang::VersionTuple(versions[0], versions[1], versions[2])
- .getAsString());
+ minimum_version_option.PutCString(version.getAsString());
}
options.push_back(minimum_version_option.GetString());
}
@@ -1662,49 +1612,35 @@ ConstString PlatformDarwin::GetFullNameForDylib(ConstString basename) {
return ConstString(stream.GetString());
}
-bool PlatformDarwin::GetOSVersion(uint32_t &major, uint32_t &minor,
- uint32_t &update, Process *process) {
+llvm::VersionTuple PlatformDarwin::GetOSVersion(Process *process) {
if (process && strstr(GetPluginName().GetCString(), "-simulator")) {
lldb_private::ProcessInstanceInfo proc_info;
if (Host::GetProcessInfo(process->GetID(), proc_info)) {
- Args &env = proc_info.GetEnvironmentEntries();
- const size_t n = env.GetArgumentCount();
- const llvm::StringRef k_runtime_version("SIMULATOR_RUNTIME_VERSION=");
- const llvm::StringRef k_dyld_root_path("DYLD_ROOT_PATH=");
- std::string dyld_root_path;
+ const Environment &env = proc_info.GetEnvironment();
- for (size_t i = 0; i < n; ++i) {
- const char *env_cstr = env.GetArgumentAtIndex(i);
- if (env_cstr) {
- llvm::StringRef env_str(env_cstr);
- if (env_str.consume_front(k_runtime_version)) {
- if (Args::StringToVersion(env_str, major, minor, update))
- return true;
- } else if (env_str.consume_front(k_dyld_root_path)) {
- dyld_root_path = env_str;
- }
- }
- }
+ llvm::VersionTuple result;
+ if (!result.tryParse(env.lookup("SIMULATOR_RUNTIME_VERSION")))
+ return result;
+ std::string dyld_root_path = env.lookup("DYLD_ROOT_PATH");
if (!dyld_root_path.empty()) {
dyld_root_path += "/System/Library/CoreServices/SystemVersion.plist";
ApplePropertyList system_version_plist(dyld_root_path.c_str());
std::string product_version;
if (system_version_plist.GetValueAsString("ProductVersion",
product_version)) {
- return Args::StringToVersion(product_version, major, minor, update);
+ if (!result.tryParse(product_version))
+ return result;
}
}
}
// For simulator platforms, do NOT call back through
- // Platform::GetOSVersion()
- // as it might call Process::GetHostOSVersion() which we don't want as it
- // will be
- // incorrect
- return false;
+ // Platform::GetOSVersion() as it might call Process::GetHostOSVersion()
+ // which we don't want as it will be incorrect
+ return llvm::VersionTuple();
}
- return Platform::GetOSVersion(major, minor, update, process);
+ return Platform::GetOSVersion(process);
}
lldb_private::FileSpec PlatformDarwin::LocateExecutable(const char *basename) {
@@ -1713,8 +1649,8 @@ lldb_private::FileSpec PlatformDarwin::LocateExecutable(const char *basename) {
// any executable directories that should be searched.
static std::vector<FileSpec> g_executable_dirs;
- // Find the global list of directories that we will search for
- // executables once so we don't keep doing the work over and over.
+ // Find the global list of directories that we will search for executables
+ // once so we don't keep doing the work over and over.
static llvm::once_flag g_once_flag;
llvm::call_once(g_once_flag, []() {
@@ -1748,22 +1684,19 @@ lldb_private::FileSpec PlatformDarwin::LocateExecutable(const char *basename) {
lldb_private::Status
PlatformDarwin::LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) {
- // Starting in Fall 2016 OSes, NSLog messages only get mirrored to stderr
- // if the OS_ACTIVITY_DT_MODE environment variable is set. (It doesn't
- // require any specific value; rather, it just needs to exist).
- // We will set it here as long as the IDE_DISABLED_OS_ACTIVITY_DT_MODE flag
- // is not set. Xcode makes use of IDE_DISABLED_OS_ACTIVITY_DT_MODE to tell
+ // Starting in Fall 2016 OSes, NSLog messages only get mirrored to stderr if
+ // the OS_ACTIVITY_DT_MODE environment variable is set. (It doesn't require
+ // any specific value; rather, it just needs to exist). We will set it here
+ // as long as the IDE_DISABLED_OS_ACTIVITY_DT_MODE flag is not set. Xcode
+ // makes use of IDE_DISABLED_OS_ACTIVITY_DT_MODE to tell
// LLDB *not* to muck with the OS_ACTIVITY_DT_MODE flag when they
// specifically want it unset.
const char *disable_env_var = "IDE_DISABLED_OS_ACTIVITY_DT_MODE";
- auto &env_vars = launch_info.GetEnvironmentEntries();
- if (!env_vars.ContainsEnvironmentVariable(llvm::StringRef(disable_env_var))) {
- // We want to make sure that OS_ACTIVITY_DT_MODE is set so that
- // we get os_log and NSLog messages mirrored to the target process
- // stderr.
- if (!env_vars.ContainsEnvironmentVariable(
- llvm::StringRef("OS_ACTIVITY_DT_MODE")))
- env_vars.AppendArgument(llvm::StringRef("OS_ACTIVITY_DT_MODE=enable"));
+ auto &env_vars = launch_info.GetEnvironment();
+ if (!env_vars.count(disable_env_var)) {
+ // We want to make sure that OS_ACTIVITY_DT_MODE is set so that we get
+ // os_log and NSLog messages mirrored to the target process stderr.
+ env_vars.try_emplace("OS_ACTIVITY_DT_MODE", "enable");
}
// Let our parent class do the real launching.
@@ -1777,24 +1710,23 @@ PlatformDarwin::FindBundleBinaryInExecSearchPaths (const ModuleSpec &module_spec
ModuleSP *old_module_sp_ptr, bool *did_create_ptr)
{
const FileSpec &platform_file = module_spec.GetFileSpec();
- // See if the file is present in any of the module_search_paths_ptr directories.
+ // See if the file is present in any of the module_search_paths_ptr
+ // directories.
if (!module_sp && module_search_paths_ptr && platform_file) {
- // create a vector of all the file / directory names in platform_file
- // e.g. this might be
+ // create a vector of all the file / directory names in platform_file e.g.
+ // this might be
// /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
//
- // We'll need to look in the module_search_paths_ptr directories for
- // both "UIFoundation" and "UIFoundation.framework" -- most likely the
- // latter will be the one we find there.
+ // We'll need to look in the module_search_paths_ptr directories for both
+ // "UIFoundation" and "UIFoundation.framework" -- most likely the latter
+ // will be the one we find there.
FileSpec platform_pull_apart(platform_file);
std::vector<std::string> path_parts;
- ConstString unix_root_dir("/");
- while (true) {
+ path_parts.push_back(
+ platform_pull_apart.GetLastPathComponent().AsCString());
+ while (platform_pull_apart.RemoveLastPathComponent()) {
ConstString part = platform_pull_apart.GetLastPathComponent();
- platform_pull_apart.RemoveLastPathComponent();
- if (part.IsEmpty() || part == unix_root_dir)
- break;
path_parts.push_back(part.AsCString());
}
const size_t path_parts_size = path_parts.size();
@@ -1804,25 +1736,24 @@ PlatformDarwin::FindBundleBinaryInExecSearchPaths (const ModuleSpec &module_spec
Log *log_verbose = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
if (log_verbose)
log_verbose->Printf ("PlatformRemoteDarwinDevice::GetSharedModule searching for binary in search-path %s", module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath().c_str());
- // Create a new FileSpec with this module_search_paths_ptr
- // plus just the filename ("UIFoundation"), then the parent
- // dir plus filename ("UIFoundation.framework/UIFoundation")
- // etc - up to four names (to handle "Foo.framework/Contents/MacOS/Foo")
+ // Create a new FileSpec with this module_search_paths_ptr plus just the
+ // filename ("UIFoundation"), then the parent dir plus filename
+ // ("UIFoundation.framework/UIFoundation") etc - up to four names (to
+ // handle "Foo.framework/Contents/MacOS/Foo")
for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) {
FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i));
// Add the components backwards. For
- // .../PrivateFrameworks/UIFoundation.framework/UIFoundation
- // path_parts is
+ // .../PrivateFrameworks/UIFoundation.framework/UIFoundation path_parts
+ // is
// [0] UIFoundation
// [1] UIFoundation.framework
// [2] PrivateFrameworks
//
// and if 'j' is 2, we want to append path_parts[1] and then
- // path_parts[0], aka
- // 'UIFoundation.framework/UIFoundation', to the module_search_paths_ptr
- // path.
+ // path_parts[0], aka 'UIFoundation.framework/UIFoundation', to the
+ // module_search_paths_ptr path.
for (int k = j; k >= 0; --k) {
path_to_try.AppendPathComponent(path_parts[k]);
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/source/Plugins/Platform/MacOSX/PlatformDarwin.h
index c04318e98cae..3ad29ec1a0b9 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwin.h
+++ b/source/Plugins/Platform/MacOSX/PlatformDarwin.h
@@ -69,8 +69,8 @@ public:
void CalculateTrapHandlerSymbolNames() override;
- bool GetOSVersion(uint32_t &major, uint32_t &minor, uint32_t &update,
- lldb_private::Process *process = nullptr) override;
+ llvm::VersionTuple
+ GetOSVersion(lldb_private::Process *process = nullptr) override;
bool SupportsModules() override { return true; }
@@ -82,7 +82,7 @@ public:
lldb_private::Status
LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) override;
- static std::tuple<uint32_t, uint32_t, uint32_t, llvm::StringRef>
+ static std::tuple<llvm::VersionTuple, llvm::StringRef>
ParseVersionBuildDir(llvm::StringRef str);
protected:
@@ -101,8 +101,7 @@ protected:
iPhoneOS,
};
- static bool SDKSupportsModules(SDKType sdk_type, uint32_t major,
- uint32_t minor, uint32_t micro);
+ static bool SDKSupportsModules(SDKType sdk_type, llvm::VersionTuple version);
static bool SDKSupportsModules(SDKType desired_type,
const lldb_private::FileSpec &sdk_path);
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp b/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
index e5d27fc28949..1e3216c0af5a 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
@@ -92,11 +92,9 @@ PlatformSP PlatformDarwinKernel::CreateInstance(bool force,
}
// This is a special plugin that we don't want to activate just based on an
- // ArchSpec for normal
- // userland debugging. It is only useful in kernel debug sessions and the
- // DynamicLoaderDarwinPlugin
- // (or a user doing 'platform select') will force the creation of this
- // Platform plugin.
+ // ArchSpec for normal userland debugging. It is only useful in kernel debug
+ // sessions and the DynamicLoaderDarwinPlugin (or a user doing 'platform
+ // select') will force the creation of this Platform plugin.
if (force == false) {
if (log)
log->Printf("PlatformDarwinKernel::%s() aborting creation of platform "
@@ -115,9 +113,8 @@ PlatformSP PlatformDarwinKernel::CreateInstance(bool force,
create = true;
break;
- // Only accept "unknown" for vendor if the host is Apple and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
+ // Only accept "unknown" for vendor if the host is Apple and it "unknown"
+ // wasn't specified (it was just returned because it was NOT specified)
case llvm::Triple::UnknownArch:
create = !arch->TripleVendorWasSpecified();
break;
@@ -133,9 +130,8 @@ PlatformSP PlatformDarwinKernel::CreateInstance(bool force,
case llvm::Triple::WatchOS:
case llvm::Triple::TvOS:
break;
- // Only accept "vendor" for vendor if the host is Apple and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
+ // Only accept "vendor" for vendor if the host is Apple and it "unknown"
+ // wasn't specified (it was just returned because it was NOT specified)
case llvm::Triple::UnknownOS:
create = !arch->TripleOSWasSpecified();
break;
@@ -341,11 +337,9 @@ void PlatformDarwinKernel::GetStatus(Stream &strm) {
void PlatformDarwinKernel::CollectKextAndKernelDirectories() {
// Differentiate between "ios debug session" and "mac debug session" so we
- // don't index
- // kext bundles that won't be used in this debug session. If this is an ios
- // kext debug
- // session, looking in /System/Library/Extensions is a waste of stat()s, for
- // example.
+ // don't index kext bundles that won't be used in this debug session. If
+ // this is an ios kext debug session, looking in /System/Library/Extensions
+ // is a waste of stat()s, for example.
// DeveloperDirectory is something like
// "/Applications/Xcode.app/Contents/Developer"
@@ -368,9 +362,8 @@ void PlatformDarwinKernel::CollectKextAndKernelDirectories() {
AddSDKSubdirsToSearchPaths("/Volumes/KernelDebugKit");
AddSDKSubdirsToSearchPaths("/AppleInternal/Developer/KDKs");
- // The KDKs distributed from Apple installed on external
- // developer systems may be in directories like
- // /Library/Developer/KDKs/KDK_10.10_14A298i.kdk
+ // The KDKs distributed from Apple installed on external developer systems
+ // may be in directories like /Library/Developer/KDKs/KDK_10.10_14A298i.kdk
AddSDKSubdirsToSearchPaths("/Library/Developer/KDKs");
if (m_ios_debug_session != eLazyBoolNo) {
@@ -438,8 +431,8 @@ void PlatformDarwinKernel::AddSDKSubdirsToSearchPaths(const std::string &dir) {
FileSpec::EnumerateDirectoryResult
PlatformDarwinKernel::FindKDKandSDKDirectoriesInDirectory(
void *baton, llvm::sys::fs::file_type ft, const FileSpec &file_spec) {
- static ConstString g_sdk_suffix = ConstString("sdk");
- static ConstString g_kdk_suffix = ConstString("kdk");
+ static ConstString g_sdk_suffix = ConstString(".sdk");
+ static ConstString g_kdk_suffix = ConstString(".kdk");
PlatformDarwinKernel *thisp = (PlatformDarwinKernel *)baton;
if (ft == llvm::sys::fs::file_type::directory_file &&
@@ -450,9 +443,8 @@ PlatformDarwinKernel::FindKDKandSDKDirectoriesInDirectory(
return FileSpec::eEnumerateDirectoryResultNext;
}
-// Recursively search trough m_search_directories looking for
-// kext and kernel binaries, adding files found to the appropriate
-// lists.
+// Recursively search trough m_search_directories looking for kext and kernel
+// binaries, adding files found to the appropriate lists.
void PlatformDarwinKernel::SearchForKextsAndKernelsRecursively() {
const uint32_t num_dirs = m_search_directories.size();
for (uint32_t i = 0; i < num_dirs; i++) {
@@ -476,13 +468,11 @@ void PlatformDarwinKernel::SearchForKextsAndKernelsRecursively() {
}
}
-// We're only doing a filename match here. We won't try opening the file to see
-// if it's really
-// a kernel or not until we need to find a kernel of a given UUID. There's no
-// cheap way to find
-// the UUID of a file (or if it's a Mach-O binary at all) without creating a
-// whole Module for
-// the file and throwing it away if it's not wanted.
+// We're only doing a filename match here. We won't try opening the file to
+// see if it's really a kernel or not until we need to find a kernel of a given
+// UUID. There's no cheap way to find the UUID of a file (or if it's a Mach-O
+// binary at all) without creating a whole Module for the file and throwing it
+// away if it's not wanted.
//
// Recurse into any subdirectories found.
@@ -502,8 +492,8 @@ FileSpec::EnumerateDirectoryResult
PlatformDarwinKernel::GetKernelsAndKextsInDirectoryHelper(
void *baton, llvm::sys::fs::file_type ft, const FileSpec &file_spec,
bool recurse) {
- static ConstString g_kext_suffix = ConstString("kext");
- static ConstString g_dsym_suffix = ConstString("dSYM");
+ static ConstString g_kext_suffix = ConstString(".kext");
+ static ConstString g_dsym_suffix = ConstString(".dSYM");
static ConstString g_bundle_suffix = ConstString("Bundle");
ConstString file_spec_extension = file_spec.GetFileNameExtension();
@@ -633,7 +623,7 @@ bool PlatformDarwinKernel::KextHasdSYMSibling(
kext_bundle_filepath.GetPath() + "/Contents/MacOS/";
deep_bundle_str += executable_name.AsCString();
deep_bundle_str += ".dSYM";
- dsym_fspec.SetFile(deep_bundle_str, true);
+ dsym_fspec.SetFile(deep_bundle_str, true, FileSpec::Style::native);
if (llvm::sys::fs::is_directory(dsym_fspec.GetPath())) {
return true;
}
@@ -643,15 +633,15 @@ bool PlatformDarwinKernel::KextHasdSYMSibling(
std::string shallow_bundle_str = kext_bundle_filepath.GetPath() + "/";
shallow_bundle_str += executable_name.AsCString();
shallow_bundle_str += ".dSYM";
- dsym_fspec.SetFile(shallow_bundle_str, true);
+ dsym_fspec.SetFile(shallow_bundle_str, true, FileSpec::Style::native);
if (llvm::sys::fs::is_directory(dsym_fspec.GetPath())) {
return true;
}
return false;
}
-// Given a FileSpec of /dir/dir/mach.development.t7004
-// Return true if a dSYM exists next to it:
+// Given a FileSpec of /dir/dir/mach.development.t7004 Return true if a dSYM
+// exists next to it:
// /dir/dir/mach.development.t7004.dSYM
bool PlatformDarwinKernel::KernelHasdSYMSibling(const FileSpec &kernel_binary) {
FileSpec kernel_dsym = kernel_binary;
@@ -694,8 +684,8 @@ Status PlatformDarwinKernel::GetSharedModule(
}
}
- // Give the generic methods, including possibly calling into
- // DebugSymbols framework on macOS systems, a chance.
+ // Give the generic methods, including possibly calling into DebugSymbols
+ // framework on macOS systems, a chance.
error = PlatformDarwin::GetSharedModule(module_spec, process, module_sp,
module_search_paths_ptr,
old_module_sp_ptr, did_create_ptr);
@@ -749,8 +739,8 @@ Status PlatformDarwinKernel::GetSharedModule(
}
}
- // Give the generic methods, including possibly calling into
- // DebugSymbols framework on macOS systems, a chance.
+ // Give the generic methods, including possibly calling into DebugSymbols
+ // framework on macOS systems, a chance.
error = PlatformDarwin::GetSharedModule(module_spec, process, module_sp,
module_search_paths_ptr,
old_module_sp_ptr, did_create_ptr);
@@ -789,37 +779,53 @@ Status PlatformDarwinKernel::GetSharedModule(
return error;
}
+std::vector<lldb_private::FileSpec>
+PlatformDarwinKernel::SearchForExecutablesRecursively(const std::string &dir) {
+ std::vector<FileSpec> executables;
+ std::error_code EC;
+ for (llvm::sys::fs::recursive_directory_iterator it(dir.c_str(), EC),
+ end;
+ it != end && !EC; it.increment(EC)) {
+ auto status = it->status();
+ if (!status)
+ break;
+ if (llvm::sys::fs::is_regular_file(*status) &&
+ llvm::sys::fs::can_execute(it->path()))
+ executables.emplace_back(it->path(), false);
+ }
+ return executables;
+}
+
Status PlatformDarwinKernel::ExamineKextForMatchingUUID(
const FileSpec &kext_bundle_path, const lldb_private::UUID &uuid,
const ArchSpec &arch, ModuleSP &exe_module_sp) {
- Status error;
- FileSpec exe_file = kext_bundle_path;
- Host::ResolveExecutableInBundle(exe_file);
- if (exe_file.Exists()) {
- ModuleSpec exe_spec(exe_file);
- exe_spec.GetUUID() = uuid;
- if (!uuid.IsValid()) {
- exe_spec.GetArchitecture() = arch;
- }
+ for (const auto &exe_file :
+ SearchForExecutablesRecursively(kext_bundle_path.GetPath())) {
+ if (exe_file.Exists()) {
+ ModuleSpec exe_spec(exe_file);
+ exe_spec.GetUUID() = uuid;
+ if (!uuid.IsValid()) {
+ exe_spec.GetArchitecture() = arch;
+ }
- // First try to create a ModuleSP with the file / arch and see if the UUID
- // matches.
- // If that fails (this exec file doesn't have the correct uuid), don't call
- // GetSharedModule
- // (which may call in to the DebugSymbols framework and therefore can be
- // slow.)
- ModuleSP module_sp(new Module(exe_spec));
- if (module_sp && module_sp->GetObjectFile() &&
- module_sp->MatchesModuleSpec(exe_spec)) {
- error = ModuleList::GetSharedModule(exe_spec, exe_module_sp, NULL, NULL,
- NULL);
- if (exe_module_sp && exe_module_sp->GetObjectFile()) {
- return error;
+ // First try to create a ModuleSP with the file / arch and see if the UUID
+ // matches. If that fails (this exec file doesn't have the correct uuid),
+ // don't call GetSharedModule (which may call in to the DebugSymbols
+ // framework and therefore can be slow.)
+ ModuleSP module_sp(new Module(exe_spec));
+ if (module_sp && module_sp->GetObjectFile() &&
+ module_sp->MatchesModuleSpec(exe_spec)) {
+ Status error = ModuleList::GetSharedModule(exe_spec, exe_module_sp,
+ NULL, NULL, NULL);
+ if (exe_module_sp && exe_module_sp->GetObjectFile()) {
+ return error;
+ }
}
+ exe_module_sp.reset();
}
- exe_module_sp.reset();
}
- return error;
+
+ return {};
}
bool PlatformDarwinKernel::GetSupportedArchitectureAtIndex(uint32_t idx,
@@ -851,17 +857,13 @@ void PlatformDarwinKernel::CalculateTrapHandlerSymbolNames() {
#else // __APPLE__
-// Since DynamicLoaderDarwinKernel is compiled in for all systems, and relies on
-// PlatformDarwinKernel for the plug-in name, we compile just the plug-in name
-// in
-// here to avoid issues. We are tracking an internal bug to resolve this issue
-// by
-// either not compiling in DynamicLoaderDarwinKernel for non-apple builds, or to
-// make
-// PlatformDarwinKernel build on all systems. PlatformDarwinKernel is currently
-// not
-// compiled on other platforms due to the use of the Mac-specific
-// source/Host/macosx/cfcpp utilities.
+// Since DynamicLoaderDarwinKernel is compiled in for all systems, and relies
+// on PlatformDarwinKernel for the plug-in name, we compile just the plug-in
+// name in here to avoid issues. We are tracking an internal bug to resolve
+// this issue by either not compiling in DynamicLoaderDarwinKernel for non-
+// apple builds, or to make PlatformDarwinKernel build on all systems.
+// PlatformDarwinKernel is currently not compiled on other platforms due to the
+// use of the Mac-specific source/Host/macosx/cfcpp utilities.
lldb_private::ConstString PlatformDarwinKernel::GetPluginNameStatic() {
static lldb_private::ConstString g_name("darwin-kernel");
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h b/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h
index 9b3ec5e0d717..7f603cac2bec 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h
+++ b/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h
@@ -127,6 +127,9 @@ protected:
const lldb_private::FileSpec &file_spec,
bool recurse);
+ static std::vector<lldb_private::FileSpec>
+ SearchForExecutablesRecursively(const std::string &dir);
+
static void AddKextToMap(PlatformDarwinKernel *thisp,
const lldb_private::FileSpec &file_spec);
@@ -201,6 +204,7 @@ public:
// source/Host/macosx/cfcpp utilities.
class PlatformDarwinKernel {
+public:
static lldb_private::ConstString GetPluginNameStatic();
};
diff --git a/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp b/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
index 43f4d8bbf023..99f603b01f43 100644
--- a/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
@@ -91,9 +91,8 @@ PlatformSP PlatformMacOSX::CreateInstance(bool force, const ArchSpec *arch) {
break;
#if defined(__APPLE__)
- // Only accept "unknown" for vendor if the host is Apple and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
+ // Only accept "unknown" for vendor if the host is Apple and it "unknown"
+ // wasn't specified (it was just returned because it was NOT specified)
case llvm::Triple::UnknownArch:
create = !arch->TripleVendorWasSpecified();
break;
@@ -109,9 +108,8 @@ PlatformSP PlatformMacOSX::CreateInstance(bool force, const ArchSpec *arch) {
case llvm::Triple::MacOSX:
break;
#if defined(__APPLE__)
- // Only accept "vendor" for vendor if the host is Apple and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
+ // Only accept "vendor" for vendor if the host is Apple and it "unknown"
+ // wasn't specified (it was just returned because it was NOT specified)
case llvm::Triple::UnknownOS:
create = !arch->TripleOSWasSpecified();
break;
@@ -175,7 +173,8 @@ ConstString PlatformMacOSX::GetSDKDirectory(lldb_private::Target &target) {
FileSpec fspec;
uint32_t versions[2];
if (objfile->GetSDKVersion(versions, sizeof(versions))) {
- if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, fspec)) {
+ fspec = HostInfo::GetShlibDir();
+ if (fspec) {
std::string path;
xcode_contents_path = fspec.GetPath();
size_t pos = xcode_contents_path.find("/Xcode.app/Contents/");
@@ -198,7 +197,7 @@ ConstString PlatformMacOSX::GetSDKDirectory(lldb_private::Target &target) {
// here
&output, // Get the output from the command and place it in this
// string
- 3); // Timeout in seconds to wait for shell program to finish
+ std::chrono::seconds(3));
if (status == 0 && !output.empty()) {
size_t first_non_newline = output.find_last_not_of("\r\n");
if (first_non_newline != std::string::npos)
@@ -219,13 +218,13 @@ ConstString PlatformMacOSX::GetSDKDirectory(lldb_private::Target &target) {
"SDKs/MacOSX%u.%u.sdk",
xcode_contents_path.c_str(), versions[0],
versions[1]);
- fspec.SetFile(sdk_path.GetString(), false);
+ fspec.SetFile(sdk_path.GetString(), false, FileSpec::Style::native);
if (fspec.Exists())
return ConstString(sdk_path.GetString());
}
if (!default_xcode_sdk.empty()) {
- fspec.SetFile(default_xcode_sdk, false);
+ fspec.SetFile(default_xcode_sdk, false, FileSpec::Style::native);
if (fspec.Exists())
return ConstString(default_xcode_sdk);
}
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp
index 1eef643d3904..be4c829a981c 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp
@@ -99,8 +99,8 @@ PlatformSP PlatformRemoteAppleTV::CreateInstance(bool force,
#if defined(__APPLE__)
// Only accept "unknown" for the vendor if the host is Apple and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
+ // "unknown" wasn't specified (it was just returned because it was NOT
+ // specified)
case llvm::Triple::UnknownArch:
create = !arch->TripleVendorWasSpecified();
break;
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp
index 17ae67bc28de..6159511d4a18 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp
@@ -94,8 +94,8 @@ PlatformSP PlatformRemoteAppleWatch::CreateInstance(bool force,
#if defined(__APPLE__)
// Only accept "unknown" for the vendor if the host is Apple and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
+ // "unknown" wasn't specified (it was just returned because it was NOT
+ // specified)
case llvm::Triple::UnknownArch:
create = !arch->TripleVendorWasSpecified();
break;
@@ -123,8 +123,8 @@ PlatformSP PlatformRemoteAppleWatch::CreateInstance(bool force,
#if defined(__APPLE__) && \
(defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
- // If lldb is running on a watch, this isn't a RemoteWatch environment; it's a
- // local system environment.
+ // If lldb is running on a watch, this isn't a RemoteWatch environment; it's
+ // a local system environment.
if (force == false) {
create = false;
}
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp
index cb064aad6155..930d062fe41e 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp
@@ -31,12 +31,10 @@ using namespace lldb_private;
PlatformRemoteDarwinDevice::SDKDirectoryInfo::SDKDirectoryInfo(
const lldb_private::FileSpec &sdk_dir)
- : directory(sdk_dir), build(), version_major(0), version_minor(0),
- version_update(0), user_cached(false) {
+ : directory(sdk_dir), build(), user_cached(false) {
llvm::StringRef dirname_str = sdk_dir.GetFilename().GetStringRef();
llvm::StringRef build_str;
- std::tie(version_major, version_minor, version_update, build_str) =
- ParseVersionBuildDir(dirname_str);
+ std::tie(version, build_str) = ParseVersionBuildDir(dirname_str);
build.SetString(build_str);
}
@@ -97,9 +95,9 @@ Status PlatformRemoteDarwinDevice::ResolveExecutable(
return error;
exe_module_sp.reset();
}
- // No valid architecture was specified or the exact ARM slice wasn't
- // found so ask the platform for the architectures that we should be
- // using (in the correct order) and see if we can find a match that way
+ // No valid architecture was specified or the exact ARM slice wasn't found
+ // so ask the platform for the architectures that we should be using (in
+ // the correct order) and see if we can find a match that way
StreamString arch_names;
for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
idx, resolved_module_spec.GetArchitecture());
@@ -183,8 +181,8 @@ bool PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded() {
&builtin_sdk_directory_infos);
// Only add SDK directories that have symbols in them, some SDKs only
- // contain
- // developer disk images and no symbols, so they aren't useful to us.
+ // contain developer disk images and no symbols, so they aren't useful to
+ // us.
FileSpec sdk_symbols_symlink_fspec;
for (const auto &sdk_directory_info : builtin_sdk_directory_infos) {
sdk_symbols_symlink_fspec = sdk_directory_info.directory;
@@ -244,8 +242,8 @@ PlatformRemoteDarwinDevice::GetSDKDirectoryForCurrentOSVersion() {
if (UpdateSDKDirectoryInfosIfNeeded()) {
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- // Check to see if the user specified a build string. If they did, then
- // be sure to match it.
+ // Check to see if the user specified a build string. If they did, then be
+ // sure to match it.
std::vector<bool> check_sdk_info(num_sdk_infos, true);
ConstString build(m_sdk_build);
if (build) {
@@ -253,26 +251,25 @@ PlatformRemoteDarwinDevice::GetSDKDirectoryForCurrentOSVersion() {
check_sdk_info[i] = m_sdk_directory_infos[i].build == build;
}
- // If we are connected we can find the version of the OS the platform
- // us running on and select the right SDK
- uint32_t major, minor, update;
- if (GetOSVersion(major, minor, update)) {
+ // If we are connected we can find the version of the OS the platform us
+ // running on and select the right SDK
+ llvm::VersionTuple version = GetOSVersion();
+ if (!version.empty()) {
if (UpdateSDKDirectoryInfosIfNeeded()) {
// First try for an exact match of major, minor and update
for (i = 0; i < num_sdk_infos; ++i) {
if (check_sdk_info[i]) {
- if (m_sdk_directory_infos[i].version_major == major &&
- m_sdk_directory_infos[i].version_minor == minor &&
- m_sdk_directory_infos[i].version_update == update) {
+ if (m_sdk_directory_infos[i].version == version)
return &m_sdk_directory_infos[i];
- }
}
}
// First try for an exact match of major and minor
for (i = 0; i < num_sdk_infos; ++i) {
if (check_sdk_info[i]) {
- if (m_sdk_directory_infos[i].version_major == major &&
- m_sdk_directory_infos[i].version_minor == minor) {
+ if (m_sdk_directory_infos[i].version.getMajor() ==
+ version.getMajor() &&
+ m_sdk_directory_infos[i].version.getMinor() ==
+ version.getMinor()) {
return &m_sdk_directory_infos[i];
}
}
@@ -280,7 +277,8 @@ PlatformRemoteDarwinDevice::GetSDKDirectoryForCurrentOSVersion() {
// Lastly try to match of major version only..
for (i = 0; i < num_sdk_infos; ++i) {
if (check_sdk_info[i]) {
- if (m_sdk_directory_infos[i].version_major == major) {
+ if (m_sdk_directory_infos[i].version.getMajor() ==
+ version.getMajor()) {
return &m_sdk_directory_infos[i];
}
}
@@ -300,25 +298,13 @@ const PlatformRemoteDarwinDevice::SDKDirectoryInfo *
PlatformRemoteDarwinDevice::GetSDKDirectoryForLatestOSVersion() {
const PlatformRemoteDarwinDevice::SDKDirectoryInfo *result = NULL;
if (UpdateSDKDirectoryInfosIfNeeded()) {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- // First try for an exact match of major, minor and update
- for (uint32_t i = 0; i < num_sdk_infos; ++i) {
- const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
- if (sdk_dir_info.version_major != UINT32_MAX) {
- if (result == NULL ||
- sdk_dir_info.version_major > result->version_major) {
- result = &sdk_dir_info;
- } else if (sdk_dir_info.version_major == result->version_major) {
- if (sdk_dir_info.version_minor > result->version_minor) {
- result = &sdk_dir_info;
- } else if (sdk_dir_info.version_minor == result->version_minor) {
- if (sdk_dir_info.version_update > result->version_update) {
- result = &sdk_dir_info;
- }
- }
- }
- }
- }
+ auto max = std::max_element(
+ m_sdk_directory_infos.begin(), m_sdk_directory_infos.end(),
+ [](const SDKDirectoryInfo &a, const SDKDirectoryInfo &b) {
+ return a.version < b.version;
+ });
+ if (max != m_sdk_directory_infos.end())
+ result = &*max;
}
return result;
}
@@ -366,8 +352,8 @@ const char *PlatformRemoteDarwinDevice::GetDeviceSupportDirectoryForOSVersion()
}
}
// We should have put a single NULL character into
- // m_device_support_directory_for_os_version
- // or it should have a valid path if the code gets here
+ // m_device_support_directory_for_os_version or it should have a valid path
+ // if the code gets here
assert(m_device_support_directory_for_os_version.empty() == false);
if (m_device_support_directory_for_os_version[0])
return m_device_support_directory_for_os_version.c_str();
@@ -409,7 +395,7 @@ bool PlatformRemoteDarwinDevice::GetFileInSDK(const char *platform_file_path,
const char *paths_to_try[] = {"Symbols", "", "Symbols.Internal", nullptr};
for (size_t i = 0; paths_to_try[i] != nullptr; i++) {
- local_file.SetFile(sdkroot_path, false);
+ local_file.SetFile(sdkroot_path, false, FileSpec::Style::native);
if (paths_to_try[i][0] != '\0')
local_file.AppendPathComponent(paths_to_try[i]);
local_file.AppendPathComponent(platform_file_path);
@@ -442,7 +428,7 @@ Status PlatformRemoteDarwinDevice::GetSymbolFile(const FileSpec &platform_file,
::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", os_version_dir,
platform_file_path);
- local_file.SetFile(resolved_path, true);
+ local_file.SetFile(resolved_path, true, FileSpec::Style::native);
if (local_file.Exists()) {
if (log) {
log->Printf("Found a copy of %s in the DeviceSupport dir %s",
@@ -454,7 +440,7 @@ Status PlatformRemoteDarwinDevice::GetSymbolFile(const FileSpec &platform_file,
::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols.Internal/%s",
os_version_dir, platform_file_path);
- local_file.SetFile(resolved_path, true);
+ local_file.SetFile(resolved_path, true, FileSpec::Style::native);
if (local_file.Exists()) {
if (log) {
log->Printf(
@@ -466,7 +452,7 @@ Status PlatformRemoteDarwinDevice::GetSymbolFile(const FileSpec &platform_file,
::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols/%s",
os_version_dir, platform_file_path);
- local_file.SetFile(resolved_path, true);
+ local_file.SetFile(resolved_path, true, FileSpec::Style::native);
if (local_file.Exists()) {
if (log) {
log->Printf("Found a copy of %s in the DeviceSupport dir %s/Symbols",
@@ -492,10 +478,9 @@ Status PlatformRemoteDarwinDevice::GetSharedModule(
const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
bool *did_create_ptr) {
- // For iOS, the SDK files are all cached locally on the host
- // system. So first we ask for the file in the cached SDK,
- // then we attempt to get a shared module for the right architecture
- // with the right UUID.
+ // For iOS, the SDK files are all cached locally on the host system. So first
+ // we ask for the file in the cached SDK, then we attempt to get a shared
+ // module for the right architecture with the right UUID.
const FileSpec &platform_file = module_spec.GetFileSpec();
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
@@ -510,8 +495,7 @@ Status PlatformRemoteDarwinDevice::GetSharedModule(
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
// If we are connected we migth be able to correctly deduce the SDK
- // directory
- // using the OS build.
+ // directory using the OS build.
const uint32_t connected_sdk_idx = GetConnectedSDKIndex();
if (connected_sdk_idx < num_sdk_infos) {
LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
@@ -528,8 +512,8 @@ Status PlatformRemoteDarwinDevice::GetSharedModule(
}
}
- // Try the last SDK index if it is set as most files from an SDK
- // will tend to be valid in that same SDK.
+ // Try the last SDK index if it is set as most files from an SDK will tend
+ // to be valid in that same SDK.
if (m_last_module_sdk_idx < num_sdk_infos) {
LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
m_sdk_directory_infos[m_last_module_sdk_idx].directory);
@@ -544,9 +528,9 @@ Status PlatformRemoteDarwinDevice::GetSharedModule(
}
}
- // First try for an exact match of major, minor and update:
- // If a particalar SDK version was specified via --version or --build, look
- // for a match on disk.
+ // First try for an exact match of major, minor and update: If a particalar
+ // SDK version was specified via --version or --build, look for a match on
+ // disk.
const SDKDirectoryInfo *current_sdk_info =
GetSDKDirectoryForCurrentOSVersion();
const uint32_t current_sdk_idx =
@@ -570,8 +554,7 @@ Status PlatformRemoteDarwinDevice::GetSharedModule(
// Second try all SDKs that were found.
for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
if (m_last_module_sdk_idx == sdk_idx) {
- // Skip the last module SDK index if we already searched
- // it above
+ // Skip the last module SDK index if we already searched it above
continue;
}
LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
@@ -582,8 +565,8 @@ Status PlatformRemoteDarwinDevice::GetSharedModule(
error = ResolveExecutable(platform_module_spec, module_sp, NULL);
if (module_sp) {
- // Remember the index of the last SDK that we found a file
- // in in case the wrong SDK was selected.
+ // Remember the index of the last SDK that we found a file in in case
+ // the wrong SDK was selected.
m_last_module_sdk_idx = sdk_idx;
error.Clear();
return error;
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h b/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h
index f159e8575d76..8ddfd51600fd 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h
@@ -60,9 +60,7 @@ protected:
SDKDirectoryInfo(const lldb_private::FileSpec &sdk_dir_spec);
lldb_private::FileSpec directory;
lldb_private::ConstString build;
- uint32_t version_major;
- uint32_t version_minor;
- uint32_t version_update;
+ llvm::VersionTuple version;
bool user_cached;
};
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
index 5bff792525bc..150bfdbfc118 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
@@ -89,8 +89,8 @@ PlatformSP PlatformRemoteiOS::CreateInstance(bool force, const ArchSpec *arch) {
#if defined(__APPLE__)
// Only accept "unknown" for the vendor if the host is Apple and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
+ // "unknown" wasn't specified (it was just returned because it was NOT
+ // specified)
case llvm::Triple::UnknownArch:
create = !arch->TripleVendorWasSpecified();
break;
diff --git a/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
index ee1f90311e7e..26feec282322 100644
--- a/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
@@ -91,9 +91,9 @@ PlatformSP PlatformiOSSimulator::CreateInstance(bool force,
break;
#if defined(__APPLE__)
- // Only accept "unknown" for the vendor if the host is Apple and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
+ // Only accept "unknown" for the vendor if the host is Apple and it
+ // "unknown" wasn't specified (it was just returned because it was NOT
+ // specified)
case llvm::Triple::UnknownArch:
create = !arch->TripleVendorWasSpecified();
break;
@@ -112,9 +112,9 @@ PlatformSP PlatformiOSSimulator::CreateInstance(bool force,
break;
#if defined(__APPLE__)
- // Only accept "unknown" for the OS if the host is Apple and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
+ // Only accept "unknown" for the OS if the host is Apple and it
+ // "unknown" wasn't specified (it was just returned because it was NOT
+ // specified)
case llvm::Triple::UnknownOS:
create = !arch->TripleOSWasSpecified();
break;
@@ -205,9 +205,9 @@ Status PlatformiOSSimulator::ResolveExecutable(
return error;
exe_module_sp.reset();
}
- // No valid architecture was specified or the exact ARM slice wasn't
- // found so ask the platform for the architectures that we should be
- // using (in the correct order) and see if we can find a match that way
+ // No valid architecture was specified or the exact ARM slice wasn't found
+ // so ask the platform for the architectures that we should be using (in
+ // the correct order) and see if we can find a match that way
StreamString arch_names;
ArchSpec platform_arch;
for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
@@ -298,8 +298,8 @@ const char *PlatformiOSSimulator::GetSDKDirectoryAsCString() {
m_sdk_directory.assign(1, '\0');
}
- // We should have put a single NULL character into m_sdk_directory
- // or it should have a valid path if the code gets here
+ // We should have put a single NULL character into m_sdk_directory or it
+ // should have a valid path if the code gets here
assert(m_sdk_directory.empty() == false);
if (m_sdk_directory[0])
return m_sdk_directory.c_str();
@@ -320,12 +320,12 @@ Status PlatformiOSSimulator::GetSymbolFile(const FileSpec &platform_file,
platform_file_path);
// First try in the SDK and see if the file is in there
- local_file.SetFile(resolved_path, true);
+ local_file.SetFile(resolved_path, true, FileSpec::Style::native);
if (local_file.Exists())
return error;
// Else fall back to the actual path itself
- local_file.SetFile(platform_file_path, true);
+ local_file.SetFile(platform_file_path, true, FileSpec::Style::native);
if (local_file.Exists())
return error;
}
@@ -342,10 +342,9 @@ Status PlatformiOSSimulator::GetSharedModule(
const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
bool *did_create_ptr) {
- // For iOS, the SDK files are all cached locally on the host
- // system. So first we ask for the file in the cached SDK,
- // then we attempt to get a shared module for the right architecture
- // with the right UUID.
+ // For iOS, the SDK files are all cached locally on the host system. So first
+ // we ask for the file in the cached SDK, then we attempt to get a shared
+ // module for the right architecture with the right UUID.
Status error;
ModuleSpec platform_module_spec(module_spec);
const FileSpec &platform_file = module_spec.GetFileSpec();
@@ -409,14 +408,14 @@ bool PlatformiOSSimulator::GetSupportedArchitectureAtIndex(uint32_t idx,
if (arch.IsValid()) {
if (idx == 2)
arch.GetTriple().setOS(llvm::Triple::IOS);
- // 32/64: return "i386-apple-ios" for architecture 2
- // 32/64: return "i386-apple-macosx" for architecture 3
+ // 32/64: return "i386-apple-ios" for architecture 2 32/64: return
+ // "i386-apple-macosx" for architecture 3
return true;
}
}
} else if (idx == 1) {
- // This macosx platform supports only 32 bit, so return the *-apple-macosx
- // version
+ // This macosx platform supports only 32 bit, so return the *-apple-
+ // macosx version
arch = platform_arch;
return true;
}
diff --git a/source/Plugins/Platform/MacOSX/objcxx/CMakeLists.txt b/source/Plugins/Platform/MacOSX/objcxx/CMakeLists.txt
new file mode 100644
index 000000000000..946ff0a64c26
--- /dev/null
+++ b/source/Plugins/Platform/MacOSX/objcxx/CMakeLists.txt
@@ -0,0 +1,17 @@
+remove_module_flags()
+include_directories(.)
+
+add_lldb_library(lldbPluginPlatformMacOSXObjCXX
+ PlatformiOSSimulatorCoreSimulatorSupport.mm
+
+ LINK_LIBS
+ lldbCore
+ lldbSymbol
+ lldbTarget
+ lldbUtility
+ ${EXTRA_LIBS}
+
+ LINK_COMPONENTS
+ Object
+ Support
+ )
diff --git a/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.h b/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h
index 31e11a60e419..083e2d6c5687 100644
--- a/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.h
+++ b/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h
@@ -24,8 +24,8 @@
typedef void *id;
#endif
// Project includes
-#include "lldb/Interpreter/Args.h"
#include "lldb/Target/ProcessLaunchInfo.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Status.h"
diff --git a/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm b/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm
index 7bd37683d2fd..4516a66ee8ca 100644
--- a/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm
+++ b/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm
@@ -478,26 +478,17 @@ CoreSimulatorSupport::Device::Spawn(ProcessLaunchInfo &launch_info) {
[options setObject:args_array forKey:kSimDeviceSpawnArguments];
}
- if (launch_info.GetEnvironmentEntries().GetArgumentCount()) {
- const Args &envs(launch_info.GetEnvironmentEntries());
- NSMutableDictionary *env_dict = [[NSMutableDictionary alloc] init];
- for (size_t idx = 0; idx < envs.GetArgumentCount(); idx++) {
- llvm::StringRef arg_sr(envs.GetArgumentAtIndex(idx));
- auto first_eq = arg_sr.find('=');
- if (first_eq == llvm::StringRef::npos)
- continue;
- llvm::StringRef key = arg_sr.substr(0, first_eq);
- llvm::StringRef value = arg_sr.substr(first_eq + 1);
+ NSMutableDictionary *env_dict = [[NSMutableDictionary alloc] init];
- NSString *key_ns = [NSString stringWithUTF8String:key.str().c_str()];
- NSString *value_ns = [NSString stringWithUTF8String:value.str().c_str()];
+ for (const auto &KV : launch_info.GetEnvironment()) {
+ NSString *key_ns = [NSString stringWithUTF8String:KV.first().str().c_str()];
+ NSString *value_ns = [NSString stringWithUTF8String:KV.second.c_str()];
- [env_dict setValue:value_ns forKey:key_ns];
- }
-
- [options setObject:env_dict forKey:kSimDeviceSpawnEnvironment];
+ [env_dict setValue:value_ns forKey:key_ns];
}
+ [options setObject:env_dict forKey:kSimDeviceSpawnEnvironment];
+
Status error;
File stdin_file;
File stdout_file;
diff --git a/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp b/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
index 38bdf60c1ced..3aa8ecb4c228 100644
--- a/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
+++ b/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
@@ -30,8 +30,8 @@
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
-// Define these constants from NetBSD mman.h for use when targeting
-// remote netbsd systems even when host has different values.
+// Define these constants from NetBSD mman.h for use when targeting remote
+// netbsd systems even when host has different values.
#define MAP_PRIVATE 0x0002
#define MAP_ANON 0x1000
@@ -45,19 +45,9 @@ static uint32_t g_initialize_count = 0;
PlatformSP PlatformNetBSD::CreateInstance(bool force, const ArchSpec *arch) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log) {
- const char *arch_name;
- if (arch && arch->GetArchitectureName())
- arch_name = arch->GetArchitectureName();
- else
- arch_name = "<null>";
-
- const char *triple_cstr =
- arch ? arch->GetTriple().getTriple().c_str() : "<null>";
-
- log->Printf("PlatformNetBSD::%s(force=%s, arch={%s,%s})", __FUNCTION__,
- force ? "true" : "false", arch_name, triple_cstr);
- }
+ LLDB_LOG(log, "force = {0}, arch=({1}, {2})", force,
+ arch ? arch->GetArchitectureName() : "<null>",
+ arch ? arch->GetTriple().getTriple() : "<null>");
bool create = force;
if (create == false && arch && arch->IsValid()) {
@@ -72,18 +62,10 @@ PlatformSP PlatformNetBSD::CreateInstance(bool force, const ArchSpec *arch) {
}
}
+ LLDB_LOG(log, "create = {0}", create);
if (create) {
- if (log)
- log->Printf("PlatformNetBSD::%s() creating remote-netbsd platform",
- __FUNCTION__);
return PlatformSP(new PlatformNetBSD(false));
}
-
- if (log)
- log->Printf(
- "PlatformNetBSD::%s() aborting creation of remote-netbsd platform",
- __FUNCTION__);
-
return PlatformSP();
}
@@ -152,7 +134,8 @@ bool PlatformNetBSD::GetSupportedArchitectureAtIndex(uint32_t idx,
arch = hostArch;
return arch.IsValid();
} else if (idx == 1) {
- // If the default host architecture is 64-bit, look for a 32-bit variant
+ // If the default host architecture is 64-bit, look for a 32-bit
+ // variant
if (hostArch.IsValid() && hostArch.GetTriple().isArch64Bit()) {
arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
return arch.IsValid();
@@ -178,13 +161,10 @@ bool PlatformNetBSD::GetSupportedArchitectureAtIndex(uint32_t idx,
return false;
}
// Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the
- // vendor by
- // calling triple.SetVendorName("unknown") so that it is a "unspecified
- // unknown".
- // This means when someone calls triple.GetVendorName() it will return an
- // empty string
- // which indicates that the vendor can be set when two architectures are
- // merged
+ // vendor by calling triple.SetVendorName("unknown") so that it is a
+ // "unspecified unknown". This means when someone calls
+ // triple.GetVendorName() it will return an empty string which indicates
+ // that the vendor can be set when two architectures are merged
// Now set the triple into "arch" and return true
arch.SetTriple(triple);
@@ -258,19 +238,15 @@ bool PlatformNetBSD::CanDebugProcess() {
}
// For local debugging, NetBSD will override the debug logic to use llgs-launch
-// rather than
-// lldb-launch, llgs-attach. This differs from current lldb-launch,
-// debugserver-attach
-// approach on MacOSX.
-lldb::ProcessSP PlatformNetBSD::DebugProcess(
- ProcessLaunchInfo &launch_info, Debugger &debugger,
- Target *target, // Can be NULL, if NULL create a new
- // target, else use existing one
- Status &error) {
+// rather than lldb-launch, llgs-attach. This differs from current lldb-
+// launch, debugserver-attach approach on MacOSX.
+lldb::ProcessSP
+PlatformNetBSD::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
+ Target *target, // Can be NULL, if NULL create a new
+ // target, else use existing one
+ Status &error) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("PlatformNetBSD::%s entered (target %p)", __FUNCTION__,
- static_cast<void *>(target));
+ LLDB_LOG(log, "target {0}", target);
// If we're a remote host, use standard behavior from parent class.
if (!IsHost())
@@ -287,67 +263,48 @@ lldb::ProcessSP PlatformNetBSD::DebugProcess(
launch_info.GetFlags().Set(eLaunchFlagDebug);
// We always launch the process we are going to debug in a separate process
- // group, since then we can handle ^C interrupts ourselves w/o having to worry
- // about the target getting them as well.
+ // group, since then we can handle ^C interrupts ourselves w/o having to
+ // worry about the target getting them as well.
launch_info.SetLaunchInSeparateProcessGroup(true);
// Ensure we have a target.
if (target == nullptr) {
- if (log)
- log->Printf("PlatformNetBSD::%s creating new target", __FUNCTION__);
-
+ LLDB_LOG(log, "creating new target");
TargetSP new_target_sp;
error = debugger.GetTargetList().CreateTarget(debugger, "", "", false,
nullptr, new_target_sp);
if (error.Fail()) {
- if (log)
- log->Printf("PlatformNetBSD::%s failed to create new target: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOG(log, "failed to create new target: {0}", error);
return process_sp;
}
target = new_target_sp.get();
if (!target) {
error.SetErrorString("CreateTarget() returned nullptr");
- if (log)
- log->Printf("PlatformNetBSD::%s failed: %s", __FUNCTION__,
- error.AsCString());
+ LLDB_LOG(log, "error: {0}", error);
return process_sp;
}
- } else {
- if (log)
- log->Printf("PlatformNetBSD::%s using provided target", __FUNCTION__);
}
// Mark target as currently selected target.
debugger.GetTargetList().SetSelectedTarget(target);
// Now create the gdb-remote process.
- if (log)
- log->Printf(
- "PlatformNetBSD::%s having target create process with gdb-remote plugin",
- __FUNCTION__);
+ LLDB_LOG(log, "having target create process with gdb-remote plugin");
process_sp = target->CreateProcess(
launch_info.GetListenerForProcess(debugger), "gdb-remote", nullptr);
if (!process_sp) {
error.SetErrorString("CreateProcess() failed for gdb-remote process");
- if (log)
- log->Printf("PlatformNetBSD::%s failed: %s", __FUNCTION__,
- error.AsCString());
+ LLDB_LOG(log, "error: {0}", error);
return process_sp;
- } else {
- if (log)
- log->Printf("PlatformNetBSD::%s successfully created process",
- __FUNCTION__);
}
+ LLDB_LOG(log, "successfully created process");
// Adjust launch for a hijacker.
ListenerSP listener_sp;
if (!launch_info.GetHijackListener()) {
- if (log)
- log->Printf("PlatformNetBSD::%s setting up hijacker", __FUNCTION__);
-
+ LLDB_LOG(log, "setting up hijacker");
listener_sp =
Listener::MakeListener("lldb.PlatformNetBSD.DebugProcess.hijack");
launch_info.SetHijackListener(listener_sp);
@@ -356,16 +313,13 @@ lldb::ProcessSP PlatformNetBSD::DebugProcess(
// Log file actions.
if (log) {
- log->Printf(
- "PlatformNetBSD::%s launching process with the following file actions:",
- __FUNCTION__);
-
+ LLDB_LOG(log, "launching process with the following file actions:");
StreamString stream;
size_t i = 0;
const FileAction *file_action;
while ((file_action = launch_info.GetFileActionAtIndex(i++)) != nullptr) {
file_action->Dump(stream);
- log->PutCString(stream.GetData());
+ LLDB_LOG(log, "{0}", stream.GetData());
stream.Clear();
}
}
@@ -378,16 +332,7 @@ lldb::ProcessSP PlatformNetBSD::DebugProcess(
const StateType state = process_sp->WaitForProcessToStop(
llvm::None, NULL, false, listener_sp);
- if (state == eStateStopped) {
- if (log)
- log->Printf("PlatformNetBSD::%s pid %" PRIu64 " state %s\n",
- __FUNCTION__, process_sp->GetID(), StateAsCString(state));
- } else {
- if (log)
- log->Printf("PlatformNetBSD::%s pid %" PRIu64
- " state is not stopped - %s\n",
- __FUNCTION__, process_sp->GetID(), StateAsCString(state));
- }
+ LLDB_LOG(log, "pid {0} state {0}", process_sp->GetID(), state);
}
// Hook up process PTY if we have one (which we should for local debugging
@@ -395,20 +340,11 @@ lldb::ProcessSP PlatformNetBSD::DebugProcess(
int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
if (pty_fd != PseudoTerminal::invalid_fd) {
process_sp->SetSTDIOFileDescriptor(pty_fd);
- if (log)
- log->Printf("PlatformNetBSD::%s pid %" PRIu64
- " hooked up STDIO pty to process",
- __FUNCTION__, process_sp->GetID());
- } else {
- if (log)
- log->Printf("PlatformNetBSD::%s pid %" PRIu64
- " not using process STDIO pty",
- __FUNCTION__, process_sp->GetID());
- }
+ LLDB_LOG(log, "hooked up STDIO pty to process");
+ } else
+ LLDB_LOG(log, "not using process STDIO pty");
} else {
- if (log)
- log->Printf("PlatformNetBSD::%s process launch failed: %s", __FUNCTION__,
- error.AsCString());
+ LLDB_LOG(log, "process launch failed: {0}", error);
// FIXME figure out appropriate cleanup here. Do we delete the target? Do
// we delete the process? Does our caller do that?
}
diff --git a/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp b/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
index 050639aba7cc..10ca8fbfbdd7 100644
--- a/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
+++ b/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
@@ -30,8 +30,8 @@
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
-// Define these constants from OpenBSD mman.h for use when targeting
-// remote openbsd systems even when host has different values.
+// Define these constants from OpenBSD mman.h for use when targeting remote
+// openbsd systems even when host has different values.
#define MAP_PRIVATE 0x0002
#define MAP_ANON 0x1000
@@ -58,9 +58,8 @@ PlatformSP PlatformOpenBSD::CreateInstance(bool force, const ArchSpec *arch) {
break;
#if defined(__OpenBSD__)
- // Only accept "unknown" for the OS if the host is BSD and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
+ // Only accept "unknown" for the OS if the host is BSD and it "unknown"
+ // wasn't specified (it was just returned because it was NOT specified)
case llvm::Triple::OSType::UnknownOS:
create = !arch->TripleOSWasSpecified();
break;
@@ -167,13 +166,10 @@ bool PlatformOpenBSD::GetSupportedArchitectureAtIndex(uint32_t idx,
return false;
}
// Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the
- // vendor by
- // calling triple.SetVendorName("unknown") so that it is a "unspecified
- // unknown".
- // This means when someone calls triple.GetVendorName() it will return an
- // empty string
- // which indicates that the vendor can be set when two architectures are
- // merged
+ // vendor by calling triple.SetVendorName("unknown") so that it is a
+ // "unspecified unknown". This means when someone calls
+ // triple.GetVendorName() it will return an empty string which indicates
+ // that the vendor can be set when two architectures are merged
// Now set the triple into "arch" and return true
arch.SetTriple(triple);
diff --git a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
index d45a54ee2499..5e7ffe71918e 100644
--- a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -18,17 +18,22 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/ValueObject.h"
+#include "lldb/Expression/DiagnosticManager.h"
+#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Expression/UserExpression.h"
+#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Host/File.h"
#include "lldb/Host/FileCache.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
+#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/ProcessLaunchInfo.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
@@ -97,17 +102,14 @@ lldb_private::Status PlatformPOSIX::RunShellCommand(
// process to exit
std::string
*command_output, // Pass NULL if you don't want the command output
- uint32_t
- timeout_sec) // Timeout in seconds to wait for shell program to finish
-{
+ const Timeout<std::micro> &timeout) {
if (IsHost())
return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr,
- command_output, timeout_sec);
+ command_output, timeout);
else {
if (m_remote_platform_sp)
- return m_remote_platform_sp->RunShellCommand(command, working_dir,
- status_ptr, signo_ptr,
- command_output, timeout_sec);
+ return m_remote_platform_sp->RunShellCommand(
+ command, working_dir, status_ptr, signo_ptr, command_output, timeout);
else
return Status("unable to run a remote command without a platform");
}
@@ -124,11 +126,12 @@ PlatformPOSIX::ResolveExecutable(const ModuleSpec &module_spec,
ModuleSpec resolved_module_spec(module_spec);
if (IsHost()) {
- // If we have "ls" as the exe_file, resolve the executable location based on
- // the current path variables
+ // If we have "ls" as the exe_file, resolve the executable location based
+ // on the current path variables
if (!resolved_module_spec.GetFileSpec().Exists()) {
resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
- resolved_module_spec.GetFileSpec().SetFile(exe_path, true);
+ resolved_module_spec.GetFileSpec().SetFile(exe_path, true,
+ FileSpec::Style::native);
}
if (!resolved_module_spec.GetFileSpec().Exists())
@@ -210,9 +213,9 @@ PlatformPOSIX::ResolveExecutable(const ModuleSpec &module_spec,
resolved_module_spec.GetArchitecture().GetArchitectureName());
}
} else {
- // No valid architecture was specified, ask the platform for
- // the architectures that we should be using (in the correct order)
- // and see if we can find a match that way
+ // No valid architecture was specified, ask the platform for the
+ // architectures that we should be using (in the correct order) and see
+ // if we can find a match that way
StreamString arch_names;
for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
idx, resolved_module_spec.GetArchitecture());
@@ -367,7 +370,8 @@ static uint32_t chown_file(Platform *platform, const char *path,
command.Printf(":%d", gid);
command.Printf("%s", path);
int status;
- platform->RunShellCommand(command.GetData(), NULL, &status, NULL, NULL, 10);
+ platform->RunShellCommand(command.GetData(), NULL, &status, NULL, NULL,
+ std::chrono::seconds(10));
return status;
}
@@ -391,7 +395,8 @@ PlatformPOSIX::PutFile(const lldb_private::FileSpec &source,
StreamString command;
command.Printf("cp %s %s", src_path.c_str(), dst_path.c_str());
int status;
- RunShellCommand(command.GetData(), NULL, &status, NULL, NULL, 10);
+ RunShellCommand(command.GetData(), NULL, &status, NULL, NULL,
+ std::chrono::seconds(10));
if (status != 0)
return Status("unable to perform copy");
if (uid == UINT32_MAX && gid == UINT32_MAX)
@@ -421,7 +426,8 @@ PlatformPOSIX::PutFile(const lldb_private::FileSpec &source,
if (log)
log->Printf("[PutFile] Running command: %s\n", command.GetData());
int retcode;
- Host::RunShellCommand(command.GetData(), NULL, &retcode, NULL, NULL, 60);
+ Host::RunShellCommand(command.GetData(), NULL, &retcode, NULL, NULL,
+ std::chrono::minutes(1));
if (retcode == 0) {
// Don't chown a local file for a remote system
// if (chown_file(this,dst_path.c_str(),uid,gid) != 0)
@@ -495,7 +501,8 @@ lldb_private::Status PlatformPOSIX::GetFile(
StreamString cp_command;
cp_command.Printf("cp %s %s", src_path.c_str(), dst_path.c_str());
int status;
- RunShellCommand(cp_command.GetData(), NULL, &status, NULL, NULL, 10);
+ RunShellCommand(cp_command.GetData(), NULL, &status, NULL, NULL,
+ std::chrono::seconds(10));
if (status != 0)
return Status("unable to perform copy");
return Status();
@@ -516,11 +523,12 @@ lldb_private::Status PlatformPOSIX::GetFile(
if (log)
log->Printf("[GetFile] Running command: %s\n", command.GetData());
int retcode;
- Host::RunShellCommand(command.GetData(), NULL, &retcode, NULL, NULL, 60);
+ Host::RunShellCommand(command.GetData(), NULL, &retcode, NULL, NULL,
+ std::chrono::minutes(1));
if (retcode == 0)
return Status();
- // If we are here, rsync has failed - let's try the slow way before giving
- // up
+ // If we are here, rsync has failed - let's try the slow way before
+ // giving up
}
// open src and dst
// read/write, read/write, read/write, ...
@@ -645,9 +653,10 @@ bool PlatformPOSIX::SetRemoteWorkingDirectory(const FileSpec &working_dir) {
}
bool PlatformPOSIX::GetRemoteOSVersion() {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetOSVersion(
- m_major_os_version, m_minor_os_version, m_update_os_version);
+ if (m_remote_platform_sp) {
+ m_os_version = m_remote_platform_sp->GetOSVersion();
+ return !m_os_version.empty();
+ }
return false;
}
@@ -658,13 +667,13 @@ bool PlatformPOSIX::GetRemoteOSBuildString(std::string &s) {
return false;
}
-size_t PlatformPOSIX::GetEnvironment(StringList &env) {
+Environment PlatformPOSIX::GetEnvironment() {
if (IsRemote()) {
if (m_remote_platform_sp)
- return m_remote_platform_sp->GetEnvironment(env);
- return 0;
+ return m_remote_platform_sp->GetEnvironment();
+ return Environment();
}
- return Host::GetEnvironment(env);
+ return Host::GetEnvironment();
}
bool PlatformPOSIX::GetRemoteOSKernelDescription(std::string &s) {
@@ -861,12 +870,12 @@ PlatformPOSIX::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
if (IsHost()) {
// We are going to hand this process off to debugserver which will be in
- // charge of setting the exit status.
- // We still need to reap it from lldb but if we let the monitor thread also
- // set the exit status, we set up a
- // race between debugserver & us for who will find out about the debugged
- // process's death.
- launch_info.GetFlags().Set(eLaunchFlagDontSetExitStatus);
+ // charge of setting the exit status. However, we still need to reap it
+ // from lldb. So, make sure we use a exit callback which does not set exit
+ // status.
+ const bool monitor_signals = false;
+ launch_info.SetMonitorProcessCallback(
+ &ProcessLaunchInfo::NoOpMonitorCallback, monitor_signals);
process_sp = Platform::DebugProcess(launch_info, debugger, target, error);
} else {
if (m_remote_platform_sp)
@@ -923,64 +932,380 @@ Status PlatformPOSIX::EvaluateLibdlExpression(
return Status();
}
+std::unique_ptr<UtilityFunction>
+PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx,
+ Status &error) {
+ // Remember to prepend this with the prefix from
+ // GetLibdlFunctionDeclarations. The returned values are all in
+ // __lldb_dlopen_result for consistency. The wrapper returns a void * but
+ // doesn't use it because UtilityFunctions don't work with void returns at
+ // present.
+ static const char *dlopen_wrapper_code = R"(
+ struct __lldb_dlopen_result {
+ void *image_ptr;
+ const char *error_str;
+ };
+
+ extern void *memcpy(void *, const void *, size_t size);
+ extern size_t strlen(const char *);
+
+
+ void * __lldb_dlopen_wrapper (const char *name,
+ const char *path_strings,
+ char *buffer,
+ __lldb_dlopen_result *result_ptr)
+ {
+ // This is the case where the name is the full path:
+ if (!path_strings) {
+ result_ptr->image_ptr = dlopen(name, 2);
+ if (result_ptr->image_ptr)
+ result_ptr->error_str = nullptr;
+ return nullptr;
+ }
+
+ // This is the case where we have a list of paths:
+ size_t name_len = strlen(name);
+ while (path_strings && path_strings[0] != '\0') {
+ size_t path_len = strlen(path_strings);
+ memcpy((void *) buffer, (void *) path_strings, path_len);
+ buffer[path_len] = '/';
+ char *target_ptr = buffer+path_len+1;
+ memcpy((void *) target_ptr, (void *) name, name_len + 1);
+ result_ptr->image_ptr = dlopen(buffer, 2);
+ if (result_ptr->image_ptr) {
+ result_ptr->error_str = nullptr;
+ break;
+ }
+ result_ptr->error_str = dlerror();
+ path_strings = path_strings + path_len + 1;
+ }
+ return nullptr;
+ }
+ )";
+
+ static const char *dlopen_wrapper_name = "__lldb_dlopen_wrapper";
+ Process *process = exe_ctx.GetProcessSP().get();
+ // Insert the dlopen shim defines into our generic expression:
+ std::string expr(GetLibdlFunctionDeclarations(process));
+ expr.append(dlopen_wrapper_code);
+ Status utility_error;
+ DiagnosticManager diagnostics;
+
+ std::unique_ptr<UtilityFunction> dlopen_utility_func_up(process
+ ->GetTarget().GetUtilityFunctionForLanguage(expr.c_str(),
+ eLanguageTypeObjC,
+ dlopen_wrapper_name,
+ utility_error));
+ if (utility_error.Fail()) {
+ error.SetErrorStringWithFormat("dlopen error: could not make utility"
+ "function: %s", utility_error.AsCString());
+ return nullptr;
+ }
+ if (!dlopen_utility_func_up->Install(diagnostics, exe_ctx)) {
+ error.SetErrorStringWithFormat("dlopen error: could not install utility"
+ "function: %s",
+ diagnostics.GetString().c_str());
+ return nullptr;
+ }
+
+ Value value;
+ ValueList arguments;
+ FunctionCaller *do_dlopen_function = nullptr;
+
+ // Fetch the clang types we will need:
+ ClangASTContext *ast = process->GetTarget().GetScratchClangASTContext();
+
+ CompilerType clang_void_pointer_type
+ = ast->GetBasicType(eBasicTypeVoid).GetPointerType();
+ CompilerType clang_char_pointer_type
+ = ast->GetBasicType(eBasicTypeChar).GetPointerType();
+
+ // We are passing four arguments, the basename, the list of places to look,
+ // a buffer big enough for all the path + name combos, and
+ // a pointer to the storage we've made for the result:
+ value.SetValueType(Value::eValueTypeScalar);
+ value.SetCompilerType(clang_void_pointer_type);
+ arguments.PushValue(value);
+ value.SetCompilerType(clang_char_pointer_type);
+ arguments.PushValue(value);
+ arguments.PushValue(value);
+ arguments.PushValue(value);
+
+ do_dlopen_function = dlopen_utility_func_up->MakeFunctionCaller(
+ clang_void_pointer_type, arguments, exe_ctx.GetThreadSP(), utility_error);
+ if (utility_error.Fail()) {
+ error.SetErrorStringWithFormat("dlopen error: could not make function"
+ "caller: %s", utility_error.AsCString());
+ return nullptr;
+ }
+
+ do_dlopen_function = dlopen_utility_func_up->GetFunctionCaller();
+ if (!do_dlopen_function) {
+ error.SetErrorString("dlopen error: could not get function caller.");
+ return nullptr;
+ }
+
+ // We made a good utility function, so cache it in the process:
+ return dlopen_utility_func_up;
+}
+
uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process,
const lldb_private::FileSpec &remote_file,
- lldb_private::Status &error) {
- char path[PATH_MAX];
- remote_file.GetPath(path, sizeof(path));
+ const std::vector<std::string> *paths,
+ lldb_private::Status &error,
+ lldb_private::FileSpec *loaded_image) {
+ if (loaded_image)
+ loaded_image->Clear();
- StreamString expr;
- expr.Printf(R"(
- struct __lldb_dlopen_result { void *image_ptr; const char *error_str; } the_result;
- the_result.image_ptr = dlopen ("%s", 2);
- if (the_result.image_ptr == (void *) 0x0)
- {
- the_result.error_str = dlerror();
- }
- else
- {
- the_result.error_str = (const char *) 0x0;
- }
- the_result;
- )",
- path);
- llvm::StringRef prefix = GetLibdlFunctionDeclarations(process);
- lldb::ValueObjectSP result_valobj_sp;
- error = EvaluateLibdlExpression(process, expr.GetData(), prefix,
- result_valobj_sp);
- if (error.Fail())
+ std::string path;
+ path = remote_file.GetPath();
+
+ ThreadSP thread_sp = process->GetThreadList().GetExpressionExecutionThread();
+ if (!thread_sp) {
+ error.SetErrorString("dlopen error: no thread available to call dlopen.");
return LLDB_INVALID_IMAGE_TOKEN;
+ }
+
+ DiagnosticManager diagnostics;
+
+ ExecutionContext exe_ctx;
+ thread_sp->CalculateExecutionContext(exe_ctx);
- error = result_valobj_sp->GetError();
- if (error.Fail())
- return LLDB_INVALID_IMAGE_TOKEN;
+ Status utility_error;
+ UtilityFunction *dlopen_utility_func;
+ ValueList arguments;
+ FunctionCaller *do_dlopen_function = nullptr;
- Scalar scalar;
- ValueObjectSP image_ptr_sp = result_valobj_sp->GetChildAtIndex(0, true);
- if (!image_ptr_sp || !image_ptr_sp->ResolveValue(scalar)) {
- error.SetErrorStringWithFormat("unable to load '%s'", path);
+ // The UtilityFunction is held in the Process. Platforms don't track the
+ // lifespan of the Targets that use them, we can't put this in the Platform.
+ dlopen_utility_func = process->GetLoadImageUtilityFunction(
+ this, [&]() -> std::unique_ptr<UtilityFunction> {
+ return MakeLoadImageUtilityFunction(exe_ctx, error);
+ });
+ // If we couldn't make it, the error will be in error, so we can exit here.
+ if (!dlopen_utility_func)
+ return LLDB_INVALID_IMAGE_TOKEN;
+
+ do_dlopen_function = dlopen_utility_func->GetFunctionCaller();
+ if (!do_dlopen_function) {
+ error.SetErrorString("dlopen error: could not get function caller.");
+ return LLDB_INVALID_IMAGE_TOKEN;
+ }
+ arguments = do_dlopen_function->GetArgumentValues();
+
+ // Now insert the path we are searching for and the result structure into the
+ // target.
+ uint32_t permissions = ePermissionsReadable|ePermissionsWritable;
+ size_t path_len = path.size() + 1;
+ lldb::addr_t path_addr = process->AllocateMemory(path_len,
+ permissions,
+ utility_error);
+ if (path_addr == LLDB_INVALID_ADDRESS) {
+ error.SetErrorStringWithFormat("dlopen error: could not allocate memory"
+ "for path: %s", utility_error.AsCString());
+ return LLDB_INVALID_IMAGE_TOKEN;
+ }
+
+ // Make sure we deallocate the input string memory:
+ CleanUp path_cleanup([process, path_addr] {
+ process->DeallocateMemory(path_addr);
+ });
+
+ process->WriteMemory(path_addr, path.c_str(), path_len, utility_error);
+ if (utility_error.Fail()) {
+ error.SetErrorStringWithFormat("dlopen error: could not write path string:"
+ " %s", utility_error.AsCString());
+ return LLDB_INVALID_IMAGE_TOKEN;
+ }
+
+ // Make space for our return structure. It is two pointers big: the token
+ // and the error string.
+ const uint32_t addr_size = process->GetAddressByteSize();
+ lldb::addr_t return_addr = process->CallocateMemory(2*addr_size,
+ permissions,
+ utility_error);
+ if (utility_error.Fail()) {
+ error.SetErrorStringWithFormat("dlopen error: could not allocate memory"
+ "for path: %s", utility_error.AsCString());
return LLDB_INVALID_IMAGE_TOKEN;
}
+
+ // Make sure we deallocate the result structure memory
+ CleanUp return_cleanup([process, return_addr] {
+ process->DeallocateMemory(return_addr);
+ });
+
+ // This will be the address of the storage for paths, if we are using them,
+ // or nullptr to signal we aren't.
+ lldb::addr_t path_array_addr = 0x0;
+ llvm::Optional<CleanUp> path_array_cleanup;
- addr_t image_ptr = scalar.ULongLong(LLDB_INVALID_ADDRESS);
- if (image_ptr != 0 && image_ptr != LLDB_INVALID_ADDRESS)
- return process->AddImageToken(image_ptr);
+ // This is the address to a buffer large enough to hold the largest path
+ // conjoined with the library name we're passing in. This is a convenience
+ // to avoid having to call malloc in the dlopen function.
+ lldb::addr_t buffer_addr = 0x0;
+ llvm::Optional<CleanUp> buffer_cleanup;
+
+ // Set the values into our args and write them to the target:
+ if (paths != nullptr) {
+ // First insert the paths into the target. This is expected to be a
+ // continuous buffer with the strings laid out null terminated and
+ // end to end with an empty string terminating the buffer.
+ // We also compute the buffer's required size as we go.
+ size_t buffer_size = 0;
+ std::string path_array;
+ for (auto path : *paths) {
+ // Don't insert empty paths, they will make us abort the path
+ // search prematurely.
+ if (path.empty())
+ continue;
+ size_t path_size = path.size();
+ path_array.append(path);
+ path_array.push_back('\0');
+ if (path_size > buffer_size)
+ buffer_size = path_size;
+ }
+ path_array.push_back('\0');
+
+ path_array_addr = process->AllocateMemory(path_array.size(),
+ permissions,
+ utility_error);
+ if (path_array_addr == LLDB_INVALID_ADDRESS) {
+ error.SetErrorStringWithFormat("dlopen error: could not allocate memory"
+ "for path array: %s",
+ utility_error.AsCString());
+ return LLDB_INVALID_IMAGE_TOKEN;
+ }
+
+ // Make sure we deallocate the paths array.
+ path_array_cleanup.emplace([process, path_array_addr] {
+ process->DeallocateMemory(path_array_addr);
+ });
- if (image_ptr == 0) {
- ValueObjectSP error_str_sp = result_valobj_sp->GetChildAtIndex(1, true);
- if (error_str_sp) {
- DataBufferSP buffer_sp(new DataBufferHeap(10240, 0));
- size_t num_chars =
- error_str_sp->ReadPointedString(buffer_sp, error, 10240).first;
- if (error.Success() && num_chars > 0)
- error.SetErrorStringWithFormat("dlopen error: %s",
- buffer_sp->GetBytes());
- else
- error.SetErrorStringWithFormat("dlopen failed for unknown reasons.");
+ process->WriteMemory(path_array_addr, path_array.data(),
+ path_array.size(), utility_error);
+
+ if (utility_error.Fail()) {
+ error.SetErrorStringWithFormat("dlopen error: could not write path array:"
+ " %s", utility_error.AsCString());
return LLDB_INVALID_IMAGE_TOKEN;
}
+ // Now make spaces in the target for the buffer. We need to add one for
+ // the '/' that the utility function will insert and one for the '\0':
+ buffer_size += path.size() + 2;
+
+ buffer_addr = process->AllocateMemory(buffer_size,
+ permissions,
+ utility_error);
+ if (buffer_addr == LLDB_INVALID_ADDRESS) {
+ error.SetErrorStringWithFormat("dlopen error: could not allocate memory"
+ "for buffer: %s",
+ utility_error.AsCString());
+ return LLDB_INVALID_IMAGE_TOKEN;
+ }
+
+ // Make sure we deallocate the buffer memory:
+ buffer_cleanup.emplace([process, buffer_addr] {
+ process->DeallocateMemory(buffer_addr);
+ });
}
- error.SetErrorStringWithFormat("unable to load '%s'", path);
+
+ arguments.GetValueAtIndex(0)->GetScalar() = path_addr;
+ arguments.GetValueAtIndex(1)->GetScalar() = path_array_addr;
+ arguments.GetValueAtIndex(2)->GetScalar() = buffer_addr;
+ arguments.GetValueAtIndex(3)->GetScalar() = return_addr;
+
+ lldb::addr_t func_args_addr = LLDB_INVALID_ADDRESS;
+
+ diagnostics.Clear();
+ if (!do_dlopen_function->WriteFunctionArguments(exe_ctx,
+ func_args_addr,
+ arguments,
+ diagnostics)) {
+ error.SetErrorStringWithFormat("dlopen error: could not write function "
+ "arguments: %s",
+ diagnostics.GetString().c_str());
+ return LLDB_INVALID_IMAGE_TOKEN;
+ }
+
+ // Make sure we clean up the args structure. We can't reuse it because the
+ // Platform lives longer than the process and the Platforms don't get a
+ // signal to clean up cached data when a process goes away.
+ CleanUp args_cleanup([do_dlopen_function, &exe_ctx, func_args_addr] {
+ do_dlopen_function->DeallocateFunctionResults(exe_ctx, func_args_addr);
+ });
+
+ // Now run the caller:
+ EvaluateExpressionOptions options;
+ options.SetExecutionPolicy(eExecutionPolicyAlways);
+ options.SetLanguage(eLanguageTypeC_plus_plus);
+ options.SetIgnoreBreakpoints(true);
+ options.SetUnwindOnError(true);
+ options.SetTrapExceptions(false); // dlopen can't throw exceptions, so
+ // don't do the work to trap them.
+ options.SetTimeout(std::chrono::seconds(2));
+
+ Value return_value;
+ // Fetch the clang types we will need:
+ ClangASTContext *ast = process->GetTarget().GetScratchClangASTContext();
+
+ CompilerType clang_void_pointer_type
+ = ast->GetBasicType(eBasicTypeVoid).GetPointerType();
+
+ return_value.SetCompilerType(clang_void_pointer_type);
+
+ ExpressionResults results = do_dlopen_function->ExecuteFunction(
+ exe_ctx, &func_args_addr, options, diagnostics, return_value);
+ if (results != eExpressionCompleted) {
+ error.SetErrorStringWithFormat("dlopen error: failed executing "
+ "dlopen wrapper function: %s",
+ diagnostics.GetString().c_str());
+ return LLDB_INVALID_IMAGE_TOKEN;
+ }
+
+ // Read the dlopen token from the return area:
+ lldb::addr_t token = process->ReadPointerFromMemory(return_addr,
+ utility_error);
+ if (utility_error.Fail()) {
+ error.SetErrorStringWithFormat("dlopen error: could not read the return "
+ "struct: %s", utility_error.AsCString());
+ return LLDB_INVALID_IMAGE_TOKEN;
+ }
+
+ // The dlopen succeeded!
+ if (token != 0x0) {
+ if (loaded_image && buffer_addr != 0x0)
+ {
+ // Capture the image which was loaded. We leave it in the buffer on
+ // exit from the dlopen function, so we can just read it from there:
+ std::string name_string;
+ process->ReadCStringFromMemory(buffer_addr, name_string, utility_error);
+ if (utility_error.Success())
+ loaded_image->SetFile(name_string, false,
+ llvm::sys::path::Style::posix);
+ }
+ return process->AddImageToken(token);
+ }
+
+ // We got an error, lets read in the error string:
+ std::string dlopen_error_str;
+ lldb::addr_t error_addr
+ = process->ReadPointerFromMemory(return_addr + addr_size, utility_error);
+ if (utility_error.Fail()) {
+ error.SetErrorStringWithFormat("dlopen error: could not read error string: "
+ "%s", utility_error.AsCString());
+ return LLDB_INVALID_IMAGE_TOKEN;
+ }
+
+ size_t num_chars = process->ReadCStringFromMemory(error_addr + addr_size,
+ dlopen_error_str,
+ utility_error);
+ if (utility_error.Success() && num_chars > 0)
+ error.SetErrorStringWithFormat("dlopen error: %s",
+ dlopen_error_str.c_str());
+ else
+ error.SetErrorStringWithFormat("dlopen failed for unknown reasons.");
+
return LLDB_INVALID_IMAGE_TOKEN;
}
diff --git a/source/Plugins/Platform/POSIX/PlatformPOSIX.h b/source/Plugins/Platform/POSIX/PlatformPOSIX.h
index 93bebeb332ca..cc6f7299c194 100644
--- a/source/Plugins/Platform/POSIX/PlatformPOSIX.h
+++ b/source/Plugins/Platform/POSIX/PlatformPOSIX.h
@@ -85,7 +85,7 @@ public:
const lldb::UnixSignalsSP &GetRemoteUnixSignals() override;
- size_t GetEnvironment(lldb_private::StringList &environment) override;
+ lldb_private::Environment GetEnvironment() override;
bool IsConnected() const override;
@@ -99,8 +99,7 @@ public:
// the process to exit
std::string
*command_output, // Pass nullptr if you don't want the command output
- uint32_t timeout_sec)
- override; // Timeout in seconds to wait for shell program to finish
+ const lldb_private::Timeout<std::micro> &timeout) override;
lldb_private::Status ResolveExecutable(
const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
@@ -166,7 +165,9 @@ public:
uint32_t DoLoadImage(lldb_private::Process *process,
const lldb_private::FileSpec &remote_file,
- lldb_private::Status &error) override;
+ const std::vector<std::string> *paths,
+ lldb_private::Status &error,
+ lldb_private::FileSpec *loaded_image) override;
lldb_private::Status UnloadImage(lldb_private::Process *process,
uint32_t image_token) override;
@@ -201,6 +202,10 @@ protected:
llvm::StringRef expr_prefix,
lldb::ValueObjectSP &result_valobj_sp);
+ std::unique_ptr<lldb_private::UtilityFunction>
+ MakeLoadImageUtilityFunction(lldb_private::ExecutionContext &exe_ctx,
+ lldb_private::Status &error);
+
virtual
llvm::StringRef GetLibdlFunctionDeclarations(lldb_private::Process *process);
diff --git a/source/Plugins/Platform/Windows/PlatformWindows.cpp b/source/Plugins/Platform/Windows/PlatformWindows.cpp
index 3535df0c65cc..ed2bcf0cbee4 100644
--- a/source/Plugins/Platform/Windows/PlatformWindows.cpp
+++ b/source/Plugins/Platform/Windows/PlatformWindows.cpp
@@ -194,7 +194,8 @@ Status PlatformWindows::ResolveExecutable(
// variables
if (!resolved_module_spec.GetFileSpec().Exists()) {
resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
- resolved_module_spec.GetFileSpec().SetFile(exe_path, true);
+ resolved_module_spec.GetFileSpec().SetFile(exe_path, true,
+ FileSpec::Style::native);
}
if (!resolved_module_spec.GetFileSpec().Exists())
@@ -237,9 +238,9 @@ Status PlatformWindows::ResolveExecutable(
resolved_module_spec.GetArchitecture().GetArchitectureName());
}
} else {
- // No valid architecture was specified, ask the platform for
- // the architectures that we should be using (in the correct order)
- // and see if we can find a match that way
+ // No valid architecture was specified, ask the platform for the
+ // architectures that we should be using (in the correct order) and see
+ // if we can find a match that way
StreamString arch_names;
for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
idx, resolved_module_spec.GetArchitecture());
@@ -279,9 +280,10 @@ Status PlatformWindows::ResolveExecutable(
}
bool PlatformWindows::GetRemoteOSVersion() {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetOSVersion(
- m_major_os_version, m_minor_os_version, m_update_os_version);
+ if (m_remote_platform_sp) {
+ m_os_version = m_remote_platform_sp->GetOSVersion();
+ return !m_os_version.empty();
+ }
return false;
}
@@ -413,29 +415,23 @@ ProcessSP PlatformWindows::DebugProcess(ProcessLaunchInfo &launch_info,
Debugger &debugger, Target *target,
Status &error) {
// Windows has special considerations that must be followed when launching or
- // attaching to a process. The
- // key requirement is that when launching or attaching to a process, you must
- // do it from the same the thread
- // that will go into a permanent loop which will then receive debug events
- // from the process. In particular,
- // this means we can't use any of LLDB's generic mechanisms to do it for us,
- // because it doesn't have the
- // special knowledge required for setting up the background thread or passing
- // the right flags.
+ // attaching to a process. The key requirement is that when launching or
+ // attaching to a process, you must do it from the same the thread that will
+ // go into a permanent loop which will then receive debug events from the
+ // process. In particular, this means we can't use any of LLDB's generic
+ // mechanisms to do it for us, because it doesn't have the special knowledge
+ // required for setting up the background thread or passing the right flags.
//
// Another problem is that that LLDB's standard model for debugging a process
- // is to first launch it, have
- // it stop at the entry point, and then attach to it. In Windows this doesn't
- // quite work, you have to
- // specify as an argument to CreateProcess() that you're going to debug the
- // process. So we override DebugProcess
- // here to handle this. Launch operations go directly to the process plugin,
- // and attach operations almost go
- // directly to the process plugin (but we hijack the events first). In
- // essence, we encapsulate all the logic
- // of Launching and Attaching in the process plugin, and
- // PlatformWindows::DebugProcess is just a pass-through
- // to get to the process plugin.
+ // is to first launch it, have it stop at the entry point, and then attach to
+ // it. In Windows this doesn't quite work, you have to specify as an
+ // argument to CreateProcess() that you're going to debug the process. So we
+ // override DebugProcess here to handle this. Launch operations go directly
+ // to the process plugin, and attach operations almost go directly to the
+ // process plugin (but we hijack the events first). In essence, we
+ // encapsulate all the logic of Launching and Attaching in the process
+ // plugin, and PlatformWindows::DebugProcess is just a pass-through to get to
+ // the process plugin.
if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) {
// This is a process attach. Don't need to launch anything.
@@ -538,8 +534,8 @@ Status PlatformWindows::GetSharedModule(
module_sp.reset();
if (IsRemote()) {
- // If we have a remote platform always, let it try and locate
- // the shared module first.
+ // If we have a remote platform always, let it try and locate the shared
+ // module first.
if (m_remote_platform_sp) {
error = m_remote_platform_sp->GetSharedModule(
module_spec, process, module_sp, module_search_paths_ptr,
@@ -572,29 +568,21 @@ void PlatformWindows::GetStatus(Stream &strm) {
Platform::GetStatus(strm);
#ifdef _WIN32
- uint32_t major;
- uint32_t minor;
- uint32_t update;
- if (!HostInfo::GetOSVersion(major, minor, update)) {
- strm << "Windows";
- return;
- }
-
- strm << "Host: Windows " << major << '.' << minor << " Build: " << update
- << '\n';
+ llvm::VersionTuple version = HostInfo::GetOSVersion();
+ strm << "Host: Windows " << version.getAsString() << '\n';
#endif
}
bool PlatformWindows::CanDebugProcess() { return true; }
-size_t PlatformWindows::GetEnvironment(StringList &env) {
+Environment PlatformWindows::GetEnvironment() {
if (IsRemote()) {
if (m_remote_platform_sp)
- return m_remote_platform_sp->GetEnvironment(env);
- return 0;
+ return m_remote_platform_sp->GetEnvironment();
+ return Environment();
}
- return Host::GetEnvironment(env);
+ return Host::GetEnvironment();
}
ConstString PlatformWindows::GetFullNameForDylib(ConstString basename) {
diff --git a/source/Plugins/Platform/Windows/PlatformWindows.h b/source/Plugins/Platform/Windows/PlatformWindows.h
index 9af42116680e..3a15271c5762 100644
--- a/source/Plugins/Platform/Windows/PlatformWindows.h
+++ b/source/Plugins/Platform/Windows/PlatformWindows.h
@@ -118,7 +118,7 @@ public:
bool CanDebugProcess() override;
- size_t GetEnvironment(StringList &env) override;
+ Environment GetEnvironment() override;
// FIXME not sure what the _sigtramp equivalent would be on this platform
void CalculateTrapHandlerSymbolNames() override {}
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index 759ec7fd1d29..348bb825a5c5 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -118,9 +118,9 @@ Status PlatformRemoteGDBServer::ResolveExecutable(
return error;
exe_module_sp.reset();
}
- // No valid architecture was specified or the exact arch wasn't
- // found so ask the platform for the architectures that we should be
- // using (in the correct order) and see if we can find a match that way
+ // No valid architecture was specified or the exact arch wasn't found so
+ // ask the platform for the architectures that we should be using (in the
+ // correct order) and see if we can find a match that way
StreamString arch_names;
for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
idx, resolved_module_spec.GetArchitecture());
@@ -236,14 +236,8 @@ size_t PlatformRemoteGDBServer::GetSoftwareBreakpointTrapOpcode(
}
bool PlatformRemoteGDBServer::GetRemoteOSVersion() {
- uint32_t major, minor, update;
- if (m_gdb_client.GetOSVersion(major, minor, update)) {
- m_major_os_version = major;
- m_minor_os_version = minor;
- m_update_os_version = update;
- return true;
- }
- return false;
+ m_os_version = m_gdb_client.GetOSVersion();
+ return !m_os_version.empty();
}
bool PlatformRemoteGDBServer::GetRemoteOSBuildString(std::string &s) {
@@ -277,8 +271,7 @@ bool PlatformRemoteGDBServer::SetRemoteWorkingDirectory(
const FileSpec &working_dir) {
if (IsConnected()) {
// Clear the working directory it case it doesn't get set correctly. This
- // will
- // for use to re-read it
+ // will for use to re-read it
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
if (log)
log->Printf("PlatformRemoteGDBServer::SetRemoteWorkingDirectory('%s')",
@@ -423,16 +416,7 @@ Status PlatformRemoteGDBServer::LaunchProcess(ProcessLaunchInfo &launch_info) {
}
// Send the environment and the program + arguments after we connect
- const char **envp =
- launch_info.GetEnvironmentEntries().GetConstArgumentVector();
-
- if (envp) {
- const char *env_entry;
- for (int i = 0; (env_entry = envp[i]); ++i) {
- if (m_gdb_client.SendEnvironmentPacket(env_entry) != 0)
- break;
- }
- }
+ m_gdb_client.SendEnvironment(launch_info.GetEnvironment());
ArchSpec arch_spec = launch_info.GetArchitecture();
const char *arch_triple = arch_spec.GetTriple().str().c_str();
@@ -549,9 +533,8 @@ bool PlatformRemoteGDBServer::LaunchGDBServer(lldb::pid_t &pid,
bool launch_result = false;
if (remote_triple.getVendor() == llvm::Triple::Apple &&
remote_triple.getOS() == llvm::Triple::IOS) {
- // When remote debugging to iOS, we use a USB mux that always talks
- // to localhost, so we will need the remote debugserver to accept
- // connections
+ // When remote debugging to iOS, we use a USB mux that always talks to
+ // localhost, so we will need the remote debugserver to accept connections
// only from localhost, no matter what our current hostname is
launch_result =
m_gdb_client.LaunchGDBServer("127.0.0.1", pid, port, socket_name);
@@ -731,11 +714,9 @@ Status PlatformRemoteGDBServer::RunShellCommand(
// process to exit
std::string
*command_output, // Pass NULL if you don't want the command output
- uint32_t
- timeout_sec) // Timeout in seconds to wait for shell program to finish
-{
+ const Timeout<std::micro> &timeout) {
return m_gdb_client.RunShellCommand(command, working_dir, status_ptr,
- signo_ptr, command_output, timeout_sec);
+ signo_ptr, command_output, timeout);
}
void PlatformRemoteGDBServer::CalculateTrapHandlerSymbolNames() {
@@ -749,8 +730,8 @@ const UnixSignalsSP &PlatformRemoteGDBServer::GetRemoteUnixSignals() {
if (m_remote_signals_sp)
return m_remote_signals_sp;
- // If packet not implemented or JSON failed to parse,
- // we'll guess the signal set based on the remote architecture.
+ // If packet not implemented or JSON failed to parse, we'll guess the signal
+ // set based on the remote architecture.
m_remote_signals_sp = UnixSignals::Create(GetRemoteSystemArchitecture());
StringExtractorGDBRemote response;
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
index 210544f752e6..a31933b5d9b0 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
@@ -17,7 +17,7 @@
// Other libraries and framework includes
// Project includes
-#include "../../Process/gdb-remote/GDBRemoteCommunicationClient.h"
+#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h"
#include "Plugins/Process/Utility/GDBRemoteSignals.h"
#include "lldb/Target/Platform.h"
@@ -155,8 +155,7 @@ public:
// process to exit
std::string
*command_output, // Pass NULL if you don't want the command output
- uint32_t timeout_sec)
- override; // Timeout in seconds to wait for shell program to finish
+ const lldb_private::Timeout<std::micro> &timeout) override;
void CalculateTrapHandlerSymbolNames() override;
diff --git a/source/Plugins/Process/CMakeLists.txt b/source/Plugins/Process/CMakeLists.txt
index 62abd75a43b6..fdeb211fe7a2 100644
--- a/source/Plugins/Process/CMakeLists.txt
+++ b/source/Plugins/Process/CMakeLists.txt
@@ -11,9 +11,9 @@ elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")
add_subdirectory(Windows/Common)
elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
add_subdirectory(MacOSX-Kernel)
- add_subdirectory(mach-core)
endif()
add_subdirectory(gdb-remote)
add_subdirectory(Utility)
add_subdirectory(elf-core)
+add_subdirectory(mach-core)
add_subdirectory(minidump)
diff --git a/source/Plugins/Process/Darwin/CFString.cpp b/source/Plugins/Process/Darwin/CFString.cpp
index 84ad56774d7c..b87afe999181 100644
--- a/source/Plugins/Process/Darwin/CFString.cpp
+++ b/source/Plugins/Process/Darwin/CFString.cpp
@@ -91,9 +91,8 @@ const char *CFString::UTF8(std::string &str) {
return CFString::UTF8(get(), str);
}
-// Static function that puts a copy of the UTF8 contents of CF_STR into STR
-// and returns the C string pointer that is contained in STR when successful,
-// else
+// Static function that puts a copy of the UTF8 contents of CF_STR into STR and
+// returns the C string pointer that is contained in STR when successful, else
// NULL is returned. This allows the std::string parameter to own the extracted
// string,
// and also allows that string to be returned as a C string pointer that can be
@@ -120,9 +119,9 @@ const char *CFString::UTF8(CFStringRef cf_str, std::string &str) {
// Static function that puts a copy of the file system representation of CF_STR
// into STR and returns the C string pointer that is contained in STR when
-// successful, else NULL is returned. This allows the std::string parameter
-// to own the extracted string, and also allows that string to be returned as
-// a C string pointer that can be used.
+// successful, else NULL is returned. This allows the std::string parameter to
+// own the extracted string, and also allows that string to be returned as a C
+// string pointer that can be used.
const char *CFString::FileSystemRepresentation(CFStringRef cf_str,
std::string &str) {
diff --git a/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp b/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp
index 6b3d5f6c117f..95659725ce2e 100644
--- a/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp
+++ b/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp
@@ -142,8 +142,8 @@ static Status ForkChildForPTraceDebugging(const char *path, char const *argv[],
}
// Use a fork that ties the child process's stdin/out/err to a pseudo
- // terminal so we can read it in our MachProcess::STDIOThread
- // as unbuffered io.
+ // terminal so we can read it in our MachProcess::STDIOThread as unbuffered
+ // io.
PseudoTerminal pty;
char fork_error[256];
memset(fork_error, 0, sizeof(fork_error));
@@ -167,12 +167,12 @@ static Status ForkChildForPTraceDebugging(const char *path, char const *argv[],
// Get BSD signals as mach exceptions.
::ptrace(PT_SIGEXC, 0, 0, 0);
- // If our parent is setgid, lets make sure we don't inherit those
- // extra powers due to nepotism.
+ // If our parent is setgid, lets make sure we don't inherit those extra
+ // powers due to nepotism.
if (::setgid(getgid()) == 0) {
- // Let the child have its own process group. We need to execute
- // this call in both the child and parent to avoid a race
- // condition between the two processes.
+ // Let the child have its own process group. We need to execute this call
+ // in both the child and parent to avoid a race condition between the two
+ // processes.
// Set the child process group to match its pid.
::setpgid(0, 0);
@@ -183,23 +183,22 @@ static Status ForkChildForPTraceDebugging(const char *path, char const *argv[],
// Turn this process into the given executable.
::execv(path, (char *const *)argv);
}
- // Exit with error code. Child process should have taken
- // over in above exec call and if the exec fails it will
- // exit the child process below.
+ // Exit with error code. Child process should have taken over in above exec
+ // call and if the exec fails it will exit the child process below.
::exit(127);
} else {
//--------------------------------------------------------------
// Parent process
//--------------------------------------------------------------
- // Let the child have its own process group. We need to execute
- // this call in both the child and parent to avoid a race condition
- // between the two processes.
+ // Let the child have its own process group. We need to execute this call
+ // in both the child and parent to avoid a race condition between the two
+ // processes.
// Set the child process group to match its pid
::setpgid(*pid, *pid);
if (pty_fd) {
- // Release our master pty file descriptor so the pty class doesn't
- // close it and so we can continue to use it in our STDIO thread
+ // Release our master pty file descriptor so the pty class doesn't close
+ // it and so we can continue to use it in our STDIO thread
*pty_fd = pty.ReleaseMasterFileDescriptor();
}
}
@@ -302,8 +301,7 @@ static Status PosixSpawnChildForPTraceDebugging(const char *path,
return error;
}
- // Ensure we clean up the spawnattr structure however we exit this
- // function.
+ // Ensure we clean up the spawnattr structure however we exit this function.
std::unique_ptr<posix_spawnattr_t, int (*)(posix_spawnattr_t *)> spawnattr_up(
&attr, ::posix_spawnattr_destroy);
@@ -332,9 +330,9 @@ static Status PosixSpawnChildForPTraceDebugging(const char *path,
#if !defined(__arm__)
- // We don't need to do this for ARM, and we really shouldn't now that we
- // have multiple CPU subtypes and no posix_spawnattr call that allows us
- // to set which CPU subtype to launch...
+ // We don't need to do this for ARM, and we really shouldn't now that we have
+ // multiple CPU subtypes and no posix_spawnattr call that allows us to set
+ // which CPU subtype to launch...
cpu_type_t desired_cpu_type = launch_info.GetArchitecture().GetMachOCPUType();
if (desired_cpu_type != LLDB_INVALID_CPUTYPE) {
size_t ocount = 0;
@@ -374,10 +372,10 @@ static Status PosixSpawnChildForPTraceDebugging(const char *path,
int (*)(posix_spawn_file_actions_t *)>
file_actions_up(&file_actions, ::posix_spawn_file_actions_destroy);
- // We assume the caller has setup the file actions appropriately. We
- // are not in the business of figuring out what we really need here.
- // lldb-server will have already called FinalizeFileActions() as well
- // to button these up properly.
+ // We assume the caller has setup the file actions appropriately. We are not
+ // in the business of figuring out what we really need here. lldb-server will
+ // have already called FinalizeFileActions() as well to button these up
+ // properly.
const size_t num_actions = launch_info.GetNumFileActions();
for (size_t action_index = 0; action_index < num_actions; ++action_index) {
const FileAction *const action =
@@ -533,8 +531,8 @@ Status LaunchInferior(ProcessLaunchInfo &launch_info, int *pty_master_fd,
if (error.Success()) {
launch_info.SetProcessID(static_cast<lldb::pid_t>(pid));
} else {
- // Reset any variables that might have been set during a failed
- // launch attempt.
+ // Reset any variables that might have been set during a failed launch
+ // attempt.
if (pty_master_fd)
*pty_master_fd = -1;
@@ -616,8 +614,8 @@ Status LaunchInferior(ProcessLaunchInfo &launch_info, int *pty_master_fd,
if (pty_master_fd)
*pty_master_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
} else {
- // Reset any variables that might have been set during a failed
- // launch attempt.
+ // Reset any variables that might have been set during a failed launch
+ // attempt.
if (pty_master_fd)
*pty_master_fd = -1;
@@ -636,8 +634,8 @@ Status LaunchInferior(ProcessLaunchInfo &launch_info, int *pty_master_fd,
}
if (launch_info.GetProcessID() == LLDB_INVALID_PROCESS_ID) {
- // If we don't have a valid process ID and no one has set the error,
- // then return a generic error.
+ // If we don't have a valid process ID and no one has set the error, then
+ // return a generic error.
if (error.Success())
error.SetErrorStringWithFormat("%s(): failed to launch, no reason "
"specified",
diff --git a/source/Plugins/Process/Darwin/MachException.cpp b/source/Plugins/Process/Darwin/MachException.cpp
index 9f5920753d68..353f2df32139 100644
--- a/source/Plugins/Process/Darwin/MachException.cpp
+++ b/source/Plugins/Process/Darwin/MachException.cpp
@@ -92,8 +92,6 @@ extern "C" kern_return_t catch_mach_exception_raise_state_identity(
(uint64_t)(exc_data_count > 0 ? exc_data[0] : 0xBADDBADD),
(uint64_t)(exc_data_count > 1 ? exc_data[1] : 0xBADDBADD));
}
- mach_port_deallocate(mach_task_self(), task_port);
- mach_port_deallocate(mach_task_self(), thread_port);
return KERN_FAILURE;
}
@@ -249,20 +247,19 @@ bool MachException::Message::CatchExceptionRaise(task_t task) {
bool success = false;
state.task_port = task;
g_message = &state;
- // The exc_server function is the MIG generated server handling function
- // to handle messages from the kernel relating to the occurrence of an
- // exception in a thread. Such messages are delivered to the exception port
- // set via thread_set_exception_ports or task_set_exception_ports. When an
- // exception occurs in a thread, the thread sends an exception message to
- // its exception port, blocking in the kernel waiting for the receipt of a
- // reply. The exc_server function performs all necessary argument handling
- // for this kernel message and calls catch_exception_raise,
- // catch_exception_raise_state or catch_exception_raise_state_identity,
- // which should handle the exception. If the called routine returns
- // KERN_SUCCESS, a reply message will be sent, allowing the thread to
- // continue from the point of the exception; otherwise, no reply message
- // is sent and the called routine must have dealt with the exception
- // thread directly.
+ // The exc_server function is the MIG generated server handling function to
+ // handle messages from the kernel relating to the occurrence of an exception
+ // in a thread. Such messages are delivered to the exception port set via
+ // thread_set_exception_ports or task_set_exception_ports. When an exception
+ // occurs in a thread, the thread sends an exception message to its exception
+ // port, blocking in the kernel waiting for the receipt of a reply. The
+ // exc_server function performs all necessary argument handling for this
+ // kernel message and calls catch_exception_raise,
+ // catch_exception_raise_state or catch_exception_raise_state_identity, which
+ // should handle the exception. If the called routine returns KERN_SUCCESS, a
+ // reply message will be sent, allowing the thread to continue from the point
+ // of the exception; otherwise, no reply message is sent and the called
+ // routine must have dealt with the exception thread directly.
if (mach_exc_server(&exc_msg.hdr, &reply_msg.hdr)) {
success = true;
} else {
@@ -385,9 +382,9 @@ Status MachException::PortInfo::Save(task_t task) {
log->Printf("MachException::PortInfo::%s(task = 0x%4.4x)", __FUNCTION__,
task);
- // Be careful to be able to have debugserver built on a newer OS than what
- // it is currently running on by being able to start with all exceptions
- // and back off to just what is supported on the current system
+ // Be careful to be able to have debugserver built on a newer OS than what it
+ // is currently running on by being able to start with all exceptions and
+ // back off to just what is supported on the current system
mask = LLDB_EXC_MASK;
count = (sizeof(ports) / sizeof(ports[0]));
diff --git a/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp b/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp
index 518f0d2da4f2..3505443abcb0 100644
--- a/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp
+++ b/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp
@@ -104,8 +104,8 @@ Status NativeProcessProtocol::Launch(
return error;
}
- // Finalize the processing needed to debug the launched process with
- // a NativeProcessDarwin instance.
+ // Finalize the processing needed to debug the launched process with a
+ // NativeProcessDarwin instance.
error = np_darwin_sp->FinalizeLaunch(launch_flavor, mainloop);
if (!error.Success()) {
if (log)
@@ -194,9 +194,9 @@ Status NativeProcessDarwin::FinalizeLaunch(LaunchFlavor launch_flavor,
"mach exception port monitor thread: %s",
__FUNCTION__, error.AsCString());
- // Terminate the inferior process. There's nothing meaningful we can
- // do if we can't receive signals and exceptions. Since we launched
- // the process, it's fair game for us to kill it.
+ // Terminate the inferior process. There's nothing meaningful we can do if
+ // we can't receive signals and exceptions. Since we launched the process,
+ // it's fair game for us to kill it.
::ptrace(PT_KILL, m_pid, 0, 0);
SetState(eStateExited);
@@ -243,9 +243,9 @@ Status NativeProcessDarwin::FinalizeLaunch(LaunchFlavor launch_flavor,
}
if (TaskPortForProcessID(error) == TASK_NULL) {
- // We failed to get the task for our process ID which is bad.
- // Kill our process; otherwise, it will be stopped at the entry
- // point and get reparented to someone else and never go away.
+ // We failed to get the task for our process ID which is bad. Kill our
+ // process; otherwise, it will be stopped at the entry point and get
+ // reparented to someone else and never go away.
if (log)
log->Printf("NativeProcessDarwin::%s(): could not get task port "
"for process, sending SIGKILL and exiting: %s",
@@ -277,9 +277,9 @@ bool NativeProcessDarwin::ProcessUsingBackBoard() const {
return false;
}
-// Called by the exception thread when an exception has been received from
-// our process. The exception message is completely filled and the exception
-// data has already been copied.
+// Called by the exception thread when an exception has been received from our
+// process. The exception message is completely filled and the exception data
+// has already been copied.
void NativeProcessDarwin::ExceptionMessageReceived(
const MachException::Message &message) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
@@ -290,8 +290,8 @@ void NativeProcessDarwin::ExceptionMessageReceived(
SuspendTask();
}
- // Use a locker to automatically unlock our mutex in case of exceptions
- // Add the exception to our internal exception stack
+ // Use a locker to automatically unlock our mutex in case of exceptions Add
+ // the exception to our internal exception stack
m_exception_messages.push_back(message);
if (log)
@@ -324,13 +324,12 @@ void *NativeProcessDarwin::DoExceptionThread() {
// Ensure we don't get CPU starved.
MaybeRaiseThreadPriority();
- // We keep a count of the number of consecutive exceptions received so
- // we know to grab all exceptions without a timeout. We do this to get a
- // bunch of related exceptions on our exception port so we can process
- // then together. When we have multiple threads, we can get an exception
- // per thread and they will come in consecutively. The main loop in this
- // thread can stop periodically if needed to service things related to this
- // process.
+ // We keep a count of the number of consecutive exceptions received so we
+ // know to grab all exceptions without a timeout. We do this to get a bunch
+ // of related exceptions on our exception port so we can process then
+ // together. When we have multiple threads, we can get an exception per
+ // thread and they will come in consecutively. The main loop in this thread
+ // can stop periodically if needed to service things related to this process.
//
// [did we lose some words here?]
//
@@ -338,15 +337,15 @@ void *NativeProcessDarwin::DoExceptionThread() {
// 0 our exception port. After we get one exception, we then will use the
// MACH_RCV_TIMEOUT option with a zero timeout to grab all other current
// exceptions for our process. After we have received the last pending
- // exception, we will get a timeout which enables us to then notify
- // our main thread that we have an exception bundle available. We then wait
- // for the main thread to tell this exception thread to start trying to get
+ // exception, we will get a timeout which enables us to then notify our main
+ // thread that we have an exception bundle available. We then wait for the
+ // main thread to tell this exception thread to start trying to get
// exceptions messages again and we start again with a mach_msg read with
// infinite timeout.
//
// We choose to park a thread on this, rather than polling, because the
- // polling is expensive. On devices, we need to minimize overhead caused
- // by the process monitor.
+ // polling is expensive. On devices, we need to minimize overhead caused by
+ // the process monitor.
uint32_t num_exceptions_received = 0;
Status error;
task_t task = m_task;
@@ -359,8 +358,7 @@ void *NativeProcessDarwin::DoExceptionThread() {
CFReleaser<SBSWatchdogAssertionRef> watchdog;
if (process->ProcessUsingSpringBoard()) {
- // Request a renewal for every 60 seconds if we attached using
- // SpringBoard.
+ // Request a renewal for every 60 seconds if we attached using SpringBoard.
watchdog.reset(::SBSWatchdogAssertionCreateForPID(nullptr, pid, 60));
if (log)
log->Printf("::SBSWatchdogAssertionCreateForPID(NULL, %4.4x, 60) "
@@ -401,18 +399,18 @@ void *NativeProcessDarwin::DoExceptionThread() {
}
#endif // #ifdef WITH_BKS
- // Do we want to use a weak pointer to the NativeProcessDarwin here, in
- // which case we can guarantee we don't whack the process monitor if we
- // race between this thread and the main one on shutdown?
+ // Do we want to use a weak pointer to the NativeProcessDarwin here, in which
+ // case we can guarantee we don't whack the process monitor if we race
+ // between this thread and the main one on shutdown?
while (IsExceptionPortValid()) {
::pthread_testcancel();
MachException::Message exception_message;
if (num_exceptions_received > 0) {
- // We don't want a timeout here, just receive as many exceptions as
- // we can since we already have one. We want to get all currently
- // available exceptions for this task at once.
+ // We don't want a timeout here, just receive as many exceptions as we
+ // can since we already have one. We want to get all currently available
+ // exceptions for this task at once.
error = exception_message.Receive(
GetExceptionPort(),
MACH_RCV_MSG | MACH_RCV_INTERRUPT | MACH_RCV_TIMEOUT, 0);
@@ -424,8 +422,8 @@ void *NativeProcessDarwin::DoExceptionThread() {
MACH_RCV_TIMEOUT,
periodic_timeout);
} else {
- // We don't need to parse all current exceptions or stop
- // periodically, just wait for an exception forever.
+ // We don't need to parse all current exceptions or stop periodically,
+ // just wait for an exception forever.
error = exception_message.Receive(GetExceptionPort(),
MACH_RCV_MSG | MACH_RCV_INTERRUPT, 0);
}
@@ -462,8 +460,8 @@ void *NativeProcessDarwin::DoExceptionThread() {
__FUNCTION__);
continue;
} else {
- // The inferior task is no longer valid. Time to exit as
- // the process has gone away.
+ // The inferior task is no longer valid. Time to exit as the process
+ // has gone away.
if (log)
log->Printf("NativeProcessDarwin::%s(): the inferior task "
"has exited, and so will we...",
@@ -476,18 +474,17 @@ void *NativeProcessDarwin::DoExceptionThread() {
// We timed out when waiting for exceptions.
if (num_exceptions_received > 0) {
- // We were receiving all current exceptions with a timeout of
- // zero. It is time to go back to our normal looping mode.
+ // We were receiving all current exceptions with a timeout of zero.
+ // It is time to go back to our normal looping mode.
num_exceptions_received = 0;
- // Notify our main thread we have a complete exception message
- // bundle available. Get the possibly updated task port back
- // from the process in case we exec'ed and our task port
- // changed.
+ // Notify our main thread we have a complete exception message bundle
+ // available. Get the possibly updated task port back from the
+ // process in case we exec'ed and our task port changed.
task = ExceptionMessageBundleComplete();
- // In case we use a timeout value when getting exceptions,
- // make sure our task is still valid.
+ // In case we use a timeout value when getting exceptions, make sure
+ // our task is still valid.
if (IsTaskValid(task)) {
// Task is still ok.
if (log)
@@ -496,8 +493,8 @@ void *NativeProcessDarwin::DoExceptionThread() {
__FUNCTION__);
continue;
} else {
- // The inferior task is no longer valid. Time to exit as
- // the process has gone away.
+ // The inferior task is no longer valid. Time to exit as the
+ // process has gone away.
if (log)
log->Printf("NativeProcessDarwin::%s(): the inferior "
"task has exited, and so will we...",
@@ -534,10 +531,8 @@ void *NativeProcessDarwin::DoExceptionThread() {
// TODO: change SBSWatchdogAssertionRelease to SBSWatchdogAssertionCancel
// when we
// all are up and running on systems that support it. The SBS framework has
- // a #define
- // that will forward SBSWatchdogAssertionRelease to
- // SBSWatchdogAssertionCancel for now
- // so it should still build either way.
+ // a #define that will forward SBSWatchdogAssertionRelease to
+ // SBSWatchdogAssertionCancel for now so it should still build either way.
DNBLogThreadedIf(LOG_TASK, "::SBSWatchdogAssertionRelease(%p)",
watchdog.get());
::SBSWatchdogAssertionRelease(watchdog.get());
@@ -728,8 +723,8 @@ task_t NativeProcessDarwin::ExceptionMessageBundleComplete() {
const int signo = m_exception_messages[i].state.SoftSignal();
if (signo == SIGTRAP) {
// SIGTRAP could mean that we exec'ed. We need to check the
- // dyld all_image_infos.infoArray to see if it is NULL and if
- // so, say that we exec'ed.
+ // dyld all_image_infos.infoArray to see if it is NULL and if so, say
+ // that we exec'ed.
const addr_t aii_addr = GetDYLDAllImageInfosAddress(error);
if (aii_addr == LLDB_INVALID_ADDRESS)
break;
@@ -744,12 +739,12 @@ task_t NativeProcessDarwin::ExceptionMessageBundleComplete() {
bytes_read); // #bytes read
if (read_error.Success() && (bytes_read == 4)) {
if (info_array_count == 0) {
- // We got the all infos address, and there are zero
- // entries. We think we exec'd.
+ // We got the all infos address, and there are zero entries. We
+ // think we exec'd.
m_did_exec = true;
- // Force the task port to update itself in case the
- // task port changed after exec
+ // Force the task port to update itself in case the task port
+ // changed after exec
const task_t old_task = m_task;
const bool force_update = true;
const task_t new_task = TaskPortForProcessID(error, force_update);
@@ -810,8 +805,7 @@ task_t NativeProcessDarwin::ExceptionMessageBundleComplete() {
// 4 - We might need to resume if we stopped only with the
// interrupt signal that we never handled.
if (m_auto_resume_signo != 0) {
- // Only auto_resume if we stopped with _only_ the interrupt
- // signal.
+ // Only auto_resume if we stopped with _only_ the interrupt signal.
if (num_task_exceptions == 1) {
auto_resume = true;
if (log)
@@ -831,8 +825,8 @@ task_t NativeProcessDarwin::ExceptionMessageBundleComplete() {
}
}
- // Let all threads recover from stopping and do any clean up based
- // on the previous thread state (if any).
+ // Let all threads recover from stopping and do any clean up based on the
+ // previous thread state (if any).
m_thread_list.ProcessDidStop(*this);
// Let each thread know of any exceptions
@@ -863,8 +857,8 @@ task_t NativeProcessDarwin::ExceptionMessageBundleComplete() {
// TODO - need to hook up event system here. !!!!
#if 0
// Wait for the eEventProcessRunningStateChanged event to be reset
- // before changing state to stopped to avoid race condition with
- // very fast start/stops.
+ // before changing state to stopped to avoid race condition with very
+ // fast start/stops.
struct timespec timeout;
//DNBTimer::OffsetTimeOfDay(&timeout, 0, 250 * 1000); // Wait for 250 ms
@@ -889,12 +883,12 @@ Status NativeProcessDarwin::StartWaitpidThread(MainLoop &main_loop) {
Status error;
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- // Strategy: create a thread that sits on waitpid(), waiting for the
- // inferior process to die, reaping it in the process. Arrange for
- // the thread to have a pipe file descriptor that it can send a byte
- // over when the waitpid completes. Have the main loop have a read
- // object for the other side of the pipe, and have the callback for
- // the read do the process termination message sending.
+ // Strategy: create a thread that sits on waitpid(), waiting for the inferior
+ // process to die, reaping it in the process. Arrange for the thread to have
+ // a pipe file descriptor that it can send a byte over when the waitpid
+ // completes. Have the main loop have a read object for the other side of
+ // the pipe, and have the callback for the read do the process termination
+ // message sending.
// Create a single-direction communication channel.
const bool child_inherits = false;
@@ -1025,8 +1019,8 @@ void *NativeProcessDarwin::DoWaitpidThread() {
}
}
- // We should never exit as long as our child process is alive. If we
- // get here, something completely unexpected went wrong and we should exit.
+ // We should never exit as long as our child process is alive. If we get
+ // here, something completely unexpected went wrong and we should exit.
if (log)
log->Printf(
"NativeProcessDarwin::%s(): internal error: waitpid thread "
@@ -1157,8 +1151,8 @@ task_t NativeProcessDarwin::TaskPortForProcessID(Status &error,
::usleep(usec_interval);
}
- // We failed to get the task for the inferior process.
- // Ensure that it is cleared out.
+ // We failed to get the task for the inferior process. Ensure that it is
+ // cleared out.
m_task = TASK_NULL;
}
return m_task;
@@ -1196,9 +1190,9 @@ Status NativeProcessDarwin::PrivateResume() {
}
// bool stepOverBreakInstruction = step;
- // Let the thread prepare to resume and see if any threads want us to
- // step over a breakpoint instruction (ProcessWillResume will modify
- // the value of stepOverBreakInstruction).
+ // Let the thread prepare to resume and see if any threads want us to step
+ // over a breakpoint instruction (ProcessWillResume will modify the value of
+ // stepOverBreakInstruction).
m_thread_list.ProcessWillResume(*this, m_thread_actions);
// Set our state accordingly
@@ -1254,8 +1248,8 @@ Status NativeProcessDarwin::ReplyToAllExceptions() {
error = message.Reply(m_pid, m_task, thread_reply_signal);
if (error.Fail() && log) {
- // We log any error here, but we don't stop the exception
- // response handling.
+ // We log any error here, but we don't stop the exception response
+ // handling.
log->Printf("NativeProcessDarwin::%s(): failed to reply to "
"exception: %s",
__FUNCTION__, error.AsCString());
@@ -1263,8 +1257,8 @@ Status NativeProcessDarwin::ReplyToAllExceptions() {
}
}
- // Erase all exception message as we should have used and replied
- // to them all already.
+ // Erase all exception message as we should have used and replied to them all
+ // already.
m_exception_messages.clear();
return error;
}
@@ -1292,8 +1286,8 @@ Status NativeProcessDarwin::ResumeTask() {
"0x%4.4x",
__FUNCTION__, m_task);
- // Get the BasicInfo struct to verify that we're suspended before we try
- // to resume the task.
+ // Get the BasicInfo struct to verify that we're suspended before we try to
+ // resume the task.
struct task_basic_info task_info;
error = GetTaskBasicInfo(m_task, &task_info);
if (error.Fail()) {
@@ -1304,9 +1298,8 @@ Status NativeProcessDarwin::ResumeTask() {
return error;
}
- // task_resume isn't counted like task_suspend calls are, so if the
- // task is not suspended, don't try and resume it since it is already
- // running
+ // task_resume isn't counted like task_suspend calls are, so if the task is
+ // not suspended, don't try and resume it since it is already running
if (task_info.suspend_count > 0) {
auto mach_err = ::task_resume(m_task);
error.SetError(mach_err, eErrorTypeMachKernel);
diff --git a/source/Plugins/Process/Darwin/NativeProcessDarwin.h b/source/Plugins/Process/Darwin/NativeProcessDarwin.h
index 649280c17a8f..0b186fd7d80c 100644
--- a/source/Plugins/Process/Darwin/NativeProcessDarwin.h
+++ b/source/Plugins/Process/Darwin/NativeProcessDarwin.h
@@ -43,10 +43,10 @@ class Scalar;
namespace process_darwin {
/// @class NativeProcessDarwin
-/// @brief Manages communication with the inferior (debugee) process.
+/// Manages communication with the inferior (debugee) process.
///
-/// Upon construction, this class prepares and launches an inferior
-/// process for debugging.
+/// Upon construction, this class prepares and launches an inferior process
+/// for debugging.
///
/// Changes in the inferior process state are broadcasted.
class NativeProcessDarwin : public NativeProcessProtocol {
@@ -205,10 +205,10 @@ private:
// -----------------------------------------------------------------
/// Finalize the launch.
///
- /// This method associates the NativeProcessDarwin instance with
- /// the host process that was just launched. It peforms actions
- /// like attaching a listener to the inferior exception port,
- /// ptracing the process, and the like.
+ /// This method associates the NativeProcessDarwin instance with the host
+ /// process that was just launched. It peforms actions like attaching a
+ /// listener to the inferior exception port, ptracing the process, and the
+ /// like.
///
/// @param[in] launch_flavor
/// The launch flavor that was used to launch the process.
@@ -263,8 +263,8 @@ private:
task_t TaskPortForProcessID(Status &error, bool force = false) const;
- /// Attaches to an existing process. Forms the
- /// implementation of Process::DoAttach.
+ /// Attaches to an existing process. Forms the implementation of
+ /// Process::DoAttach.
void AttachToInferior(MainLoop &mainloop, lldb::pid_t pid, Status &error);
::pid_t Attach(lldb::pid_t pid, Status &error);
@@ -323,8 +323,8 @@ private:
Status GetSignalInfo(lldb::tid_t tid, void *siginfo);
/// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
- /// corresponding to the given thread ID to the memory pointed to
- /// by @p message.
+ /// corresponding to the given thread ID to the memory pointed to by @p
+ /// message.
Status GetEventMessage(lldb::tid_t tid, unsigned long *message);
void NotifyThreadDeath(lldb::tid_t tid);
diff --git a/source/Plugins/Process/Darwin/NativeThreadDarwin.cpp b/source/Plugins/Process/Darwin/NativeThreadDarwin.cpp
index 07398ab7b678..521c6d5c8fd0 100644
--- a/source/Plugins/Process/Darwin/NativeThreadDarwin.cpp
+++ b/source/Plugins/Process/Darwin/NativeThreadDarwin.cpp
@@ -30,8 +30,8 @@ uint64_t NativeThreadDarwin::GetGloballyUniqueThreadIDForMachPortID(
(thread_info_t)&tident, &tident_count);
if (mach_err != KERN_SUCCESS) {
// When we fail to get thread info for the supposed port, assume it is
- // really a globally unique thread id already, or return the best thing
- // we can, which is the thread port.
+ // really a globally unique thread id already, or return the best thing we
+ // can, which is the thread port.
return mach_port_id;
}
return tident.thread_id;
@@ -47,9 +47,9 @@ NativeThreadDarwin::NativeThreadDarwin(NativeProcessDarwin *process,
bool NativeThreadDarwin::GetIdentifierInfo() {
// Don't try to get the thread info once and cache it for the life of the
- // thread. It changes over time, for instance
- // if the thread name changes, then the thread_handle also changes... So you
- // have to refetch it every time.
+ // thread. It changes over time, for instance if the thread name changes,
+ // then the thread_handle also changes... So you have to refetch it every
+ // time.
mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
kern_return_t kret = ::thread_info(m_mach_thread_port, THREAD_IDENTIFIER_INFO,
(thread_info_t)&m_ident_info, &count);
@@ -137,16 +137,16 @@ bool NativeThreadDarwin::NotifyException(MachException::Data &exc) {
// TODO implement this.
#if 0
// Allow the arch specific protocol to process (MachException::Data &)exc
- // first before possible reassignment of m_stop_exception with exc.
- // See also MachThread::GetStopException().
+ // first before possible reassignment of m_stop_exception with exc. See
+ // also MachThread::GetStopException().
bool handled = m_arch_ap->NotifyException(exc);
if (m_stop_exception.IsValid())
{
// We may have more than one exception for a thread, but we need to
- // only remember the one that we will say is the reason we stopped.
- // We may have been single stepping and also gotten a signal exception,
- // so just remember the most pertinent one.
+ // only remember the one that we will say is the reason we stopped. We
+ // may have been single stepping and also gotten a signal exception, so
+ // just remember the most pertinent one.
if (m_stop_exception.IsBreakpoint())
m_stop_exception = exc;
}
@@ -170,8 +170,8 @@ bool NativeThreadDarwin::ShouldStop(bool &step_more) const {
if (bp)
{
- // This thread is sitting at a breakpoint, ask the breakpoint
- // if we should be stopping here.
+ // This thread is sitting at a breakpoint, ask the breakpoint if we
+ // should be stopping here.
return true;
}
else
@@ -181,11 +181,10 @@ bool NativeThreadDarwin::ShouldStop(bool &step_more) const {
step_more = true;
return false;
}
- // The thread state is used to let us know what the thread was
- // trying to do. MachThread::ThreadWillResume() will set the
- // thread state to various values depending if the thread was
- // the current thread and if it was to be single stepped, or
- // resumed.
+ // The thread state is used to let us know what the thread was trying
+ // to do. MachThread::ThreadWillResume() will set the thread state to
+ // various values depending if the thread was the current thread and if
+ // it was to be single stepped, or resumed.
if (GetState() == eStateRunning)
{
// If our state is running, then we should continue as we are in
@@ -194,8 +193,7 @@ bool NativeThreadDarwin::ShouldStop(bool &step_more) const {
}
else
{
- // Stop if we have any kind of valid exception for this
- // thread.
+ // Stop if we have any kind of valid exception for this thread.
if (GetStopException().IsValid())
return true;
}
@@ -209,17 +207,17 @@ bool NativeThreadDarwin::ShouldStop(bool &step_more) const {
void NativeThreadDarwin::ThreadDidStop() {
// TODO implement this.
#if 0
- // This thread has existed prior to resuming under debug nub control,
- // and has just been stopped. Do any cleanup that needs to be done
- // after running.
+ // This thread has existed prior to resuming under debug nub control, and
+ // has just been stopped. Do any cleanup that needs to be done after
+ // running.
- // The thread state and breakpoint will still have the same values
- // as they had prior to resuming the thread, so it makes it easy to check
- // if we were trying to step a thread, or we tried to resume while being
- // at a breakpoint.
+ // The thread state and breakpoint will still have the same values as they
+ // had prior to resuming the thread, so it makes it easy to check if we
+ // were trying to step a thread, or we tried to resume while being at a
+ // breakpoint.
- // When this method gets called, the process state is still in the
- // state it was in while running so we can act accordingly.
+ // When this method gets called, the process state is still in the state it
+ // was in while running so we can act accordingly.
m_arch_ap->ThreadDidStop();
diff --git a/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp b/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp
index 7d44adeec375..4ff662e42097 100644
--- a/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp
+++ b/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp
@@ -308,8 +308,8 @@ uint32_t NativeThreadListDarwin::UpdateThreadList(NativeProcessDarwin &process,
__FUNCTION__, process.GetID(), update, process.GetStopID());
if (process.GetStopID() == 0) {
- // On our first stop, we'll record details like 32/64 bitness and
- // select the proper architecture implementation.
+ // On our first stop, we'll record details like 32/64 bitness and select
+ // the proper architecture implementation.
//
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)process.GetID()};
@@ -358,9 +358,9 @@ uint32_t NativeThreadListDarwin::UpdateThreadList(NativeProcessDarwin &process,
if (thread_list_count > 0) {
collection currThreads;
size_t idx;
- // Iterator through the current thread list and see which threads
- // we already have in our list (keep them), which ones we don't
- // (add them), and which ones are not around anymore (remove them).
+ // Iterator through the current thread list and see which threads we
+ // already have in our list (keep them), which ones we don't (add them),
+ // and which ones are not around anymore (remove them).
for (idx = 0; idx < thread_list_count; ++idx) {
// Get the Mach thread port.
const ::thread_t mach_port_num = thread_list[idx];
@@ -373,18 +373,18 @@ uint32_t NativeThreadListDarwin::UpdateThreadList(NativeProcessDarwin &process,
// Retrieve the thread if it exists.
auto thread_sp = GetThreadByID(unique_thread_id);
if (thread_sp) {
- // We are already tracking it. Keep the existing native
- // thread instance.
+ // We are already tracking it. Keep the existing native thread
+ // instance.
currThreads.push_back(thread_sp);
} else {
- // We don't have a native thread instance for this thread.
- // Create it now.
+ // We don't have a native thread instance for this thread. Create it
+ // now.
thread_sp.reset(new NativeThreadDarwin(
&process, m_is_64_bit, unique_thread_id, mach_port_num));
- // Add the new thread regardless of its is user ready state.
- // Make sure the thread is ready to be displayed and shown
- // to users before we add this thread to our list...
+ // Add the new thread regardless of its is user ready state. Make
+ // sure the thread is ready to be displayed and shown to users before
+ // we add this thread to our list...
if (thread_sp->IsUserReady()) {
if (new_threads)
new_threads->push_back(thread_sp);
@@ -417,9 +417,9 @@ NativeThreadListDarwin::CurrentThread (MachThreadSP& thread_sp)
PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
if (m_current_thread.get() == NULL)
{
- // Figure out which thread is going to be our current thread.
- // This is currently done by finding the first thread in the list
- // that has a valid exception.
+ // Figure out which thread is going to be our current thread. This is
+ // currently done by finding the first thread in the list that has a
+ // valid exception.
const size_t num_threads = m_threads.size();
for (uint32_t idx = 0; idx < num_threads; ++idx)
{
@@ -455,8 +455,8 @@ void NativeThreadListDarwin::ProcessWillResume(
NativeProcessDarwin &process, const ResumeActionList &thread_actions) {
std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
- // Update our thread list, because sometimes libdispatch or the kernel
- // will spawn threads while a task is suspended.
+ // Update our thread list, because sometimes libdispatch or the kernel will
+ // spawn threads while a task is suspended.
NativeThreadListDarwin::collection new_threads;
// TODO implement this.
@@ -489,7 +489,8 @@ void NativeThreadListDarwin::ProcessWillResume(
#if 0
DNBThreadResumeAction resume_new_threads = { -1U, eStateRunning, 0, INVALID_NUB_ADDRESS };
- // If we are planning to run only one thread, any new threads should be suspended.
+ // If we are planning to run only one thread, any new threads should be
+ // suspended.
if (run_one_thread)
resume_new_threads.state = eStateSuspended;
@@ -549,11 +550,11 @@ uint32_t NativeThreadListDarwin::ProcessDidStop(NativeProcessDarwin &process) {
}
//----------------------------------------------------------------------
-// Check each thread in our thread list to see if we should notify our
-// client of the current halt in execution.
+// Check each thread in our thread list to see if we should notify our client
+// of the current halt in execution.
//
-// Breakpoints can have callback functions associated with them than
-// can return true to stop, or false to continue executing the inferior.
+// Breakpoints can have callback functions associated with them than can return
+// true to stop, or false to continue executing the inferior.
//
// RETURNS
// true if we should stop and notify our clients
@@ -607,8 +608,9 @@ NativeThreadListDarwin::DisableHardwareBreakpoint (const DNBBreakpoint* bp) cons
return false;
}
-// DNBWatchpointSet() -> MachProcess::CreateWatchpoint() -> MachProcess::EnableWatchpoint()
-// -> NativeThreadListDarwin::EnableHardwareWatchpoint().
+// DNBWatchpointSet() -> MachProcess::CreateWatchpoint() ->
+// MachProcess::EnableWatchpoint() ->
+// NativeThreadListDarwin::EnableHardwareWatchpoint().
uint32_t
NativeThreadListDarwin::EnableHardwareWatchpoint (const DNBBreakpoint* wp) const
{
@@ -617,14 +619,16 @@ NativeThreadListDarwin::EnableHardwareWatchpoint (const DNBBreakpoint* wp) const
{
PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
const size_t num_threads = m_threads.size();
- // On Mac OS X we have to prime the control registers for new threads. We do this
- // using the control register data for the first thread, for lack of a better way of choosing.
+ // On Mac OS X we have to prime the control registers for new threads.
+ // We do this using the control register data for the first thread, for
+ // lack of a better way of choosing.
bool also_set_on_task = true;
for (uint32_t idx = 0; idx < num_threads; ++idx)
{
if ((hw_index = m_threads[idx]->EnableHardwareWatchpoint(wp, also_set_on_task)) == INVALID_NUB_HW_INDEX)
{
- // We know that idx failed for some reason. Let's rollback the transaction for [0, idx).
+ // We know that idx failed for some reason. Let's rollback the
+ // transaction for [0, idx).
for (uint32_t i = 0; i < idx; ++i)
m_threads[i]->RollbackTransForHWP();
return INVALID_NUB_HW_INDEX;
@@ -647,14 +651,16 @@ NativeThreadListDarwin::DisableHardwareWatchpoint (const DNBBreakpoint* wp) cons
PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
const size_t num_threads = m_threads.size();
- // On Mac OS X we have to prime the control registers for new threads. We do this
- // using the control register data for the first thread, for lack of a better way of choosing.
+ // On Mac OS X we have to prime the control registers for new threads.
+ // We do this using the control register data for the first thread, for
+ // lack of a better way of choosing.
bool also_set_on_task = true;
for (uint32_t idx = 0; idx < num_threads; ++idx)
{
if (!m_threads[idx]->DisableHardwareWatchpoint(wp, also_set_on_task))
{
- // We know that idx failed for some reason. Let's rollback the transaction for [0, idx).
+ // We know that idx failed for some reason. Let's rollback the
+ // transaction for [0, idx).
for (uint32_t i = 0; i < idx; ++i)
m_threads[i]->RollbackTransForHWP();
return false;
@@ -675,7 +681,8 @@ NativeThreadListDarwin::NumSupportedHardwareWatchpoints () const
{
PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
const size_t num_threads = m_threads.size();
- // Use an arbitrary thread to retrieve the number of supported hardware watchpoints.
+ // Use an arbitrary thread to retrieve the number of supported hardware
+ // watchpoints.
if (num_threads)
return m_threads[0]->NumSupportedHardwareWatchpoints();
return 0;
diff --git a/source/Plugins/Process/FreeBSD/CMakeLists.txt b/source/Plugins/Process/FreeBSD/CMakeLists.txt
index 63855992d708..c8301f350e07 100644
--- a/source/Plugins/Process/FreeBSD/CMakeLists.txt
+++ b/source/Plugins/Process/FreeBSD/CMakeLists.txt
@@ -1,7 +1,3 @@
-include_directories(.)
-include_directories(../POSIX)
-include_directories(../Utility)
-
add_lldb_library(lldbPluginProcessFreeBSD PLUGIN
ProcessFreeBSD.cpp
FreeBSDThread.cpp
diff --git a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
index e6557c2d58e0..3576a7f26f86 100644
--- a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
+++ b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
@@ -57,7 +57,7 @@ using namespace lldb_private;
FreeBSDThread::FreeBSDThread(Process &process, lldb::tid_t tid)
: Thread(process, tid), m_frame_ap(), m_breakpoint(),
- m_thread_name_valid(false), m_thread_name(), m_posix_thread(NULL) {
+ m_thread_name_valid(false), m_thread_name(), m_posix_thread(nullptr) {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
LLDB_LOGV(log, "tid = {0}", tid);
@@ -69,15 +69,15 @@ FreeBSDThread::FreeBSDThread(Process &process, lldb::tid_t tid)
for (uint32_t wp_idx = 0; wp_idx < wp_size; wp_idx++) {
lldb::WatchpointSP wp = wp_list.GetByIndex(wp_idx);
if (wp.get() && wp->IsEnabled()) {
- // This watchpoint as been enabled; obviously this "new" thread
- // has been created since that watchpoint was enabled. Since
- // the POSIXBreakpointProtocol has yet to be initialized, its
- // m_watchpoints_initialized member will be FALSE. Attempting to
- // read the debug status register to determine if a watchpoint
- // has been hit would result in the zeroing of that register.
- // Since the active debug registers would have been cloned when
- // this thread was created, simply force the m_watchpoints_initized
- // member to TRUE and avoid resetting dr6 and dr7.
+ // This watchpoint as been enabled; obviously this "new" thread has been
+ // created since that watchpoint was enabled. Since the
+ // POSIXBreakpointProtocol has yet to be initialized, its
+ // m_watchpoints_initialized member will be FALSE. Attempting to read
+ // the debug status register to determine if a watchpoint has been hit
+ // would result in the zeroing of that register. Since the active debug
+ // registers would have been cloned when this thread was created, simply
+ // force the m_watchpoints_initized member to TRUE and avoid resetting
+ // dr6 and dr7.
GetPOSIXBreakpointProtocol()->ForceWatchpointsInitialized();
}
}
@@ -98,16 +98,15 @@ void FreeBSDThread::RefreshStateAfterStop() {
// context by the time this function gets called. The KDPRegisterContext
// class has been made smart enough to detect when it needs to invalidate
// which registers are valid by putting hooks in the register read and
- // register supply functions where they check the process stop ID and do
- // the right thing.
- // if (StateIsStoppedState(GetState())
+ // register supply functions where they check the process stop ID and do the
+ // right thing. if (StateIsStoppedState(GetState())
{
const bool force = false;
GetRegisterContext()->InvalidateIfNeeded(force);
}
}
-const char *FreeBSDThread::GetInfo() { return NULL; }
+const char *FreeBSDThread::GetInfo() { return nullptr; }
void FreeBSDThread::SetName(const char *name) {
m_thread_name_valid = (name && name[0]);
@@ -158,15 +157,15 @@ const char *FreeBSDThread::GetName() {
}
if (m_thread_name.empty())
- return NULL;
+ return nullptr;
return m_thread_name.c_str();
}
lldb::RegisterContextSP FreeBSDThread::GetRegisterContext() {
if (!m_reg_context_sp) {
- m_posix_thread = NULL;
+ m_posix_thread = nullptr;
- RegisterInfoInterface *reg_interface = NULL;
+ RegisterInfoInterface *reg_interface = nullptr;
const ArchSpec &target_arch = GetProcess()->GetTarget().GetArchitecture();
assert(target_arch.GetTriple().getOS() == llvm::Triple::FreeBSD);
@@ -282,7 +281,7 @@ bool FreeBSDThread::CalculateStopInfo() {
}
Unwind *FreeBSDThread::GetUnwinder() {
- if (m_unwinder_ap.get() == NULL)
+ if (!m_unwinder_ap)
m_unwinder_ap.reset(new UnwindLLDB(*this));
return m_unwinder_ap.get();
@@ -469,22 +468,19 @@ void FreeBSDThread::BreakNotify(const ProcessMessage &message) {
GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
// If the breakpoint is for this thread, then we'll report the hit, but if it
- // is for another thread,
- // we create a stop reason with should_stop=false. If there is no breakpoint
- // location, then report
- // an invalid stop reason. We don't need to worry about stepping over the
- // breakpoint here, that will
- // be taken care of when the thread resumes and notices that there's a
+ // is for another thread, we create a stop reason with should_stop=false. If
+ // there is no breakpoint location, then report an invalid stop reason. We
+ // don't need to worry about stepping over the breakpoint here, that will be
+ // taken care of when the thread resumes and notices that there's a
// breakpoint under the pc.
if (bp_site) {
lldb::break_id_t bp_id = bp_site->GetID();
// If we have an operating system plug-in, we might have set a thread
- // specific breakpoint using the
- // operating system thread ID, so we can't make any assumptions about the
- // thread ID so we must always
- // report the breakpoint regardless of the thread.
+ // specific breakpoint using the operating system thread ID, so we can't
+ // make any assumptions about the thread ID so we must always report the
+ // breakpoint regardless of the thread.
if (bp_site->ValidForThisThread(this) ||
- GetProcess()->GetOperatingSystem() != NULL)
+ GetProcess()->GetOperatingSystem() != nullptr)
SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id));
else {
const bool should_stop = false;
@@ -541,15 +537,14 @@ void FreeBSDThread::TraceNotify(const ProcessMessage &message) {
lldb::BreakpointSiteSP bp_site(
GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
- // If the current pc is a breakpoint site then set the StopInfo to Breakpoint.
- // Otherwise, set the StopInfo to Watchpoint or Trace.
- // If we have an operating system plug-in, we might have set a thread specific
- // breakpoint using the
- // operating system thread ID, so we can't make any assumptions about the
- // thread ID so we must always
- // report the breakpoint regardless of the thread.
+ // If the current pc is a breakpoint site then set the StopInfo to
+ // Breakpoint. Otherwise, set the StopInfo to Watchpoint or Trace. If we have
+ // an operating system plug-in, we might have set a thread specific
+ // breakpoint using the operating system thread ID, so we can't make any
+ // assumptions about the thread ID so we must always report the breakpoint
+ // regardless of the thread.
if (bp_site && (bp_site->ValidForThisThread(this) ||
- GetProcess()->GetOperatingSystem() != NULL))
+ GetProcess()->GetOperatingSystem() != nullptr))
SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(
*this, bp_site->GetID()));
else {
diff --git a/source/Plugins/Process/FreeBSD/FreeBSDThread.h b/source/Plugins/Process/FreeBSD/FreeBSDThread.h
index 72e846459552..c93cc4fbfd73 100644
--- a/source/Plugins/Process/FreeBSD/FreeBSDThread.h
+++ b/source/Plugins/Process/FreeBSD/FreeBSDThread.h
@@ -24,7 +24,7 @@ class POSIXBreakpointProtocol;
//------------------------------------------------------------------------------
// @class FreeBSDThread
-// @brief Abstraction of a FreeBSD thread.
+// Abstraction of a FreeBSD thread.
class FreeBSDThread : public lldb_private::Thread {
public:
//------------------------------------------------------------------
diff --git a/source/Plugins/Process/FreeBSD/POSIXStopInfo.h b/source/Plugins/Process/FreeBSD/POSIXStopInfo.h
index 96861852b38e..ff3693107170 100644
--- a/source/Plugins/Process/FreeBSD/POSIXStopInfo.h
+++ b/source/Plugins/Process/FreeBSD/POSIXStopInfo.h
@@ -17,7 +17,7 @@
//===----------------------------------------------------------------------===//
/// @class POSIXStopInfo
-/// @brief Simple base class for all POSIX-specific StopInfo objects.
+/// Simple base class for all POSIX-specific StopInfo objects.
///
class POSIXStopInfo : public lldb_private::StopInfo {
public:
@@ -27,7 +27,7 @@ public:
//===----------------------------------------------------------------------===//
/// @class POSIXLimboStopInfo
-/// @brief Represents the stop state of a process ready to exit.
+/// Represents the stop state of a process ready to exit.
///
class POSIXLimboStopInfo : public POSIXStopInfo {
public:
@@ -46,7 +46,7 @@ public:
//===----------------------------------------------------------------------===//
/// @class POSIXNewThreadStopInfo
-/// @brief Represents the stop state of process when a new thread is spawned.
+/// Represents the stop state of process when a new thread is spawned.
///
class POSIXNewThreadStopInfo : public POSIXStopInfo {
diff --git a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
index 7a937db49be0..fa0bcea8f6bd 100644
--- a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
+++ b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
@@ -357,10 +357,10 @@ ProcessFreeBSD::GetFileSpec(const lldb_private::FileAction *file_action,
if (file_action && file_action->GetAction() == FileAction::eFileActionOpen) {
file_spec = file_action->GetFileSpec();
- // By default the stdio paths passed in will be pseudo-terminal
- // (/dev/pts). If so, convert to using a different default path
- // instead to redirect I/O to the debugger console. This should
- // also handle user overrides to /dev/null or a different file.
+ // By default the stdio paths passed in will be pseudo-terminal (/dev/pts).
+ // If so, convert to using a different default path instead to redirect I/O
+ // to the debugger console. This should also handle user overrides to
+ // /dev/null or a different file.
if (!file_spec || file_spec == dbg_pts_file_spec)
file_spec = default_file_spec;
}
@@ -407,9 +407,8 @@ Status ProcessFreeBSD::DoLaunch(Module *module,
m_monitor = new ProcessMonitor(
this, module, launch_info.GetArguments().GetConstArgumentVector(),
- launch_info.GetEnvironmentEntries().GetConstArgumentVector(),
- stdin_file_spec, stdout_file_spec, stderr_file_spec, working_dir,
- launch_info, error);
+ launch_info.GetEnvironment(), stdin_file_spec, stdout_file_spec,
+ stderr_file_spec, working_dir, launch_info, error);
m_module = module;
@@ -656,19 +655,19 @@ ProcessFreeBSD::GetSoftwareBreakpointTrapOpcode(BreakpointSite *bp_site) {
break;
case llvm::Triple::arm: {
- // The ARM reference recommends the use of 0xe7fddefe and 0xdefe
- // but the linux kernel does otherwise.
+ // The ARM reference recommends the use of 0xe7fddefe and 0xdefe but the
+ // linux kernel does otherwise.
static const uint8_t g_arm_breakpoint_opcode[] = {0xf0, 0x01, 0xf0, 0xe7};
static const uint8_t g_thumb_breakpoint_opcode[] = {0x01, 0xde};
lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0));
- AddressClass addr_class = eAddressClassUnknown;
+ AddressClass addr_class = AddressClass::eUnknown;
if (bp_loc_sp)
addr_class = bp_loc_sp->GetAddress().GetAddressClass();
- if (addr_class == eAddressClassCodeAlternateISA ||
- (addr_class == eAddressClassUnknown &&
+ if (addr_class == AddressClass::eCodeAlternateISA ||
+ (addr_class == AddressClass::eUnknown &&
bp_loc_sp->GetAddress().GetOffset() & 1)) {
opcode = g_thumb_breakpoint_opcode;
opcode_size = sizeof(g_thumb_breakpoint_opcode);
@@ -745,8 +744,8 @@ Status ProcessFreeBSD::EnableWatchpoint(Watchpoint *wp, bool notify) {
wp->SetEnabled(true, notify);
return error;
} else {
- // Watchpoint enabling failed on at least one
- // of the threads so roll back all of them
+ // Watchpoint enabling failed on at least one of the threads so roll
+ // back all of them
DisableWatchpoint(wp, false);
error.SetErrorString("Setting hardware watchpoint failed");
}
@@ -813,8 +812,8 @@ Status ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num) {
Status ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num, bool &after) {
Status error = GetWatchpointSupportInfo(num);
- // Watchpoints trigger and halt the inferior after
- // the corresponding instruction has been executed.
+ // Watchpoints trigger and halt the inferior after the corresponding
+ // instruction has been executed.
after = true;
return error;
}
@@ -1077,8 +1076,8 @@ Status ProcessFreeBSD::SetupSoftwareSingleStepping(lldb::tid_t tid) {
"Emulation was successful but PC wasn't updated");
next_pc = pc_it->second.GetAsUInt64();
} else if (pc_it == baton.m_register_values.end()) {
- // Emulate instruction failed and it haven't changed PC. Advance PC
- // with the size of the current opcode because the emulation of all
+ // Emulate instruction failed and it haven't changed PC. Advance PC with
+ // the size of the current opcode because the emulation of all
// PC modifying instruction should be successful. The failure most
// likely caused by a not supported instruction which don't modify PC.
next_pc =
diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
index bd06fa25f0a0..51fdf2e5ef33 100644
--- a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
+++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
@@ -38,15 +38,11 @@
#include "ProcessFreeBSD.h"
#include "ProcessMonitor.h"
-extern "C" {
-extern char **environ;
-}
-
using namespace lldb;
using namespace lldb_private;
-// We disable the tracing of ptrace calls for integration builds to
-// avoid the additional indirection and checks.
+// We disable the tracing of ptrace calls for integration builds to avoid the
+// additional indirection and checks.
#ifndef LLDB_CONFIGURATION_BUILDANDINTEGRATION
// Wrapper for ptrace to catch errors and log calls.
@@ -65,9 +61,8 @@ const char *Get_PT_IO_OP(int op) {
}
}
-// Wrapper for ptrace to catch errors and log calls.
-// Note that ptrace sets errno on error because -1 is reserved as a valid
-// result.
+// Wrapper for ptrace to catch errors and log calls. Note that ptrace sets
+// errno on error because -1 is reserved as a valid result.
extern long PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data,
const char *reqName, const char *file, int line) {
long int result;
@@ -134,8 +129,8 @@ extern long PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data,
return result;
}
-// Wrapper for ptrace when logging is not required.
-// Sets errno to 0 prior to calling ptrace.
+// Wrapper for ptrace when logging is not required. Sets errno to 0 prior to
+// calling ptrace.
extern long PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data) {
long result = 0;
errno = 0;
@@ -163,8 +158,10 @@ static size_t DoReadMemory(lldb::pid_t pid, lldb::addr_t vm_addr, void *buf,
pi_desc.piod_addr = buf;
pi_desc.piod_len = size;
- if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0)
+ if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0) {
error.SetErrorToErrno();
+ return 0;
+ }
return pi_desc.piod_len;
}
@@ -177,8 +174,10 @@ static size_t DoWriteMemory(lldb::pid_t pid, lldb::addr_t vm_addr,
pi_desc.piod_addr = (void *)buf;
pi_desc.piod_len = size;
- if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0)
+ if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0) {
error.SetErrorToErrno();
+ return 0;
+ }
return pi_desc.piod_len;
}
@@ -202,15 +201,16 @@ static bool EnsureFDFlags(int fd, int flags, Status &error) {
//------------------------------------------------------------------------------
/// @class Operation
-/// @brief Represents a ProcessMonitor operation.
+/// Represents a ProcessMonitor operation.
///
-/// Under FreeBSD, it is not possible to ptrace() from any other thread but the
-/// one that spawned or attached to the process from the start. Therefore, when
-/// a ProcessMonitor is asked to deliver or change the state of an inferior
-/// process the operation must be "funneled" to a specific thread to perform the
-/// task. The Operation class provides an abstract base for all services the
-/// ProcessMonitor must perform via the single virtual function Execute, thus
-/// encapsulating the code that needs to run in the privileged context.
+/// Under FreeBSD, it is not possible to ptrace() from any other thread but
+/// the one that spawned or attached to the process from the start.
+/// Therefore, when a ProcessMonitor is asked to deliver or change the state
+/// of an inferior process the operation must be "funneled" to a specific
+/// thread to perform the task. The Operation class provides an abstract base
+/// for all services the ProcessMonitor must perform via the single virtual
+/// function Execute, thus encapsulating the code that needs to run in the
+/// privileged context.
class Operation {
public:
virtual ~Operation() {}
@@ -219,7 +219,7 @@ public:
//------------------------------------------------------------------------------
/// @class ReadOperation
-/// @brief Implements ProcessMonitor::ReadMemory.
+/// Implements ProcessMonitor::ReadMemory.
class ReadOperation : public Operation {
public:
ReadOperation(lldb::addr_t addr, void *buff, size_t size, Status &error,
@@ -245,7 +245,7 @@ void ReadOperation::Execute(ProcessMonitor *monitor) {
//------------------------------------------------------------------------------
/// @class WriteOperation
-/// @brief Implements ProcessMonitor::WriteMemory.
+/// Implements ProcessMonitor::WriteMemory.
class WriteOperation : public Operation {
public:
WriteOperation(lldb::addr_t addr, const void *buff, size_t size,
@@ -271,7 +271,7 @@ void WriteOperation::Execute(ProcessMonitor *monitor) {
//------------------------------------------------------------------------------
/// @class ReadRegOperation
-/// @brief Implements ProcessMonitor::ReadRegisterValue.
+/// Implements ProcessMonitor::ReadRegisterValue.
class ReadRegOperation : public Operation {
public:
ReadRegOperation(lldb::tid_t tid, unsigned offset, unsigned size,
@@ -311,7 +311,7 @@ void ReadRegOperation::Execute(ProcessMonitor *monitor) {
//------------------------------------------------------------------------------
/// @class WriteRegOperation
-/// @brief Implements ProcessMonitor::WriteRegisterValue.
+/// Implements ProcessMonitor::WriteRegisterValue.
class WriteRegOperation : public Operation {
public:
WriteRegOperation(lldb::tid_t tid, unsigned offset,
@@ -344,7 +344,7 @@ void WriteRegOperation::Execute(ProcessMonitor *monitor) {
//------------------------------------------------------------------------------
/// @class ReadDebugRegOperation
-/// @brief Implements ProcessMonitor::ReadDebugRegisterValue.
+/// Implements ProcessMonitor::ReadDebugRegisterValue.
class ReadDebugRegOperation : public Operation {
public:
ReadDebugRegOperation(lldb::tid_t tid, unsigned offset, unsigned size,
@@ -379,7 +379,7 @@ void ReadDebugRegOperation::Execute(ProcessMonitor *monitor) {
//------------------------------------------------------------------------------
/// @class WriteDebugRegOperation
-/// @brief Implements ProcessMonitor::WriteDebugRegisterValue.
+/// Implements ProcessMonitor::WriteDebugRegisterValue.
class WriteDebugRegOperation : public Operation {
public:
WriteDebugRegOperation(lldb::tid_t tid, unsigned offset,
@@ -412,7 +412,7 @@ void WriteDebugRegOperation::Execute(ProcessMonitor *monitor) {
//------------------------------------------------------------------------------
/// @class ReadGPROperation
-/// @brief Implements ProcessMonitor::ReadGPR.
+/// Implements ProcessMonitor::ReadGPR.
class ReadGPROperation : public Operation {
public:
ReadGPROperation(lldb::tid_t tid, void *buf, bool &result)
@@ -439,7 +439,7 @@ void ReadGPROperation::Execute(ProcessMonitor *monitor) {
//------------------------------------------------------------------------------
/// @class ReadFPROperation
-/// @brief Implements ProcessMonitor::ReadFPR.
+/// Implements ProcessMonitor::ReadFPR.
class ReadFPROperation : public Operation {
public:
ReadFPROperation(lldb::tid_t tid, void *buf, bool &result)
@@ -462,7 +462,7 @@ void ReadFPROperation::Execute(ProcessMonitor *monitor) {
//------------------------------------------------------------------------------
/// @class WriteGPROperation
-/// @brief Implements ProcessMonitor::WriteGPR.
+/// Implements ProcessMonitor::WriteGPR.
class WriteGPROperation : public Operation {
public:
WriteGPROperation(lldb::tid_t tid, void *buf, bool &result)
@@ -485,7 +485,7 @@ void WriteGPROperation::Execute(ProcessMonitor *monitor) {
//------------------------------------------------------------------------------
/// @class WriteFPROperation
-/// @brief Implements ProcessMonitor::WriteFPR.
+/// Implements ProcessMonitor::WriteFPR.
class WriteFPROperation : public Operation {
public:
WriteFPROperation(lldb::tid_t tid, void *buf, bool &result)
@@ -508,7 +508,7 @@ void WriteFPROperation::Execute(ProcessMonitor *monitor) {
//------------------------------------------------------------------------------
/// @class ResumeOperation
-/// @brief Implements ProcessMonitor::Resume.
+/// Implements ProcessMonitor::Resume.
class ResumeOperation : public Operation {
public:
ResumeOperation(uint32_t signo, bool &result)
@@ -539,7 +539,7 @@ void ResumeOperation::Execute(ProcessMonitor *monitor) {
//------------------------------------------------------------------------------
/// @class SingleStepOperation
-/// @brief Implements ProcessMonitor::SingleStep.
+/// Implements ProcessMonitor::SingleStep.
class SingleStepOperation : public Operation {
public:
SingleStepOperation(uint32_t signo, bool &result)
@@ -567,7 +567,7 @@ void SingleStepOperation::Execute(ProcessMonitor *monitor) {
//------------------------------------------------------------------------------
/// @class LwpInfoOperation
-/// @brief Implements ProcessMonitor::GetLwpInfo.
+/// Implements ProcessMonitor::GetLwpInfo.
class LwpInfoOperation : public Operation {
public:
LwpInfoOperation(lldb::tid_t tid, void *info, bool &result, int &ptrace_err)
@@ -596,7 +596,7 @@ void LwpInfoOperation::Execute(ProcessMonitor *monitor) {
//------------------------------------------------------------------------------
/// @class ThreadSuspendOperation
-/// @brief Implements ProcessMonitor::ThreadSuspend.
+/// Implements ProcessMonitor::ThreadSuspend.
class ThreadSuspendOperation : public Operation {
public:
ThreadSuspendOperation(lldb::tid_t tid, bool suspend, bool &result)
@@ -616,7 +616,7 @@ void ThreadSuspendOperation::Execute(ProcessMonitor *monitor) {
//------------------------------------------------------------------------------
/// @class EventMessageOperation
-/// @brief Implements ProcessMonitor::GetEventMessage.
+/// Implements ProcessMonitor::GetEventMessage.
class EventMessageOperation : public Operation {
public:
EventMessageOperation(lldb::tid_t tid, unsigned long *message, bool &result)
@@ -646,7 +646,7 @@ void EventMessageOperation::Execute(ProcessMonitor *monitor) {
//------------------------------------------------------------------------------
/// @class KillOperation
-/// @brief Implements ProcessMonitor::Kill.
+/// Implements ProcessMonitor::Kill.
class KillOperation : public Operation {
public:
KillOperation(bool &result) : m_result(result) {}
@@ -668,7 +668,7 @@ void KillOperation::Execute(ProcessMonitor *monitor) {
//------------------------------------------------------------------------------
/// @class DetachOperation
-/// @brief Implements ProcessMonitor::Detach.
+/// Implements ProcessMonitor::Detach.
class DetachOperation : public Operation {
public:
DetachOperation(Status &result) : m_error(result) {}
@@ -695,13 +695,14 @@ ProcessMonitor::OperationArgs::~OperationArgs() { sem_destroy(&m_semaphore); }
ProcessMonitor::LaunchArgs::LaunchArgs(ProcessMonitor *monitor,
lldb_private::Module *module,
- char const **argv, char const **envp,
+ char const **argv, Environment env,
const FileSpec &stdin_file_spec,
const FileSpec &stdout_file_spec,
const FileSpec &stderr_file_spec,
const FileSpec &working_dir)
- : OperationArgs(monitor), m_module(module), m_argv(argv), m_envp(envp),
- m_stdin_file_spec(stdin_file_spec), m_stdout_file_spec(stdout_file_spec),
+ : OperationArgs(monitor), m_module(module), m_argv(argv),
+ m_env(std::move(env)), m_stdin_file_spec(stdin_file_spec),
+ m_stdout_file_spec(stdout_file_spec),
m_stderr_file_spec(stderr_file_spec), m_working_dir(working_dir) {}
ProcessMonitor::LaunchArgs::~LaunchArgs() {}
@@ -714,11 +715,10 @@ ProcessMonitor::AttachArgs::~AttachArgs() {}
//------------------------------------------------------------------------------
/// The basic design of the ProcessMonitor is built around two threads.
///
-/// One thread (@see SignalThread) simply blocks on a call to waitpid() looking
-/// for changes in the debugee state. When a change is detected a
+/// One thread (@see SignalThread) simply blocks on a call to waitpid()
+/// looking for changes in the debugee state. When a change is detected a
/// ProcessMessage is sent to the associated ProcessFreeBSD instance. This
-/// thread
-/// "drives" state changes in the debugger.
+/// thread "drives" state changes in the debugger.
///
/// The second thread (@see OperationThread) is responsible for two things 1)
/// launching or attaching to the inferior process, and then 2) servicing
@@ -726,7 +726,7 @@ ProcessMonitor::AttachArgs::~AttachArgs() {}
/// on the Operation class for more info as to why this is needed.
ProcessMonitor::ProcessMonitor(
ProcessFreeBSD *process, Module *module, const char *argv[],
- const char *envp[], const FileSpec &stdin_file_spec,
+ Environment env, const FileSpec &stdin_file_spec,
const FileSpec &stdout_file_spec, const FileSpec &stderr_file_spec,
const FileSpec &working_dir,
const lldb_private::ProcessLaunchInfo & /* launch_info */,
@@ -736,7 +736,7 @@ ProcessMonitor::ProcessMonitor(
using namespace std::placeholders;
std::unique_ptr<LaunchArgs> args(
- new LaunchArgs(this, module, argv, envp, stdin_file_spec,
+ new LaunchArgs(this, module, argv, std::move(env), stdin_file_spec,
stdout_file_spec, stderr_file_spec, working_dir));
sem_init(&m_operation_pending, 0, 0);
@@ -837,7 +837,6 @@ bool ProcessMonitor::Launch(LaunchArgs *args) {
ProcessMonitor *monitor = args->m_monitor;
ProcessFreeBSD &process = monitor->GetProcess();
const char **argv = args->m_argv;
- const char **envp = args->m_envp;
const FileSpec &stdin_file_spec = args->m_stdin_file_spec;
const FileSpec &stdout_file_spec = args->m_stdout_file_spec;
const FileSpec &stderr_file_spec = args->m_stderr_file_spec;
@@ -849,8 +848,8 @@ bool ProcessMonitor::Launch(LaunchArgs *args) {
::pid_t pid;
// Propagate the environment if one is not supplied.
- if (envp == NULL || envp[0] == NULL)
- envp = const_cast<const char **>(environ);
+ Environment::Envp envp =
+ (args->m_env.empty() ? Host::GetEnvironment() : args->m_env).getEnvp();
if ((pid = terminal.Fork(err_str, err_len)) == -1) {
args->m_error.SetErrorToGenericError();
@@ -875,9 +874,9 @@ bool ProcessMonitor::Launch(LaunchArgs *args) {
if (PTRACE(PT_TRACE_ME, 0, NULL, 0) < 0)
exit(ePtraceFailed);
- // terminal has already dupped the tty descriptors to stdin/out/err.
- // This closes original fd from which they were copied (and avoids
- // leaking descriptors to the debugged process.
+ // terminal has already dupped the tty descriptors to stdin/out/err. This
+ // closes original fd from which they were copied (and avoids leaking
+ // descriptors to the debugged process.
terminal.CloseSlaveFileDescriptor();
// Do not inherit setgid powers.
@@ -908,8 +907,7 @@ bool ProcessMonitor::Launch(LaunchArgs *args) {
exit(eChdirFailed);
// Execute. We should never return.
- execve(argv[0], const_cast<char *const *>(argv),
- const_cast<char *const *>(envp));
+ execve(argv[0], const_cast<char *const *>(argv), envp);
exit(eExecFailed);
}
@@ -1103,9 +1101,9 @@ ProcessMessage ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor,
break;
case (SIGTRAP /* | (PTRACE_EVENT_EXIT << 8) */): {
- // The inferior process is about to exit. Maintain the process in a
- // state of "limbo" until we are explicitly commanded to detach,
- // destroy, resume, etc.
+ // The inferior process is about to exit. Maintain the process in a state
+ // of "limbo" until we are explicitly commanded to detach, destroy, resume,
+ // etc.
unsigned long data = 0;
if (!monitor->GetEventMessage(tid, &data))
data = -1;
@@ -1160,8 +1158,8 @@ ProcessMessage ProcessMonitor::MonitorSignal(ProcessMonitor *monitor,
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
// POSIX says that process behaviour is undefined after it ignores a SIGFPE,
- // SIGILL, SIGSEGV, or SIGBUS *unless* that signal was generated by a
- // kill(2) or raise(3). Similarly for tgkill(2) on FreeBSD.
+ // SIGILL, SIGSEGV, or SIGBUS *unless* that signal was generated by a kill(2)
+ // or raise(3). Similarly for tgkill(2) on FreeBSD.
//
// IOW, user generated signals never generate what we consider to be a
// "crash".
@@ -1197,8 +1195,8 @@ ProcessMessage ProcessMonitor::MonitorSignal(ProcessMonitor *monitor,
} // else; Use atleast si_signo info for other si_code
}
- // Everything else is "normal" and does not require any special action on
- // our part.
+ // Everything else is "normal" and does not require any special action on our
+ // part.
return ProcessMessage::Signal(tid, signo);
}
@@ -1424,14 +1422,14 @@ void ProcessMonitor::StopMonitor() {
}
// FIXME: On Linux, when a new thread is created, we receive to notifications,
-// (1) a SIGTRAP|PTRACE_EVENT_CLONE from the main process thread with the
-// child thread id as additional information, and (2) a SIGSTOP|SI_USER from
-// the new child thread indicating that it has is stopped because we attached.
-// We have no guarantee of the order in which these arrive, but we need both
-// before we are ready to proceed. We currently keep a list of threads which
-// have sent the initial SIGSTOP|SI_USER event. Then when we receive the
-// SIGTRAP|PTRACE_EVENT_CLONE notification, if the initial stop has not occurred
-// we call ProcessMonitor::WaitForInitialTIDStop() to wait for it.
+// (1) a SIGTRAP|PTRACE_EVENT_CLONE from the main process thread with the child
+// thread id as additional information, and (2) a SIGSTOP|SI_USER from the new
+// child thread indicating that it has is stopped because we attached. We have
+// no guarantee of the order in which these arrive, but we need both before we
+// are ready to proceed. We currently keep a list of threads which have sent
+// the initial SIGSTOP|SI_USER event. Then when we receive the
+// SIGTRAP|PTRACE_EVENT_CLONE notification, if the initial stop has not
+// occurred we call ProcessMonitor::WaitForInitialTIDStop() to wait for it.
//
// Right now, the above logic is in ProcessPOSIX, so we need a definition of
// this function in the FreeBSD ProcessMonitor implementation even if it isn't
diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.h b/source/Plugins/Process/FreeBSD/ProcessMonitor.h
index 0963453a31b1..1d3e2d746fa9 100644
--- a/source/Plugins/Process/FreeBSD/ProcessMonitor.h
+++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.h
@@ -32,10 +32,10 @@ class ProcessFreeBSD;
class Operation;
/// @class ProcessMonitor
-/// @brief Manages communication with the inferior (debugee) process.
+/// Manages communication with the inferior (debugee) process.
///
-/// Upon construction, this class prepares and launches an inferior process for
-/// debugging.
+/// Upon construction, this class prepares and launches an inferior process
+/// for debugging.
///
/// Changes in the inferior process state are propagated to the associated
/// ProcessFreeBSD instance by calling ProcessFreeBSD::SendMessage with the
@@ -48,7 +48,7 @@ public:
/// Launches an inferior process ready for debugging. Forms the
/// implementation of Process::DoLaunch.
ProcessMonitor(ProcessFreeBSD *process, lldb_private::Module *module,
- char const *argv[], char const *envp[],
+ char const *argv[], lldb_private::Environment env,
const lldb_private::FileSpec &stdin_file_spec,
const lldb_private::FileSpec &stdout_file_spec,
const lldb_private::FileSpec &stderr_file_spec,
@@ -74,8 +74,7 @@ public:
/// standard error of this debugee. Even if stderr and stdout were
/// redirected on launch it may still happen that data is available on this
/// descriptor (if the inferior process opens /dev/tty, for example). This
- /// descriptor is
- /// closed after a call to StopMonitor().
+ /// descriptor is closed after a call to StopMonitor().
///
/// If this monitor was attached to an existing process this method returns
/// -1.
@@ -95,8 +94,8 @@ public:
size_t WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
lldb_private::Status &error);
- /// Reads the contents from the register identified by the given (architecture
- /// dependent) offset.
+ /// Reads the contents from the register identified by the given
+ /// (architecture dependent) offset.
///
/// This method is provided for use by RegisterContextFreeBSD derivatives.
bool ReadRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name,
@@ -215,11 +214,11 @@ private:
/// @class LauchArgs
///
- /// @brief Simple structure to pass data to the thread responsible for
- /// launching a child process.
+ /// Simple structure to pass data to the thread responsible for launching a
+ /// child process.
struct LaunchArgs : OperationArgs {
LaunchArgs(ProcessMonitor *monitor, lldb_private::Module *module,
- char const **argv, char const **envp,
+ char const **argv, lldb_private::Environment env,
const lldb_private::FileSpec &stdin_file_spec,
const lldb_private::FileSpec &stdout_file_spec,
const lldb_private::FileSpec &stderr_file_spec,
@@ -229,7 +228,7 @@ private:
lldb_private::Module *m_module; // The executable image to launch.
char const **m_argv; // Process arguments.
- char const **m_envp; // Process environment.
+ lldb_private::Environment m_env; // Process environment.
const lldb_private::FileSpec m_stdin_file_spec; // Redirect stdin or empty.
const lldb_private::FileSpec
m_stdout_file_spec; // Redirect stdout or empty.
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h b/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h
index 4ff5121bac13..b1b44e71de46 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h
@@ -13,14 +13,14 @@
// C Includes
// C++ Includes
// Other libraries and framework includes
-#include "RegisterInfoInterface.h"
+#include "Plugins/Process/Utility/RegisterInfoInterface.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/ArchSpec.h"
//------------------------------------------------------------------------------
/// @class POSIXBreakpointProtocol
///
-/// @brief Extends RegisterClass with a few virtual operations useful on POSIX.
+/// Extends RegisterClass with a few virtual operations useful on POSIX.
class POSIXBreakpointProtocol {
public:
POSIXBreakpointProtocol() { m_watchpoints_initialized = false; }
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp
index 59d42b9ad72e..8ddc253aea5d 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp
@@ -14,7 +14,7 @@
#include "ProcessFreeBSD.h"
#include "ProcessMonitor.h"
#include "RegisterContextPOSIXProcessMonitor_arm.h"
-#include "RegisterContextPOSIX_arm.h"
+#include "Plugins/Process/Utility/RegisterContextPOSIX_arm.h"
using namespace lldb_private;
using namespace lldb;
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp
index b911ee222015..734167e1fc98 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp
@@ -130,14 +130,14 @@ bool RegisterContextPOSIXProcessMonitor_mips64::ReadRegister(
bool success = ReadRegister(full_reg, value);
if (success) {
- // If our read was not aligned (for ah,bh,ch,dh), shift our returned value
- // one byte to the right.
+ // If our read was not aligned (for ah,bh,ch,dh), shift our returned
+ // value one byte to the right.
if (is_subreg && (reg_info->byte_offset & 0x1))
value.SetUInt64(value.GetAsUInt64() >> 8);
// If our return byte size was greater than the return value reg size,
- // then
- // use the type specified by reg_info rather than the uint64_t default
+ // then use the type specified by reg_info rather than the uint64_t
+ // default
if (value.GetByteSize() > reg_info->byte_size)
value.SetType(reg_info);
}
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp
index bc1d4df89fc8..5cc6cd290629 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp
@@ -14,7 +14,7 @@
#include "ProcessFreeBSD.h"
#include "ProcessMonitor.h"
#include "RegisterContextPOSIXProcessMonitor_powerpc.h"
-#include "RegisterContextPOSIX_powerpc.h"
+#include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h"
using namespace lldb_private;
using namespace lldb;
@@ -140,8 +140,8 @@ bool RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(
if (success) {
// If our return byte size was greater than the return value reg size,
- // then
- // use the type specified by reg_info rather than the uint64_t default
+ // then use the type specified by reg_info rather than the uint64_t
+ // default
if (value.GetByteSize() > reg_info->byte_size)
value.SetType(reg_info);
}
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
index 4608520dba40..7db7f803b371 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
@@ -193,14 +193,14 @@ bool RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(
bool success = ReadRegister(full_reg, value);
if (success) {
- // If our read was not aligned (for ah,bh,ch,dh), shift our returned value
- // one byte to the right.
+ // If our read was not aligned (for ah,bh,ch,dh), shift our returned
+ // value one byte to the right.
if (is_subreg && (reg_info->byte_offset & 0x1))
value.SetUInt64(value.GetAsUInt64() >> 8);
// If our return byte size was greater than the return value reg size,
- // then
- // use the type specified by reg_info rather than the uint64_t default
+ // then use the type specified by reg_info rather than the uint64_t
+ // default
if (value.GetByteSize() > reg_info->byte_size)
value.SetType(reg_info);
}
@@ -221,7 +221,8 @@ bool RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(
value.SetBytes(m_fpr.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
reg_info->byte_size, byte_order);
if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
- // Concatenate ymm using the register halves in xmm.bytes and ymmh.bytes
+ // Concatenate ymm using the register halves in xmm.bytes and
+ // ymmh.bytes
if (GetFPRType() == eXSAVE && CopyXSTATEtoYMM(reg, byte_order))
value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
reg_info->byte_size, byte_order);
@@ -233,11 +234,10 @@ bool RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(
return false;
}
- // Get pointer to m_fpr.fxsave variable and set the data from it.
- // Byte offsets of all registers are calculated wrt 'UserArea' structure.
- // However, ReadFPR() reads fpu registers {using ptrace(PT_GETFPREGS,..)}
- // and stores them in 'm_fpr' (of type FPR structure). To extract values of
- // fpu
+ // Get pointer to m_fpr.fxsave variable and set the data from it. Byte
+ // offsets of all registers are calculated wrt 'UserArea' structure. However,
+ // ReadFPR() reads fpu registers {using ptrace(PT_GETFPREGS,..)} and stores
+ // them in 'm_fpr' (of type FPR structure). To extract values of fpu
// registers, m_fpr should be read at byte offsets calculated wrt to FPR
// structure.
@@ -299,12 +299,12 @@ bool RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(
return false;
}
} else {
- // Get pointer to m_fpr.fxsave variable and set the data to it.
- // Byte offsets of all registers are calculated wrt 'UserArea' structure.
- // However, WriteFPR() takes m_fpr (of type FPR structure) and writes only
- // fpu
- // registers using ptrace(PT_SETFPREGS,..) API. Hence fpu registers should
- // be written in m_fpr at byte offsets calculated wrt FPR structure.
+ // Get pointer to m_fpr.fxsave variable and set the data to it. Byte
+ // offsets of all registers are calculated wrt 'UserArea' structure.
+ // However, WriteFPR() takes m_fpr (of type FPR structure) and writes
+ // only fpu registers using ptrace(PT_SETFPREGS,..) API. Hence fpu
+ // registers should be written in m_fpr at byte offsets calculated wrt
+ // FPR structure.
// Since, FPR structure is also one of the member of UserArea structure.
// byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
diff --git a/source/Plugins/Process/Linux/CMakeLists.txt b/source/Plugins/Process/Linux/CMakeLists.txt
index 390dbd9ff8bf..b4b4c401a271 100644
--- a/source/Plugins/Process/Linux/CMakeLists.txt
+++ b/source/Plugins/Process/Linux/CMakeLists.txt
@@ -1,7 +1,3 @@
-include_directories(.)
-include_directories(../POSIX)
-include_directories(../Utility)
-
add_lldb_library(lldbPluginProcessLinux PLUGIN
NativeProcessLinux.cpp
NativeRegisterContextLinux.cpp
diff --git a/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index 136af361af29..3fb886e1c7a3 100644
--- a/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -245,13 +245,15 @@ NativeProcessLinux::Factory::Launch(ProcessLaunchInfo &launch_info,
}
LLDB_LOG(log, "inferior started, now in stopped state");
- ArchSpec arch;
- if ((status = ResolveProcessArchitecture(pid, arch)).Fail())
- return status.ToError();
+ ProcessInstanceInfo Info;
+ if (!Host::GetProcessInfo(pid, Info)) {
+ return llvm::make_error<StringError>("Cannot get process architecture",
+ llvm::inconvertibleErrorCode());
+ }
// Set the architecture to the exe architecture.
LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid,
- arch.GetArchitectureName());
+ Info.GetArchitecture().GetArchitectureName());
status = SetDefaultPtraceOpts(pid);
if (status.Fail()) {
@@ -261,7 +263,7 @@ NativeProcessLinux::Factory::Launch(ProcessLaunchInfo &launch_info,
return std::unique_ptr<NativeProcessLinux>(new NativeProcessLinux(
pid, launch_info.GetPTY().ReleaseMasterFileDescriptor(), native_delegate,
- arch, mainloop, {pid}));
+ Info.GetArchitecture(), mainloop, {pid}));
}
llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
@@ -272,17 +274,18 @@ NativeProcessLinux::Factory::Attach(
LLDB_LOG(log, "pid = {0:x}", pid);
// Retrieve the architecture for the running process.
- ArchSpec arch;
- Status status = ResolveProcessArchitecture(pid, arch);
- if (!status.Success())
- return status.ToError();
+ ProcessInstanceInfo Info;
+ if (!Host::GetProcessInfo(pid, Info)) {
+ return llvm::make_error<StringError>("Cannot get process architecture",
+ llvm::inconvertibleErrorCode());
+ }
auto tids_or = NativeProcessLinux::Attach(pid);
if (!tids_or)
return tids_or.takeError();
return std::unique_ptr<NativeProcessLinux>(new NativeProcessLinux(
- pid, -1, native_delegate, arch, mainloop, *tids_or));
+ pid, -1, native_delegate, Info.GetArchitecture(), mainloop, *tids_or));
}
// -----------------------------------------------------------------------------
@@ -334,8 +337,8 @@ llvm::Expected<std::vector<::pid_t>> NativeProcessLinux::Attach(::pid_t pid) {
// Attach to the requested process.
// An attach will cause the thread to stop with a SIGSTOP.
if ((status = PtraceWrapper(PTRACE_ATTACH, tid)).Fail()) {
- // No such thread. The thread may have exited.
- // More error handling may be needed.
+ // No such thread. The thread may have exited. More error handling
+ // may be needed.
if (status.GetError() == ESRCH) {
it = tids_to_attach.erase(it);
continue;
@@ -345,11 +348,11 @@ llvm::Expected<std::vector<::pid_t>> NativeProcessLinux::Attach(::pid_t pid) {
int wpid =
llvm::sys::RetryAfterSignal(-1, ::waitpid, tid, nullptr, __WALL);
- // Need to use __WALL otherwise we receive an error with errno=ECHLD
- // At this point we should have a thread stopped if waitpid succeeds.
+ // Need to use __WALL otherwise we receive an error with errno=ECHLD At
+ // this point we should have a thread stopped if waitpid succeeds.
if (wpid < 0) {
- // No such thread. The thread may have exited.
- // More error handling may be needed.
+ // No such thread. The thread may have exited. More error handling
+ // may be needed.
if (errno == ESRCH) {
it = tids_to_attach.erase(it);
continue;
@@ -394,8 +397,8 @@ Status NativeProcessLinux::SetDefaultPtraceOpts(lldb::pid_t pid) {
// appropriate ptrace flags here (PTRACE_O_TRACEFORK, PTRACE_O_TRACEVFORK)
ptrace_opts |= PTRACE_O_TRACECLONE;
- // Have the tracer notify us before execve returns
- // (needed to disable legacy SIGTRAP generation)
+ // Have the tracer notify us before execve returns (needed to disable legacy
+ // SIGTRAP generation)
ptrace_opts |= PTRACE_O_TRACEEXEC;
return PtraceWrapper(PTRACE_SETOPTIONS, pid, nullptr, (void *)ptrace_opts);
@@ -435,8 +438,8 @@ void NativeProcessLinux::MonitorCallback(lldb::pid_t pid, bool exited,
auto thread_sp = GetThreadByID(pid);
if (!thread_sp) {
- // Normally, the only situation when we cannot find the thread is if we have
- // just received a new thread notification. This is indicated by
+ // Normally, the only situation when we cannot find the thread is if we
+ // have just received a new thread notification. This is indicated by
// GetSignalInfo() returning si_code == SI_USER and si_pid == 0
LLDB_LOG(log, "received notification about an unknown tid {0}.", pid);
@@ -468,15 +471,15 @@ void NativeProcessLinux::MonitorCallback(lldb::pid_t pid, bool exited,
MonitorSignal(info, *thread_sp, exited);
} else {
if (info_err.GetError() == EINVAL) {
- // This is a group stop reception for this tid.
- // We can reach here if we reinject SIGSTOP, SIGSTP, SIGTTIN or SIGTTOU
- // into the tracee, triggering the group-stop mechanism. Normally
- // receiving these would stop the process, pending a SIGCONT. Simulating
- // this state in a debugger is hard and is generally not needed (one use
- // case is debugging background task being managed by a shell). For
- // general use, it is sufficient to stop the process in a signal-delivery
- // stop which happens before the group stop. This done by MonitorSignal
- // and works correctly for all signals.
+ // This is a group stop reception for this tid. We can reach here if we
+ // reinject SIGSTOP, SIGSTP, SIGTTIN or SIGTTOU into the tracee,
+ // triggering the group-stop mechanism. Normally receiving these would
+ // stop the process, pending a SIGCONT. Simulating this state in a
+ // debugger is hard and is generally not needed (one use case is
+ // debugging background task being managed by a shell). For general use,
+ // it is sufficient to stop the process in a signal-delivery stop which
+ // happens before the group stop. This done by MonitorSignal and works
+ // correctly for all signals.
LLDB_LOG(log,
"received a group stop for pid {0} tid {1}. Transparent "
"handling of group stops not supported, resuming the "
@@ -502,8 +505,8 @@ void NativeProcessLinux::MonitorCallback(lldb::pid_t pid, bool exited,
if (is_main_thread) {
// Notify the delegate - our process is not available but appears to
- // have been killed outside
- // our control. Is eStateExited the right exit state in this case?
+ // have been killed outside our control. Is eStateExited the right
+ // exit state in this case?
SetExitStatus(status, true);
SetState(StateType::eStateExited, true);
} else {
@@ -572,19 +575,14 @@ void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
switch (info.si_code) {
// TODO: these two cases are required if we want to support tracing of the
- // inferiors' children. We'd need this to debug a monitor.
- // case (SIGTRAP | (PTRACE_EVENT_FORK << 8)):
- // case (SIGTRAP | (PTRACE_EVENT_VFORK << 8)):
+ // inferiors' children. We'd need this to debug a monitor. case (SIGTRAP |
+ // (PTRACE_EVENT_FORK << 8)): case (SIGTRAP | (PTRACE_EVENT_VFORK << 8)):
case (SIGTRAP | (PTRACE_EVENT_CLONE << 8)): {
// This is the notification on the parent thread which informs us of new
- // thread
- // creation.
- // We don't want to do anything with the parent thread so we just resume it.
- // In case we
- // want to implement "break on thread creation" functionality, we would need
- // to stop
- // here.
+ // thread creation. We don't want to do anything with the parent thread so
+ // we just resume it. In case we want to implement "break on thread
+ // creation" functionality, we would need to stop here.
unsigned long event_message = 0;
if (GetEventMessage(thread.GetID(), &event_message).Fail()) {
@@ -634,10 +632,10 @@ void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
}
case (SIGTRAP | (PTRACE_EVENT_EXIT << 8)): {
- // The inferior process or one of its threads is about to exit.
- // We don't want to do anything with the thread so we just resume it. In
- // case we want to implement "break on thread exit" functionality, we would
- // need to stop here.
+ // The inferior process or one of its threads is about to exit. We don't
+ // want to do anything with the thread so we just resume it. In case we
+ // want to implement "break on thread exit" functionality, we would need to
+ // stop here.
unsigned long data = 0;
if (GetEventMessage(thread.GetID(), &data).Fail())
@@ -655,8 +653,8 @@ void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
// Due to a kernel bug, we may sometimes get this stop after the inferior
// gets a SIGKILL. This confuses our state tracking logic in
// ResumeThread(), since normally, we should not be receiving any ptrace
- // events while the inferior is stopped. This makes sure that the inferior
- // is resumed and exits normally.
+ // events while the inferior is stopped. This makes sure that the
+ // inferior is resumed and exits normally.
state = eStateRunning;
}
ResumeThread(thread, state, LLDB_INVALID_SIGNAL_NUMBER);
@@ -702,8 +700,8 @@ void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
case SI_KERNEL:
#if defined __mips__
- // For mips there is no special signal for watchpoint
- // So we check for watchpoint in kernel trap
+ // For mips there is no special signal for watchpoint So we check for
+ // watchpoint in kernel trap
{
// If a watchpoint was hit, report it
uint32_t wp_index;
@@ -779,8 +777,8 @@ void NativeProcessLinux::MonitorWatchpoint(NativeThreadLinux &thread,
LLDB_LOG(log, "received watchpoint event, pid = {0}, wp_index = {1}",
thread.GetID(), wp_index);
- // Mark the thread as stopped at watchpoint.
- // The address is at (lldb::addr_t)info->si_addr if we need it.
+ // Mark the thread as stopped at watchpoint. The address is at
+ // (lldb::addr_t)info->si_addr if we need it.
thread.SetStoppedByWatchpoint(wp_index);
// We need to tell all other running threads before we notify the delegate
@@ -796,8 +794,8 @@ void NativeProcessLinux::MonitorSignal(const siginfo_t &info,
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
// POSIX says that process behaviour is undefined after it ignores a SIGFPE,
- // SIGILL, SIGSEGV, or SIGBUS *unless* that signal was generated by a
- // kill(2) or raise(3). Similarly for tgkill(2) on Linux.
+ // SIGILL, SIGSEGV, or SIGBUS *unless* that signal was generated by a kill(2)
+ // or raise(3). Similarly for tgkill(2) on Linux.
//
// IOW, user generated signals never generate what we consider to be a
// "crash".
@@ -816,22 +814,22 @@ void NativeProcessLinux::MonitorSignal(const siginfo_t &info,
// This is a tgkill()-based stop.
LLDB_LOG(log, "pid {0} tid {1}, thread stopped", GetID(), thread.GetID());
- // Check that we're not already marked with a stop reason.
- // Note this thread really shouldn't already be marked as stopped - if we
- // were, that would imply that the kernel signaled us with the thread
- // stopping which we handled and marked as stopped, and that, without an
- // intervening resume, we received another stop. It is more likely that we
- // are missing the marking of a run state somewhere if we find that the
- // thread was marked as stopped.
+ // Check that we're not already marked with a stop reason. Note this thread
+ // really shouldn't already be marked as stopped - if we were, that would
+ // imply that the kernel signaled us with the thread stopping which we
+ // handled and marked as stopped, and that, without an intervening resume,
+ // we received another stop. It is more likely that we are missing the
+ // marking of a run state somewhere if we find that the thread was marked
+ // as stopped.
const StateType thread_state = thread.GetState();
if (!StateIsStoppedState(thread_state, false)) {
// An inferior thread has stopped because of a SIGSTOP we have sent it.
// Generally, these are not important stops and we don't want to report
// them as they are just used to stop other threads when one thread (the
// one with the *real* stop reason) hits a breakpoint (watchpoint,
- // etc...). However, in the case of an asynchronous Interrupt(), this *is*
- // the real stop reason, so we leave the signal intact if this is the
- // thread that was chosen as the triggering thread.
+ // etc...). However, in the case of an asynchronous Interrupt(), this
+ // *is* the real stop reason, so we leave the signal intact if this is
+ // the thread that was chosen as the triggering thread.
if (m_pending_notification_tid != LLDB_INVALID_THREAD_ID) {
if (m_pending_notification_tid == thread.GetID())
thread.SetStoppedBySignal(SIGSTOP, &info);
@@ -860,8 +858,8 @@ void NativeProcessLinux::MonitorSignal(const siginfo_t &info,
return;
}
- // Check if debugger should stop at this signal or just ignore it
- // and resume the inferior.
+ // Check if debugger should stop at this signal or just ignore it and resume
+ // the inferior.
if (m_signals_to_ignore.find(signo) != m_signals_to_ignore.end()) {
ResumeThread(thread, thread.GetState(), signo);
return;
@@ -912,9 +910,9 @@ static bool ReadRegisterCallback(EmulateInstruction *instruction, void *baton,
return true;
}
- // The emulator only fill in the dwarf regsiter numbers (and in some case
- // the generic register numbers). Get the full register info from the
- // register context based on the dwarf register numbers.
+ // The emulator only fill in the dwarf regsiter numbers (and in some case the
+ // generic register numbers). Get the full register info from the register
+ // context based on the dwarf register numbers.
const RegisterInfo *full_reg_info =
emulator_baton->m_reg_context.GetRegisterInfo(
eRegisterKindDWARF, reg_info->kinds[eRegisterKindDWARF]);
@@ -998,8 +996,8 @@ NativeProcessLinux::SetupSoftwareSingleStepping(NativeThreadLinux &thread) {
else
next_flags = ReadFlags(register_context);
} else if (pc_it == baton.m_register_values.end()) {
- // Emulate instruction failed and it haven't changed PC. Advance PC
- // with the size of the current opcode because the emulation of all
+ // Emulate instruction failed and it haven't changed PC. Advance PC with
+ // the size of the current opcode because the emulation of all
// PC modifying instruction should be successful. The failure most
// likely caused by a not supported instruction which don't modify PC.
next_pc = register_context.GetPC() + emulator_ap->GetOpcode().GetByteSize();
@@ -1030,8 +1028,8 @@ NativeProcessLinux::SetupSoftwareSingleStepping(NativeThreadLinux &thread) {
error = SetSoftwareBreakpoint(next_pc, 0);
}
- // If setting the breakpoint fails because next_pc is out of
- // the address space, ignore it and let the debugee segfault.
+ // If setting the breakpoint fails because next_pc is out of the address
+ // space, ignore it and let the debugee segfault.
if (error.GetError() == EIO || error.GetError() == EFAULT) {
return Status();
} else if (error.Fail())
@@ -1162,8 +1160,8 @@ Status NativeProcessLinux::Signal(int signo) {
}
Status NativeProcessLinux::Interrupt() {
- // Pick a running thread (or if none, a not-dead stopped thread) as
- // the chosen thread that will be the stop-reason thread.
+ // Pick a running thread (or if none, a not-dead stopped thread) as the
+ // chosen thread that will be the stop-reason thread.
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
NativeThreadProtocol *running_thread = nullptr;
@@ -1171,15 +1169,15 @@ Status NativeProcessLinux::Interrupt() {
LLDB_LOG(log, "selecting running thread for interrupt target");
for (const auto &thread : m_threads) {
- // If we have a running or stepping thread, we'll call that the
- // target of the interrupt.
+ // If we have a running or stepping thread, we'll call that the target of
+ // the interrupt.
const auto thread_state = thread->GetState();
if (thread_state == eStateRunning || thread_state == eStateStepping) {
running_thread = thread.get();
break;
} else if (!stopped_thread && StateIsStoppedState(thread_state, true)) {
- // Remember the first non-dead stopped thread. We'll use that as a backup
- // if there are no running threads.
+ // Remember the first non-dead stopped thread. We'll use that as a
+ // backup if there are no running threads.
stopped_thread = thread.get();
}
}
@@ -1248,9 +1246,8 @@ ParseMemoryRegionInfoFromProcMapsLine(llvm::StringRef &maps_line,
StringExtractor line_extractor(maps_line);
// Format: {address_start_hex}-{address_end_hex} perms offset dev inode
- // pathname
- // perms: rwxp (letter is present if set, '-' if not, final character is
- // p=private, s=shared).
+ // pathname perms: rwxp (letter is present if set, '-' if not, final
+ // character is p=private, s=shared).
// Parse out the starting address
lldb::addr_t start_address = line_extractor.GetHexMaxU64(false, 0);
@@ -1331,8 +1328,8 @@ Status NativeProcessLinux::GetMemoryRegionInfo(lldb::addr_t load_addr,
// the virtual address space,
// with no perms if it is not mapped.
- // Use an approach that reads memory regions from /proc/{pid}/maps.
- // Assume proc maps entries are in ascending order.
+ // Use an approach that reads memory regions from /proc/{pid}/maps. Assume
+ // proc maps entries are in ascending order.
// FIXME assert if we find differently.
if (m_supports_mem_region == LazyBool::eLazyBoolNo) {
@@ -1383,10 +1380,8 @@ Status NativeProcessLinux::GetMemoryRegionInfo(lldb::addr_t load_addr,
}
// If we made it here, we didn't find an entry that contained the given
- // address. Return the
- // load_addr as start and the amount of bytes betwwen load address and the end
- // of the memory as
- // size.
+ // address. Return the load_addr as start and the amount of bytes betwwen
+ // load address and the end of the memory as size.
range_info.GetRange().SetRangeBase(load_addr);
range_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
range_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
@@ -1431,8 +1426,8 @@ Status NativeProcessLinux::PopulateMemoryRegionCache() {
if (m_mem_region_cache.empty()) {
// No entries after attempting to read them. This shouldn't happen if
- // /proc/{pid}/maps is supported. Assume we don't support map entries
- // via procfs.
+ // /proc/{pid}/maps is supported. Assume we don't support map entries via
+ // procfs.
m_supports_mem_region = LazyBool::eLazyBoolNo;
LLDB_LOG(log,
"failed to find any procfs maps entries, assuming no support "
@@ -1459,8 +1454,8 @@ void NativeProcessLinux::DoStopIDBumped(uint32_t newBumpId) {
Status NativeProcessLinux::AllocateMemory(size_t size, uint32_t permissions,
lldb::addr_t &addr) {
// FIXME implementing this requires the equivalent of
-// InferiorCallPOSIX::InferiorCallMmap, which depends on
-// functional ThreadPlans working with Native*Protocol.
+// InferiorCallPOSIX::InferiorCallMmap, which depends on functional ThreadPlans
+// working with Native*Protocol.
#if 1
return Status("not implemented yet");
#else
@@ -1475,8 +1470,7 @@ Status NativeProcessLinux::AllocateMemory(size_t size, uint32_t permissions,
prot |= eMmapProtExec;
// TODO implement this directly in NativeProcessLinux
- // (and lift to NativeProcessPOSIX if/when that class is
- // refactored out).
+ // (and lift to NativeProcessPOSIX if/when that class is refactored out).
if (InferiorCallMmap(this, addr, 0, size, prot,
eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
m_addr_to_mmap_size[addr] = size;
@@ -1502,10 +1496,9 @@ lldb::addr_t NativeProcessLinux::GetSharedLibraryInfoAddress() {
}
size_t NativeProcessLinux::UpdateThreads() {
- // The NativeProcessLinux monitoring threads are always up to date
- // with respect to thread state and they keep the thread list
- // populated properly. All this method needs to do is return the
- // thread count.
+ // The NativeProcessLinux monitoring threads are always up to date with
+ // respect to thread state and they keep the thread list populated properly.
+ // All this method needs to do is return the thread count.
return m_threads.size();
}
@@ -1515,7 +1508,6 @@ Status NativeProcessLinux::GetSoftwareBreakpointPCOffset(
// set per architecture. Need ARM, MIPS support here.
static const uint8_t g_i386_opcode[] = {0xCC};
static const uint8_t g_s390x_opcode[] = {0x00, 0x01};
- static const uint8_t g_ppc64le_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap
switch (m_arch.GetMachine()) {
case llvm::Triple::x86:
@@ -1527,16 +1519,13 @@ Status NativeProcessLinux::GetSoftwareBreakpointPCOffset(
actual_opcode_size = static_cast<uint32_t>(sizeof(g_s390x_opcode));
return Status();
- case llvm::Triple::ppc64le:
- actual_opcode_size = static_cast<uint32_t>(sizeof(g_ppc64le_opcode));
- return Status();
-
case llvm::Triple::arm:
case llvm::Triple::aarch64:
case llvm::Triple::mips64:
case llvm::Triple::mips64el:
case llvm::Triple::mips:
case llvm::Triple::mipsel:
+ case llvm::Triple::ppc64le:
// On these architectures the PC don't get updated for breakpoint hits
actual_opcode_size = 0;
return Status();
@@ -1633,161 +1622,11 @@ Status NativeProcessLinux::GetSoftwareBreakpointTrapOpcode(
}
}
-#if 0
-ProcessMessage::CrashReason
-NativeProcessLinux::GetCrashReasonForSIGSEGV(const siginfo_t *info)
-{
- ProcessMessage::CrashReason reason;
- assert(info->si_signo == SIGSEGV);
-
- reason = ProcessMessage::eInvalidCrashReason;
-
- switch (info->si_code)
- {
- default:
- assert(false && "unexpected si_code for SIGSEGV");
- break;
- case SI_KERNEL:
- // Linux will occasionally send spurious SI_KERNEL codes.
- // (this is poorly documented in sigaction)
- // One way to get this is via unaligned SIMD loads.
- reason = ProcessMessage::eInvalidAddress; // for lack of anything better
- break;
- case SEGV_MAPERR:
- reason = ProcessMessage::eInvalidAddress;
- break;
- case SEGV_ACCERR:
- reason = ProcessMessage::ePrivilegedAddress;
- break;
- }
-
- return reason;
-}
-#endif
-
-#if 0
-ProcessMessage::CrashReason
-NativeProcessLinux::GetCrashReasonForSIGILL(const siginfo_t *info)
-{
- ProcessMessage::CrashReason reason;
- assert(info->si_signo == SIGILL);
-
- reason = ProcessMessage::eInvalidCrashReason;
-
- switch (info->si_code)
- {
- default:
- assert(false && "unexpected si_code for SIGILL");
- break;
- case ILL_ILLOPC:
- reason = ProcessMessage::eIllegalOpcode;
- break;
- case ILL_ILLOPN:
- reason = ProcessMessage::eIllegalOperand;
- break;
- case ILL_ILLADR:
- reason = ProcessMessage::eIllegalAddressingMode;
- break;
- case ILL_ILLTRP:
- reason = ProcessMessage::eIllegalTrap;
- break;
- case ILL_PRVOPC:
- reason = ProcessMessage::ePrivilegedOpcode;
- break;
- case ILL_PRVREG:
- reason = ProcessMessage::ePrivilegedRegister;
- break;
- case ILL_COPROC:
- reason = ProcessMessage::eCoprocessorError;
- break;
- case ILL_BADSTK:
- reason = ProcessMessage::eInternalStackError;
- break;
- }
-
- return reason;
-}
-#endif
-
-#if 0
-ProcessMessage::CrashReason
-NativeProcessLinux::GetCrashReasonForSIGFPE(const siginfo_t *info)
-{
- ProcessMessage::CrashReason reason;
- assert(info->si_signo == SIGFPE);
-
- reason = ProcessMessage::eInvalidCrashReason;
-
- switch (info->si_code)
- {
- default:
- assert(false && "unexpected si_code for SIGFPE");
- break;
- case FPE_INTDIV:
- reason = ProcessMessage::eIntegerDivideByZero;
- break;
- case FPE_INTOVF:
- reason = ProcessMessage::eIntegerOverflow;
- break;
- case FPE_FLTDIV:
- reason = ProcessMessage::eFloatDivideByZero;
- break;
- case FPE_FLTOVF:
- reason = ProcessMessage::eFloatOverflow;
- break;
- case FPE_FLTUND:
- reason = ProcessMessage::eFloatUnderflow;
- break;
- case FPE_FLTRES:
- reason = ProcessMessage::eFloatInexactResult;
- break;
- case FPE_FLTINV:
- reason = ProcessMessage::eFloatInvalidOperation;
- break;
- case FPE_FLTSUB:
- reason = ProcessMessage::eFloatSubscriptRange;
- break;
- }
-
- return reason;
-}
-#endif
-
-#if 0
-ProcessMessage::CrashReason
-NativeProcessLinux::GetCrashReasonForSIGBUS(const siginfo_t *info)
-{
- ProcessMessage::CrashReason reason;
- assert(info->si_signo == SIGBUS);
-
- reason = ProcessMessage::eInvalidCrashReason;
-
- switch (info->si_code)
- {
- default:
- assert(false && "unexpected si_code for SIGBUS");
- break;
- case BUS_ADRALN:
- reason = ProcessMessage::eIllegalAlignment;
- break;
- case BUS_ADRERR:
- reason = ProcessMessage::eIllegalAddress;
- break;
- case BUS_OBJERR:
- reason = ProcessMessage::eHardwareError;
- break;
- }
-
- return reason;
-}
-#endif
-
Status NativeProcessLinux::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
size_t &bytes_read) {
if (ProcessVmReadvSupported()) {
// The process_vm_readv path is about 50 times faster than ptrace api. We
- // want to use
- // this syscall if it is supported.
+ // want to use this syscall if it is supported.
const ::pid_t pid = GetID();
@@ -2094,12 +1933,11 @@ Status NativeProcessLinux::ResumeThread(NativeThreadLinux &thread,
Log *const log = ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD);
LLDB_LOG(log, "tid: {0}", thread.GetID());
- // Before we do the resume below, first check if we have a pending
- // stop notification that is currently waiting for
- // all threads to stop. This is potentially a buggy situation since
- // we're ostensibly waiting for threads to stop before we send out the
- // pending notification, and here we are resuming one before we send
- // out the pending stop notification.
+ // Before we do the resume below, first check if we have a pending stop
+ // notification that is currently waiting for all threads to stop. This is
+ // potentially a buggy situation since we're ostensibly waiting for threads
+ // to stop before we send out the pending notification, and here we are
+ // resuming one before we send out the pending stop notification.
if (m_pending_notification_tid != LLDB_INVALID_THREAD_ID) {
LLDB_LOG(log,
"about to resume tid {0} per explicit request but we have a "
@@ -2108,8 +1946,8 @@ Status NativeProcessLinux::ResumeThread(NativeThreadLinux &thread,
thread.GetID(), m_pending_notification_tid);
}
- // Request a resume. We expect this to be synchronous and the system
- // to reflect it is running after this completes.
+ // Request a resume. We expect this to be synchronous and the system to
+ // reflect it is running after this completes.
switch (state) {
case eStateRunning: {
const auto resume_result = thread.Resume(signo);
@@ -2138,8 +1976,8 @@ void NativeProcessLinux::StopRunningThreads(const lldb::tid_t triggering_tid) {
m_pending_notification_tid = triggering_tid;
- // Request a stop for all the thread stops that need to be stopped
- // and are not already known to be stopped.
+ // Request a stop for all the thread stops that need to be stopped and are
+ // not already known to be stopped.
for (const auto &thread : m_threads) {
if (StateIsRunningState(thread->GetState()))
static_cast<NativeThreadLinux *>(thread.get())->RequestStop();
@@ -2185,8 +2023,7 @@ void NativeProcessLinux::ThreadWasCreated(NativeThreadLinux &thread) {
if (m_pending_notification_tid != LLDB_INVALID_THREAD_ID &&
StateIsRunningState(thread.GetState())) {
// We will need to wait for this new thread to stop as well before firing
- // the
- // notification.
+ // the notification.
thread.RequestStop();
}
}
@@ -2222,9 +2059,8 @@ void NativeProcessLinux::SigchldHandler() {
}
}
-// Wrapper for ptrace to catch errors and log calls.
-// Note that ptrace sets errno on error because -1 can be a valid result (i.e.
-// for PTRACE_PEEK*)
+// Wrapper for ptrace to catch errors and log calls. Note that ptrace sets
+// errno on error because -1 can be a valid result (i.e. for PTRACE_PEEK*)
Status NativeProcessLinux::PtraceWrapper(int req, lldb::pid_t pid, void *addr,
void *data, size_t data_size,
long *result) {
@@ -2422,8 +2258,8 @@ Status NativeProcessLinux::StopTracingForThread(lldb::tid_t thread) {
}
if (iter->second->GetTraceID() == m_pt_proces_trace_id) {
- // traceid maps to the whole process so we have to erase it from the
- // thread group.
+ // traceid maps to the whole process so we have to erase it from the thread
+ // group.
LLDB_LOG(log, "traceid maps to process");
m_pt_traced_thread_group.erase(thread);
}
@@ -2474,8 +2310,8 @@ Status NativeProcessLinux::StopProcessorTracingOnThread(lldb::user_id_t traceid,
if (thread == LLDB_INVALID_THREAD_ID) {
for (auto& iter : m_processor_trace_monitor) {
if (iter.second->GetTraceID() == traceid) {
- // Stopping a trace instance for an individual thread
- // hence there will only be one traceid that can match.
+ // Stopping a trace instance for an individual thread hence there will
+ // only be one traceid that can match.
m_processor_trace_monitor.erase(iter.first);
return error;
}
@@ -2505,8 +2341,8 @@ Status NativeProcessLinux::StopProcessorTracingOnThread(lldb::user_id_t traceid,
LLDB_LOG(log, "UID - {0} , Thread -{1}", traceid, thread);
if (traceid == m_pt_proces_trace_id) {
- // traceid maps to the whole process so we have to erase it from the
- // thread group.
+ // traceid maps to the whole process so we have to erase it from the thread
+ // group.
LLDB_LOG(log, "traceid maps to process");
m_pt_traced_thread_group.erase(thread);
}
diff --git a/source/Plugins/Process/Linux/NativeProcessLinux.h b/source/Plugins/Process/Linux/NativeProcessLinux.h
index f078c1ac30e2..1c2f786e8d69 100644
--- a/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ b/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -31,10 +31,10 @@ class Scalar;
namespace process_linux {
/// @class NativeProcessLinux
-/// @brief Manages communication with the inferior (debugee) process.
+/// Manages communication with the inferior (debugee) process.
///
-/// Upon construction, this class prepares and launches an inferior process for
-/// debugging.
+/// Upon construction, this class prepares and launches an inferior process
+/// for debugging.
///
/// Changes in the inferior process state are broadcasted.
class NativeProcessLinux : public NativeProcessProtocol {
@@ -184,20 +184,6 @@ private:
Status SetupSoftwareSingleStepping(NativeThreadLinux &thread);
-#if 0
- static ::ProcessMessage::CrashReason
- GetCrashReasonForSIGSEGV(const siginfo_t *info);
-
- static ::ProcessMessage::CrashReason
- GetCrashReasonForSIGILL(const siginfo_t *info);
-
- static ::ProcessMessage::CrashReason
- GetCrashReasonForSIGFPE(const siginfo_t *info);
-
- static ::ProcessMessage::CrashReason
- GetCrashReasonForSIGBUS(const siginfo_t *info);
-#endif
-
bool HasThreadNoLock(lldb::tid_t thread_id);
bool StopTrackingThread(lldb::tid_t thread_id);
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
index cb05416cb6c3..749291684620 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
@@ -184,14 +184,14 @@ NativeRegisterContextLinux_arm::ReadRegister(const RegisterInfo *reg_info,
error = ReadRegisterRaw(full_reg, reg_value);
if (error.Success()) {
- // If our read was not aligned (for ah,bh,ch,dh), shift our returned value
- // one byte to the right.
+ // If our read was not aligned (for ah,bh,ch,dh), shift our returned
+ // value one byte to the right.
if (is_subreg && (reg_info->byte_offset & 0x1))
reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8);
// If our return byte size was greater than the return value reg size,
- // then
- // use the type specified by reg_info rather than the uint64_t default
+ // then use the type specified by reg_info rather than the uint64_t
+ // default
if (reg_value.GetByteSize() > reg_info->byte_size)
reg_value.SetType(reg_info);
}
@@ -558,8 +558,8 @@ uint32_t NativeRegisterContextLinux_arm::SetHardwareWatchpoint(
uint32_t control_value = 0, wp_index = 0, addr_word_offset = 0, byte_mask = 0;
lldb::addr_t real_addr = addr;
- // Check if we are setting watchpoint other than read/write/access
- // Also update watchpoint flag to match Arm write-read bit configuration.
+ // Check if we are setting watchpoint other than read/write/access Also
+ // update watchpoint flag to match Arm write-read bit configuration.
switch (watch_flags) {
case 1:
watch_flags = 2;
@@ -579,9 +579,9 @@ uint32_t NativeRegisterContextLinux_arm::SetHardwareWatchpoint(
if (size == 0 || size > 4)
return LLDB_INVALID_INDEX32;
- // Check 4-byte alignment for hardware watchpoint target address.
- // Below is a hack to recalculate address and size in order to
- // make sure we can watch non 4-byte alligned addresses as well.
+ // Check 4-byte alignment for hardware watchpoint target address. Below is a
+ // hack to recalculate address and size in order to make sure we can watch
+ // non 4-byte alligned addresses as well.
if (addr & 0x03) {
uint8_t watch_mask = (addr & 0x03) + size;
@@ -874,12 +874,10 @@ Status NativeRegisterContextLinux_arm::DoReadRegisterValue(
uint32_t offset, const char *reg_name, uint32_t size,
RegisterValue &value) {
// PTRACE_PEEKUSER don't work in the aarch64 linux kernel used on android
- // devices (always return
- // "Bad address"). To avoid using PTRACE_PEEKUSER we read out the full GPR
- // register set instead.
- // This approach is about 4 times slower but the performance overhead is
- // negligible in
- // comparision to processing time in lldb-server.
+ // devices (always return "Bad address"). To avoid using PTRACE_PEEKUSER we
+ // read out the full GPR register set instead. This approach is about 4 times
+ // slower but the performance overhead is negligible in comparision to
+ // processing time in lldb-server.
assert(offset % 4 == 0 && "Try to write a register with unaligned offset");
if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm))
return Status("Register isn't fit into the size of the GPR area");
@@ -895,13 +893,10 @@ Status NativeRegisterContextLinux_arm::DoReadRegisterValue(
Status NativeRegisterContextLinux_arm::DoWriteRegisterValue(
uint32_t offset, const char *reg_name, const RegisterValue &value) {
// PTRACE_POKEUSER don't work in the aarch64 linux kernel used on android
- // devices (always return
- // "Bad address"). To avoid using PTRACE_POKEUSER we read out the full GPR
- // register set, modify
- // the requested register and write it back. This approach is about 4 times
- // slower but the
- // performance overhead is negligible in comparision to processing time in
- // lldb-server.
+ // devices (always return "Bad address"). To avoid using PTRACE_POKEUSER we
+ // read out the full GPR register set, modify the requested register and
+ // write it back. This approach is about 4 times slower but the performance
+ // overhead is negligible in comparision to processing time in lldb-server.
assert(offset % 4 == 0 && "Try to write a register with unaligned offset");
if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm))
return Status("Register isn't fit into the size of the GPR area");
@@ -915,9 +910,8 @@ Status NativeRegisterContextLinux_arm::DoWriteRegisterValue(
// will clear thumb bit of new PC if we are already in thumb mode; that is
// CPSR thumb mode bit is set.
if (offset / sizeof(uint32_t) == gpr_pc_arm) {
- // Check if we are already in thumb mode and
- // thumb bit of current PC is read out to be zero and
- // thumb bit of next PC is read out to be one.
+ // Check if we are already in thumb mode and thumb bit of current PC is
+ // read out to be zero and thumb bit of next PC is read out to be one.
if ((m_gpr_arm[gpr_cpsr_arm] & 0x20) && !(m_gpr_arm[gpr_pc_arm] & 0x01) &&
(value.GetAsUInt32() & 0x01)) {
reg_value &= (~1ull);
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
index 40e3b80eda74..d0b068550a9e 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
@@ -42,7 +42,7 @@ public:
Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
//------------------------------------------------------------------
- // Hardware breakpoints/watchpoint mangement functions
+ // Hardware breakpoints/watchpoint management functions
//------------------------------------------------------------------
uint32_t NumSupportedHardwareBreakpoints() override;
@@ -140,7 +140,7 @@ private:
// occurred.
lldb::addr_t real_addr; // Address value that should cause target to stop.
uint32_t control; // Breakpoint/watchpoint control value.
- uint32_t refcount; // Serves as enable/disable and refernce counter.
+ uint32_t refcount; // Serves as enable/disable and reference counter.
};
struct DREG m_hbr_regs[16]; // Arm native linux hardware breakpoints
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
index c483260a5b2c..41fe446f728c 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
@@ -28,8 +28,7 @@
#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
// System includes - They have to be included after framework includes because
-// they define some
-// macros which collide with variable names in other modules
+// they define some macros which collide with variable names in other modules
#include <sys/socket.h>
// NT_PRSTATUS and NT_FPREGSET definition
#include <elf.h>
@@ -207,14 +206,14 @@ NativeRegisterContextLinux_arm64::ReadRegister(const RegisterInfo *reg_info,
error = ReadRegisterRaw(full_reg, reg_value);
if (error.Success()) {
- // If our read was not aligned (for ah,bh,ch,dh), shift our returned value
- // one byte to the right.
+ // If our read was not aligned (for ah,bh,ch,dh), shift our returned
+ // value one byte to the right.
if (is_subreg && (reg_info->byte_offset & 0x1))
reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8);
// If our return byte size was greater than the return value reg size,
- // then
- // use the type specified by reg_info rather than the uint64_t default
+ // then use the type specified by reg_info rather than the uint64_t
+ // default
if (reg_value.GetByteSize() > reg_info->byte_size)
reg_value.SetType(reg_info);
}
@@ -562,8 +561,8 @@ uint32_t NativeRegisterContextLinux_arm64::SetHardwareWatchpoint(
uint32_t control_value = 0, wp_index = 0;
lldb::addr_t real_addr = addr;
- // Check if we are setting watchpoint other than read/write/access
- // Also update watchpoint flag to match AArch64 write-read bit configuration.
+ // Check if we are setting watchpoint other than read/write/access Also
+ // update watchpoint flag to match AArch64 write-read bit configuration.
switch (watch_flags) {
case 1:
watch_flags = 2;
@@ -581,9 +580,9 @@ uint32_t NativeRegisterContextLinux_arm64::SetHardwareWatchpoint(
if (size != 1 && size != 2 && size != 4 && size != 8)
return LLDB_INVALID_INDEX32;
- // Check 8-byte alignment for hardware watchpoint target address.
- // Below is a hack to recalculate address and size in order to
- // make sure we can watch non 8-byte alligned addresses as well.
+ // Check 8-byte alignment for hardware watchpoint target address. Below is a
+ // hack to recalculate address and size in order to make sure we can watch
+ // non 8-byte alligned addresses as well.
if (addr & 0x07) {
uint8_t watch_mask = (addr & 0x07) + size;
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
index ab3c881ead59..c859d4249d05 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
@@ -42,7 +42,7 @@ public:
Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
//------------------------------------------------------------------
- // Hardware breakpoints/watchpoint mangement functions
+ // Hardware breakpoints/watchpoint management functions
//------------------------------------------------------------------
uint32_t NumSupportedHardwareBreakpoints() override;
@@ -140,7 +140,7 @@ private:
// occurred.
lldb::addr_t real_addr; // Address value that should cause target to stop.
uint32_t control; // Breakpoint/watchpoint control value.
- uint32_t refcount; // Serves as enable/disable and refernce counter.
+ uint32_t refcount; // Serves as enable/disable and reference counter.
};
struct DREG m_hbr_regs[16]; // Arm native linux hardware breakpoints
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
index 32c04a4374e6..69194b3c0663 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
@@ -140,9 +140,9 @@ NativeRegisterContextLinux_mips64::NativeRegisterContextLinux_mips64(
break;
}
- // Initialize m_iovec to point to the buffer and buffer size
- // using the conventions of Berkeley style UIO structures, as required
- // by PTRACE extensions.
+ // Initialize m_iovec to point to the buffer and buffer size using the
+ // conventions of Berkeley style UIO structures, as required by PTRACE
+ // extensions.
m_iovec.iov_base = &m_msa;
m_iovec.iov_len = sizeof(MSA_linux_mips);
@@ -337,7 +337,8 @@ lldb_private::Status NativeRegisterContextLinux_mips64::WriteRegister(
uint8_t byte_size = reg_info->byte_size;
lldbassert(reg_info->byte_offset < sizeof(UserArea));
- // Initialise the FP and MSA buffers by reading all co-processor 1 registers
+ // Initialise the FP and MSA buffers by reading all co-processor 1
+ // registers
ReadCP1();
if (IsFPR(reg_index)) {
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp
index ea854dfa1dc6..6aa4af64ab51 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp
@@ -26,8 +26,7 @@
#include "Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h"
// System includes - They have to be included after framework includes because
-// they define some
-// macros which collide with variable names in other modules
+// they define some macros which collide with variable names in other modules
#include <sys/socket.h>
#include <elf.h>
#include <asm/ptrace.h>
@@ -50,6 +49,7 @@ static const uint32_t g_gpr_regnums_ppc64le[] = {
gpr_pc_ppc64le, gpr_msr_ppc64le, gpr_origr3_ppc64le, gpr_ctr_ppc64le,
gpr_lr_ppc64le, gpr_xer_ppc64le, gpr_cr_ppc64le, gpr_softe_ppc64le,
gpr_trap_ppc64le,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static const uint32_t g_fpr_regnums_ppc64le[] = {
@@ -62,6 +62,7 @@ static const uint32_t g_fpr_regnums_ppc64le[] = {
fpr_f24_ppc64le, fpr_f25_ppc64le, fpr_f26_ppc64le, fpr_f27_ppc64le,
fpr_f28_ppc64le, fpr_f29_ppc64le, fpr_f30_ppc64le, fpr_f31_ppc64le,
fpr_fpscr_ppc64le,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static const uint32_t g_vmx_regnums_ppc64le[] = {
@@ -74,6 +75,7 @@ static const uint32_t g_vmx_regnums_ppc64le[] = {
vmx_vr24_ppc64le, vmx_vr25_ppc64le, vmx_vr26_ppc64le, vmx_vr27_ppc64le,
vmx_vr28_ppc64le, vmx_vr29_ppc64le, vmx_vr30_ppc64le, vmx_vr31_ppc64le,
vmx_vscr_ppc64le, vmx_vrsave_ppc64le,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static const uint32_t g_vsx_regnums_ppc64le[] = {
@@ -93,6 +95,7 @@ static const uint32_t g_vsx_regnums_ppc64le[] = {
vsx_vs52_ppc64le, vsx_vs53_ppc64le, vsx_vs54_ppc64le, vsx_vs55_ppc64le,
vsx_vs56_ppc64le, vsx_vs57_ppc64le, vsx_vs58_ppc64le, vsx_vs59_ppc64le,
vsx_vs60_ppc64le, vsx_vs61_ppc64le, vsx_vs62_ppc64le, vsx_vs63_ppc64le,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
};
namespace {
@@ -565,8 +568,8 @@ uint32_t NativeRegisterContextLinux_ppc64le::SetHardwareWatchpoint(
lldb::addr_t real_addr = addr;
uint32_t rw_mode = 0;
- // Check if we are setting watchpoint other than read/write/access
- // Update watchpoint flag to match ppc64le write-read bit configuration.
+ // Check if we are setting watchpoint other than read/write/access Update
+ // watchpoint flag to match ppc64le write-read bit configuration.
switch (watch_flags) {
case eWatchpointKindWrite:
rw_mode = PPC_BREAKPOINT_TRIGGER_WRITE;
@@ -587,9 +590,9 @@ uint32_t NativeRegisterContextLinux_ppc64le::SetHardwareWatchpoint(
if (size != 1 && size != 2 && size != 4 && size != 8)
return LLDB_INVALID_INDEX32;
- // Check 8-byte alignment for hardware watchpoint target address.
- // Below is a hack to recalculate address and size in order to
- // make sure we can watch non 8-byte alligned addresses as well.
+ // Check 8-byte alignment for hardware watchpoint target address. Below is a
+ // hack to recalculate address and size in order to make sure we can watch
+ // non 8-byte alligned addresses as well.
if (addr & 0x07) {
addr_t begin = llvm::alignDown(addr, 8);
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h
index bb25af80d02c..2c4471962ad0 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h
@@ -19,7 +19,7 @@
#include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h"
#define DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
-#include "RegisterInfos_ppc64le.h"
+#include "Plugins/Process/Utility/RegisterInfos_ppc64le.h"
#undef DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
namespace lldb_private {
@@ -49,7 +49,7 @@ public:
Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
//------------------------------------------------------------------
- // Hardware watchpoint mangement functions
+ // Hardware watchpoint management functions
//------------------------------------------------------------------
uint32_t NumSupportedHardwareWatchpoints() override;
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
index 021394ab154b..36da2b001054 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
@@ -10,7 +10,7 @@
#if defined(__s390x__) && defined(__linux__)
#include "NativeRegisterContextLinux_s390x.h"
-
+#include "Plugins/Process/Linux/NativeProcessLinux.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Utility/DataBufferHeap.h"
@@ -372,10 +372,10 @@ Status NativeRegisterContextLinux_s390x::ReadAllRegisterValues(
DoReadRegisterSet(NT_S390_SYSTEM_CALL, dst, 4);
dst += 4;
- // To enable inferior function calls while the process is stopped in
- // an interrupted system call, we need to clear the system call flag.
- // It will be restored to its original value by WriteAllRegisterValues.
- // Again we ignore error if the regset is unsupported.
+ // To enable inferior function calls while the process is stopped in an
+ // interrupted system call, we need to clear the system call flag. It will be
+ // restored to its original value by WriteAllRegisterValues. Again we ignore
+ // error if the regset is unsupported.
uint32_t system_call = 0;
DoWriteRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4);
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
index 84ffe9b6e420..87f4b8da053e 100755
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
@@ -329,9 +329,9 @@ NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64(
break;
}
- // Initialize m_iovec to point to the buffer and buffer size
- // using the conventions of Berkeley style UIO structures, as required
- // by PTRACE extensions.
+ // Initialize m_iovec to point to the buffer and buffer size using the
+ // conventions of Berkeley style UIO structures, as required by PTRACE
+ // extensions.
m_iovec.iov_base = &m_fpr;
m_iovec.iov_len = sizeof(m_fpr);
@@ -420,14 +420,14 @@ NativeRegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info,
error = ReadRegisterRaw(full_reg, reg_value);
if (error.Success()) {
- // If our read was not aligned (for ah,bh,ch,dh), shift our returned value
- // one byte to the right.
+ // If our read was not aligned (for ah,bh,ch,dh), shift our returned
+ // value one byte to the right.
if (is_subreg && (reg_info->byte_offset & 0x1))
reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8);
// If our return byte size was greater than the return value reg size,
- // then
- // use the type specified by reg_info rather than the uint64_t default
+ // then use the type specified by reg_info rather than the uint64_t
+ // default
if (reg_value.GetByteSize() > reg_info->byte_size)
reg_value.SetType(reg_info);
}
@@ -448,7 +448,8 @@ NativeRegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info,
reg_value.SetBytes(m_fpr.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
reg_info->byte_size, byte_order);
if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
- // Concatenate ymm using the register halves in xmm.bytes and ymmh.bytes
+ // Concatenate ymm using the register halves in xmm.bytes and
+ // ymmh.bytes
if (CopyXSTATEtoYMM(reg, byte_order))
reg_value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
reg_info->byte_size, byte_order);
@@ -492,8 +493,7 @@ NativeRegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info,
// Byte offsets of all registers are calculated wrt 'UserArea' structure.
// However, ReadFPR() reads fpu registers {using ptrace(PTRACE_GETFPREGS,..)}
// and stores them in 'm_fpr' (of type FPR structure). To extract values of
- // fpu
- // registers, m_fpr should be read at byte offsets calculated wrt to FPR
+ // fpu registers, m_fpr should be read at byte offsets calculated wrt to FPR
// structure.
// Since, FPR structure is also one of the member of UserArea structure.
@@ -599,11 +599,10 @@ Status NativeRegisterContextLinux_x86_64::WriteRegister(
// Get pointer to m_fpr.fxsave variable and set the data to it.
// Byte offsets of all registers are calculated wrt 'UserArea' structure.
- // However, WriteFPR() takes m_fpr (of type FPR structure) and writes only
- // fpu
- // registers using ptrace(PTRACE_SETFPREGS,..) API. Hence fpu registers
- // should
- // be written in m_fpr at byte offsets calculated wrt FPR structure.
+ // However, WriteFPR() takes m_fpr (of type FPR structure) and writes
+ // only fpu registers using ptrace(PTRACE_SETFPREGS,..) API. Hence fpu
+ // registers should be written in m_fpr at byte offsets calculated wrt
+ // FPR structure.
// Since, FPR structure is also one of the member of UserArea structure.
// byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
@@ -1093,8 +1092,7 @@ Status NativeRegisterContextLinux_x86_64::SetHardwareWatchpointWithIndex(
if (error.Fail())
return error;
- // for watchpoints 0, 1, 2, or 3, respectively,
- // set bits 1, 3, 5, or 7
+ // for watchpoints 0, 1, 2, or 3, respectively, set bits 1, 3, 5, or 7
uint64_t enable_bit = 1 << (2 * wp_index);
// set bits 16-17, 20-21, 24-25, or 28-29
@@ -1132,8 +1130,8 @@ bool NativeRegisterContextLinux_x86_64::ClearHardwareWatchpoint(
RegisterValue reg_value;
- // for watchpoints 0, 1, 2, or 3, respectively,
- // clear bits 0, 1, 2, or 3 of the debug status register (DR6)
+ // for watchpoints 0, 1, 2, or 3, respectively, clear bits 0, 1, 2, or 3 of
+ // the debug status register (DR6)
Status error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
if (error.Fail())
return false;
@@ -1143,9 +1141,9 @@ bool NativeRegisterContextLinux_x86_64::ClearHardwareWatchpoint(
if (error.Fail())
return false;
- // for watchpoints 0, 1, 2, or 3, respectively,
- // clear bits {0-1,16-19}, {2-3,20-23}, {4-5,24-27}, or {6-7,28-31}
- // of the debug control register (DR7)
+ // for watchpoints 0, 1, 2, or 3, respectively, clear bits {0-1,16-19},
+ // {2-3,20-23}, {4-5,24-27}, or {6-7,28-31} of the debug control register
+ // (DR7)
error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
if (error.Fail())
return false;
diff --git a/source/Plugins/Process/Linux/NativeThreadLinux.cpp b/source/Plugins/Process/Linux/NativeThreadLinux.cpp
index 0db3bd56b8e4..4ab2a9ae6245 100644
--- a/source/Plugins/Process/Linux/NativeThreadLinux.cpp
+++ b/source/Plugins/Process/Linux/NativeThreadLinux.cpp
@@ -211,8 +211,8 @@ Status NativeThreadLinux::Resume(uint32_t signo) {
m_stop_info.reason = StopReason::eStopReasonNone;
m_stop_description.clear();
- // If watchpoints have been set, but none on this thread,
- // then this is a new thread. So set all existing watchpoints.
+ // If watchpoints have been set, but none on this thread, then this is a new
+ // thread. So set all existing watchpoints.
if (m_watchpoint_index_map.empty()) {
NativeProcessLinux &process = GetProcess();
@@ -263,8 +263,8 @@ Status NativeThreadLinux::SingleStep(uint32_t signo) {
data = signo;
// If hardware single-stepping is not supported, we just do a continue. The
- // breakpoint on the
- // next instruction has been setup in NativeProcessLinux::Resume.
+ // breakpoint on the next instruction has been setup in
+ // NativeProcessLinux::Resume.
return NativeProcessLinux::PtraceWrapper(
GetProcess().SupportHardwareSingleStepping() ? PTRACE_SINGLESTEP
: PTRACE_CONT,
diff --git a/source/Plugins/Process/Linux/ProcessorTrace.h b/source/Plugins/Process/Linux/ProcessorTrace.h
index 6603c7d60478..6fd918c2bb58 100644
--- a/source/Plugins/Process/Linux/ProcessorTrace.h
+++ b/source/Plugins/Process/Linux/ProcessorTrace.h
@@ -34,7 +34,7 @@ namespace process_linux {
// a key to the tracing instance and trace manipulations could be
// performed using the trace id.
//
-// The traace id could map to trace instances for a group of threads
+// The trace id could map to trace instances for a group of threads
// (spanning to all the threads in the process) or a single thread.
// The kernel interface for us is the perf_event_open.
// ---------------------------------------------------------------------
diff --git a/source/Plugins/Process/Linux/SingleStepCheck.cpp b/source/Plugins/Process/Linux/SingleStepCheck.cpp
index 251cb4b2f10a..c57a2daf2275 100644
--- a/source/Plugins/Process/Linux/SingleStepCheck.cpp
+++ b/source/Plugins/Process/Linux/SingleStepCheck.cpp
@@ -59,9 +59,9 @@ struct ChildDeleter {
bool WorkaroundNeeded() {
// We shall spawn a child, and use it to verify the debug capabilities of the
- // cpu. We shall iterate through the cpus, bind the child to each one in turn,
- // and verify that single-stepping works on that cpu. A workaround is needed
- // if we find at least one broken cpu.
+ // cpu. We shall iterate through the cpus, bind the child to each one in
+ // turn, and verify that single-stepping works on that cpu. A workaround is
+ // needed if we find at least one broken cpu.
Log *log = ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD);
::pid_t child_pid = fork();
diff --git a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
index 3d9f498b1e9a..116155d9a232 100644
--- a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
@@ -59,15 +59,6 @@ bool CommunicationKDP::SendRequestPacket(
return SendRequestPacketNoLock(request_packet);
}
-#if 0
-typedef struct {
- uint8_t request; // Either: CommandType | ePacketTypeRequest, or CommandType | ePacketTypeReply
- uint8_t sequence;
- uint16_t length; // Length of entire packet including this header
- uint32_t key; // Session key
-} kdp_hdr_t;
-#endif
-
void CommunicationKDP::MakeRequestPacketHeader(CommandType request_type,
PacketStreamType &request_packet,
uint16_t request_length) {
@@ -127,16 +118,14 @@ bool CommunicationKDP::SendRequestAndGetReply(
}
} else if (reply_sequence_id > request_sequence_id) {
// Sequence ID was greater than the sequence ID of the packet we
- // sent, something
- // is really wrong...
+ // sent, something is really wrong...
reply_packet.Clear();
return false;
} else {
- // The reply sequence ID was less than our current packet's sequence
- // ID
- // so we should keep trying to get a response because this was a
- // response
- // for a previous packet that we must have retried.
+ // The reply sequence ID was less than our current packet's
+ // sequence ID so we should keep trying to get a response because
+ // this was a response for a previous packet that we must have
+ // retried.
}
} else {
// Break and retry sending the packet as we didn't get a response due
@@ -186,7 +175,7 @@ bool CommunicationKDP::GetSequenceMutex(
bool CommunicationKDP::WaitForNotRunningPrivate(
const std::chrono::microseconds &timeout) {
- return m_is_running.WaitForValueEqualTo(false, timeout, NULL);
+ return m_is_running.WaitForValueEqualTo(false, timeout);
}
size_t
@@ -324,9 +313,9 @@ bool CommunicationKDP::CheckForPacket(const uint8_t *src, size_t src_len,
offset = 2;
const uint16_t length = packet.GetU16(&offset);
if (length <= bytes_available) {
- // We have an entire packet ready, we need to copy the data
- // bytes into a buffer that will be owned by the packet and
- // erase the bytes from our communcation buffer "m_bytes"
+ // We have an entire packet ready, we need to copy the data bytes into
+ // a buffer that will be owned by the packet and erase the bytes from
+ // our communcation buffer "m_bytes"
packet.SetData(DataBufferSP(new DataBufferHeap(&m_bytes[0], length)));
m_bytes.erase(0, length);
@@ -341,8 +330,8 @@ bool CommunicationKDP::CheckForPacket(const uint8_t *src, size_t src_len,
} break;
default:
- // Unrecognized reply command byte, erase this byte and try to get back on
- // track
+ // Unrecognized reply command byte, erase this byte and try to get back
+ // on track
if (log)
log->Printf("CommunicationKDP::%s: tossing junk byte: 0x%2.2x",
__FUNCTION__, (uint8_t)m_bytes[0]);
@@ -436,34 +425,6 @@ bool CommunicationKDP::SendRequestVersion() {
return false;
}
-#if 0 // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
-const char *
-CommunicationKDP::GetImagePath ()
-{
- if (m_image_path.empty())
- SendRequestImagePath();
- return m_image_path.c_str();
-}
-
-bool
-CommunicationKDP::SendRequestImagePath ()
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- const CommandType command = KDP_IMAGEPATH;
- const uint32_t command_length = 8;
- MakeRequestPacketHeader (command, request_packet, command_length);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- {
- const char *path = reply_packet.PeekCStr(8);
- if (path && path[0])
- m_kernel_version.assign (path);
- return true;
- }
- return false;
-}
-#endif
-
uint32_t CommunicationKDP::GetCPUMask() {
if (!HostInfoIsValid())
SendRequestHostInfo();
@@ -495,7 +456,7 @@ lldb_private::UUID CommunicationKDP::GetUUID() {
if (uuid_str.size() < 32)
return uuid;
- if (uuid.SetFromCString(uuid_str.c_str()) == 0) {
+ if (uuid.SetFromStringRef(uuid_str) == 0) {
UUID invalid_uuid;
return invalid_uuid;
}
@@ -1245,8 +1206,8 @@ uint32_t CommunicationKDP::SendRequestReadRegisters(uint32_t cpu,
if (src) {
::memcpy(dst, src, bytes_to_copy);
error.Clear();
- // Return the number of bytes we could have returned regardless if
- // we copied them or not, just so we know when things don't match up
+ // Return the number of bytes we could have returned regardless if we
+ // copied them or not, just so we know when things don't match up
return src_len;
}
}
diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
index f01f1ace583c..2e707ab2e363 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
@@ -172,10 +172,10 @@ ProcessKDP::ProcessKDP(TargetSP target_sp, ListenerSP listener_sp)
//----------------------------------------------------------------------
ProcessKDP::~ProcessKDP() {
Clear();
- // We need to call finalize on the process before destroying ourselves
- // to make sure all of the broadcaster cleanup goes as planned. If we
- // destruct this class, then Process::~Process() might have problems
- // trying to fully destroy the broadcaster.
+ // We need to call finalize on the process before destroying ourselves to
+ // make sure all of the broadcaster cleanup goes as planned. If we destruct
+ // this class, then Process::~Process() might have problems trying to fully
+ // destroy the broadcaster.
Finalize();
}
@@ -226,9 +226,9 @@ bool ProcessKDP::GetHostArchitecture(ArchSpec &arch) {
Status ProcessKDP::DoConnectRemote(Stream *strm, llvm::StringRef remote_url) {
Status error;
- // Don't let any JIT happen when doing KDP as we can't allocate
- // memory and we don't want to be mucking with threads that might
- // already be handling exceptions
+ // Don't let any JIT happen when doing KDP as we can't allocate memory and we
+ // don't want to be mucking with threads that might already be handling
+ // exceptions
SetCanJIT(false);
if (remote_url.empty()) {
@@ -282,16 +282,15 @@ Status ProcessKDP::DoConnectRemote(Stream *strm, llvm::StringRef remote_url) {
if (m_comm.RemoteIsEFI()) {
// Select an invalid plugin name for the dynamic loader so one
- // doesn't get used
- // since EFI does its own manual loading via python scripting
+ // doesn't get used since EFI does its own manual loading via
+ // python scripting
static ConstString g_none_dynamic_loader("none");
m_dyld_plugin_name = g_none_dynamic_loader;
if (kernel_uuid.IsValid()) {
- // If EFI passed in a UUID= try to lookup UUID
- // The slide will not be provided. But the UUID
- // lookup will be used to launch EFI debug scripts
- // from the dSYM, that can load all of the symbols.
+ // If EFI passed in a UUID= try to lookup UUID The slide will not
+ // be provided. But the UUID lookup will be used to launch EFI
+ // debug scripts from the dSYM, that can load all of the symbols.
ModuleSpec module_spec;
module_spec.GetUUID() = kernel_uuid;
module_spec.GetArchitecture() = target.GetArchitecture();
@@ -386,7 +385,7 @@ ProcessKDP::DoAttachToProcessWithID(lldb::pid_t attach_pid,
const ProcessAttachInfo &attach_info) {
Status error;
error.SetErrorString(
- "attach to process by ID is not suppported in kdp remote debugging");
+ "attach to process by ID is not supported in kdp remote debugging");
return error;
}
@@ -395,7 +394,7 @@ ProcessKDP::DoAttachToProcessWithName(const char *process_name,
const ProcessAttachInfo &attach_info) {
Status error;
error.SetErrorString(
- "attach to process by name is not suppported in kdp remote debugging");
+ "attach to process by name is not supported in kdp remote debugging");
return error;
}
@@ -443,8 +442,8 @@ Status ProcessKDP::DoResume() {
StateAsCString(thread_resume_state));
switch (thread_resume_state) {
case eStateSuspended:
- // Nothing to do here when a thread will stay suspended
- // we just leave the CPU mask bit set to zero for the thread
+ // Nothing to do here when a thread will stay suspended we just leave the
+ // CPU mask bit set to zero for the thread
if (log)
log->Printf("ProcessKDP::DoResume() = suspended???");
break;
@@ -535,8 +534,8 @@ bool ProcessKDP::UpdateThreadList(ThreadList &old_thread_list,
}
void ProcessKDP::RefreshStateAfterStop() {
- // Let all threads recover from stopping and do any clean up based
- // on the previous thread state (if any).
+ // Let all threads recover from stopping and do any clean up based on the
+ // previous thread state (if any).
m_thread_list.RefreshStateAfterStop();
}
@@ -545,9 +544,9 @@ Status ProcessKDP::DoHalt(bool &caused_stop) {
if (m_comm.IsRunning()) {
if (m_destroy_in_process) {
- // If we are attemping to destroy, we need to not return an error to
- // Halt or DoDestroy won't get called.
- // We are also currently running, so send a process stopped event
+ // If we are attempting to destroy, we need to not return an error to Halt
+ // or DoDestroy won't get called. We are also currently running, so send
+ // a process stopped event
SetPrivateState(eStateStopped);
} else {
error.SetErrorString("KDP cannot interrupt a running kernel");
@@ -563,8 +562,8 @@ Status ProcessKDP::DoDetach(bool keep_stopped) {
log->Printf("ProcessKDP::DoDetach(keep_stopped = %i)", keep_stopped);
if (m_comm.IsRunning()) {
- // We are running and we can't interrupt a running kernel, so we need
- // to just close the connection to the kernel and hope for the best
+ // We are running and we can't interrupt a running kernel, so we need to
+ // just close the connection to the kernel and hope for the best
} else {
// If we are going to keep the target stopped, then don't send the
// disconnect message.
@@ -647,14 +646,14 @@ size_t ProcessKDP::DoWriteMemory(addr_t addr, const void *buf, size_t size,
lldb::addr_t ProcessKDP::DoAllocateMemory(size_t size, uint32_t permissions,
Status &error) {
error.SetErrorString(
- "memory allocation not suppported in kdp remote debugging");
+ "memory allocation not supported in kdp remote debugging");
return LLDB_INVALID_ADDRESS;
}
Status ProcessKDP::DoDeallocateMemory(lldb::addr_t addr) {
Status error;
error.SetErrorString(
- "memory deallocation not suppported in kdp remote debugging");
+ "memory deallocation not supported in kdp remote debugging");
return error;
}
@@ -701,14 +700,14 @@ Status ProcessKDP::DisableBreakpointSite(BreakpointSite *bp_site) {
Status ProcessKDP::EnableWatchpoint(Watchpoint *wp, bool notify) {
Status error;
error.SetErrorString(
- "watchpoints are not suppported in kdp remote debugging");
+ "watchpoints are not supported in kdp remote debugging");
return error;
}
Status ProcessKDP::DisableWatchpoint(Watchpoint *wp, bool notify) {
Status error;
error.SetErrorString(
- "watchpoints are not suppported in kdp remote debugging");
+ "watchpoints are not supported in kdp remote debugging");
return error;
}
@@ -717,7 +716,7 @@ void ProcessKDP::Clear() { m_thread_list.Clear(); }
Status ProcessKDP::DoSignal(int signo) {
Status error;
error.SetErrorString(
- "sending signals is not suppported in kdp remote debugging");
+ "sending signals is not supported in kdp remote debugging");
return error;
}
diff --git a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
index 1902cc492ff4..7fca0fc24fdb 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
@@ -52,11 +52,11 @@ ThreadKDP::~ThreadKDP() {
const char *ThreadKDP::GetName() {
if (m_thread_name.empty())
- return NULL;
+ return nullptr;
return m_thread_name.c_str();
}
-const char *ThreadKDP::GetQueueName() { return NULL; }
+const char *ThreadKDP::GetQueueName() { return nullptr; }
void ThreadKDP::RefreshStateAfterStop() {
// Invalidate all registers in our register context. We don't set "force" to
@@ -65,8 +65,8 @@ void ThreadKDP::RefreshStateAfterStop() {
// context by the time this function gets called. The KDPRegisterContext
// class has been made smart enough to detect when it needs to invalidate
// which registers are valid by putting hooks in the register read and
- // register supply functions where they check the process stop ID and do
- // the right thing.
+ // register supply functions where they check the process stop ID and do the
+ // right thing.
const bool force = false;
lldb::RegisterContextSP reg_ctx_sp(GetRegisterContext());
if (reg_ctx_sp)
@@ -79,8 +79,8 @@ void ThreadKDP::Dump(Log *log, uint32_t index) {}
bool ThreadKDP::ShouldStop(bool &step_more) { return true; }
lldb::RegisterContextSP ThreadKDP::GetRegisterContext() {
- if (m_reg_context_sp.get() == NULL)
- m_reg_context_sp = CreateRegisterContextForFrame(NULL);
+ if (!m_reg_context_sp)
+ m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
return m_reg_context_sp;
}
@@ -119,7 +119,7 @@ ThreadKDP::CreateRegisterContextForFrame(StackFrame *frame) {
}
} else {
Unwind *unwinder = GetUnwinder();
- if (unwinder)
+ if (unwinder != nullptr)
reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
}
return reg_ctx_sp;
@@ -151,8 +151,8 @@ void ThreadKDP::SetStopInfoFrom_KDP_EXCEPTION(
const uint32_t exc_type = exc_reply_packet.GetU32(&offset);
const uint32_t exc_code = exc_reply_packet.GetU32(&offset);
const uint32_t exc_subcode = exc_reply_packet.GetU32(&offset);
- // We have to make a copy of the stop info because the thread list
- // will iterate through the threads and clear all stop infos..
+ // We have to make a copy of the stop info because the thread list will
+ // iterate through the threads and clear all stop infos..
// Let the StopInfoMachException::CreateStopReasonWithMachException()
// function update the PC if needed as we might hit a software breakpoint
diff --git a/source/Plugins/Process/NetBSD/CMakeLists.txt b/source/Plugins/Process/NetBSD/CMakeLists.txt
index 5b2cef8b847b..92a6014ced07 100644
--- a/source/Plugins/Process/NetBSD/CMakeLists.txt
+++ b/source/Plugins/Process/NetBSD/CMakeLists.txt
@@ -1,7 +1,3 @@
-include_directories(.)
-include_directories(../POSIX)
-include_directories(../Utility)
-
add_lldb_library(lldbPluginProcessNetBSD PLUGIN
NativeProcessNetBSD.cpp
NativeRegisterContextNetBSD.cpp
diff --git a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
index 387f04afa5b4..1a4cb21d000e 100644
--- a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
+++ b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
@@ -24,8 +24,7 @@
#include "llvm/Support/Errno.h"
// System includes - They have to be included after framework includes because
-// they define some
-// macros which collide with variable names in other modules
+// they define some macros which collide with variable names in other modules
// clang-format off
#include <sys/types.h>
#include <sys/ptrace.h>
@@ -93,17 +92,19 @@ NativeProcessNetBSD::Factory::Launch(ProcessLaunchInfo &launch_info,
}
LLDB_LOG(log, "inferior started, now in stopped state");
- ArchSpec arch;
- if ((status = ResolveProcessArchitecture(pid, arch)).Fail())
- return status.ToError();
+ ProcessInstanceInfo Info;
+ if (!Host::GetProcessInfo(pid, Info)) {
+ return llvm::make_error<StringError>("Cannot get process architecture",
+ llvm::inconvertibleErrorCode());
+ }
// Set the architecture to the exe architecture.
LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid,
- arch.GetArchitectureName());
+ Info.GetArchitecture().GetArchitectureName());
std::unique_ptr<NativeProcessNetBSD> process_up(new NativeProcessNetBSD(
pid, launch_info.GetPTY().ReleaseMasterFileDescriptor(), native_delegate,
- arch, mainloop));
+ Info.GetArchitecture(), mainloop));
status = process_up->ReinitializeThreads();
if (status.Fail())
@@ -111,7 +112,7 @@ NativeProcessNetBSD::Factory::Launch(ProcessLaunchInfo &launch_info,
for (const auto &thread : process_up->m_threads)
static_cast<NativeThreadNetBSD &>(*thread).SetStoppedBySignal(SIGSTOP);
- process_up->SetState(StateType::eStateStopped);
+ process_up->SetState(StateType::eStateStopped, false);
return std::move(process_up);
}
@@ -124,15 +125,16 @@ NativeProcessNetBSD::Factory::Attach(
LLDB_LOG(log, "pid = {0:x}", pid);
// Retrieve the architecture for the running process.
- ArchSpec arch;
- Status status = ResolveProcessArchitecture(pid, arch);
- if (!status.Success())
- return status.ToError();
+ ProcessInstanceInfo Info;
+ if (!Host::GetProcessInfo(pid, Info)) {
+ return llvm::make_error<StringError>("Cannot get process architecture",
+ llvm::inconvertibleErrorCode());
+ }
- std::unique_ptr<NativeProcessNetBSD> process_up(
- new NativeProcessNetBSD(pid, -1, native_delegate, arch, mainloop));
+ std::unique_ptr<NativeProcessNetBSD> process_up(new NativeProcessNetBSD(
+ pid, -1, native_delegate, Info.GetArchitecture(), mainloop));
- status = process_up->Attach();
+ Status status = process_up->Attach();
if (!status.Success())
return status.ToError();
@@ -349,8 +351,8 @@ NativeProcessNetBSD::FixupBreakpointPCAsNeeded(NativeThreadNetBSD &thread) {
return error;
} else
LLDB_LOG(log, "breakpoint size: {0}", breakpoint_size);
- // First try probing for a breakpoint at a software breakpoint location: PC
- // - breakpoint size.
+ // First try probing for a breakpoint at a software breakpoint location: PC -
+ // breakpoint size.
const lldb::addr_t initial_pc_addr =
context.GetPCfromBreakpointLocation();
lldb::addr_t breakpoint_addr = initial_pc_addr;
@@ -559,8 +561,8 @@ Status NativeProcessNetBSD::GetMemoryRegionInfo(lldb::addr_t load_addr,
"descending memory map entries detected, unexpected");
prev_base_address = proc_entry_info.GetRange().GetRangeBase();
UNUSED_IF_ASSERT_DISABLED(prev_base_address);
- // If the target address comes before this entry, indicate distance to
- // next region.
+ // If the target address comes before this entry, indicate distance to next
+ // region.
if (load_addr < proc_entry_info.GetRange().GetRangeBase()) {
range_info.GetRange().SetRangeBase(load_addr);
range_info.GetRange().SetByteSize(
@@ -579,9 +581,8 @@ Status NativeProcessNetBSD::GetMemoryRegionInfo(lldb::addr_t load_addr,
// parsed.
}
// If we made it here, we didn't find an entry that contained the given
- // address. Return the
- // load_addr as start and the amount of bytes betwwen load address and the
- // end of the memory as size.
+ // address. Return the load_addr as start and the amount of bytes betwwen
+ // load address and the end of the memory as size.
range_info.GetRange().SetRangeBase(load_addr);
range_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
range_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
@@ -641,8 +642,8 @@ Status NativeProcessNetBSD::PopulateMemoryRegionCache() {
free(vm);
if (m_mem_region_cache.empty()) {
- // No entries after attempting to read them. This shouldn't happen.
- // Assume we don't support map entries.
+ // No entries after attempting to read them. This shouldn't happen. Assume
+ // we don't support map entries.
LLDB_LOG(log, "failed to find any vmmap entries, assuming no support "
"for memory region metadata retrieval");
m_supports_mem_region = LazyBool::eLazyBoolNo;
@@ -778,8 +779,8 @@ Status NativeProcessNetBSD::Attach() {
return status;
int wstatus;
- // Need to use WALLSIG otherwise we receive an error with errno=ECHLD
- // At this point we should have a thread stopped if waitpid succeeds.
+ // Need to use WALLSIG otherwise we receive an error with errno=ECHLD At this
+ // point we should have a thread stopped if waitpid succeeds.
if ((wstatus = waitpid(m_pid, NULL, WALLSIG)) < 0)
return Status(errno, eErrorTypePOSIX);
@@ -871,13 +872,13 @@ NativeProcessNetBSD::GetAuxvData() const {
*/
size_t auxv_size = 100 * sizeof(AuxInfo);
- ErrorOr<std::unique_ptr<MemoryBuffer>> buf =
- llvm::MemoryBuffer::getNewMemBuffer(auxv_size);
+ ErrorOr<std::unique_ptr<WritableMemoryBuffer>> buf =
+ llvm::WritableMemoryBuffer::getNewMemBuffer(auxv_size);
struct ptrace_io_desc io;
io.piod_op = PIOD_READ_AUXV;
io.piod_offs = 0;
- io.piod_addr = const_cast<void *>(static_cast<const void *>(buf.get()->getBufferStart()));
+ io.piod_addr = static_cast<void *>(buf.get()->getBufferStart());
io.piod_len = auxv_size;
Status error = NativeProcessNetBSD::PtraceWrapper(PT_IO, GetID(), &io);
@@ -888,7 +889,7 @@ NativeProcessNetBSD::GetAuxvData() const {
if (io.piod_len < 1)
return std::error_code(ECANCELED, std::generic_category());
- return buf;
+ return std::move(buf);
}
Status NativeProcessNetBSD::ReinitializeThreads() {
diff --git a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
index 7090fce34fc9..142f74ecf194 100644
--- a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
+++ b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
@@ -20,10 +20,10 @@
namespace lldb_private {
namespace process_netbsd {
/// @class NativeProcessNetBSD
-/// @brief Manages communication with the inferior (debugee) process.
+/// Manages communication with the inferior (debugee) process.
///
-/// Upon construction, this class prepares and launches an inferior process for
-/// debugging.
+/// Upon construction, this class prepares and launches an inferior process
+/// for debugging.
///
/// Changes in the inferior process state are broadcasted.
class NativeProcessNetBSD : public NativeProcessProtocol {
diff --git a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
index 347c15ae5b23..16b6f2c52dd5 100644
--- a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
+++ b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
@@ -161,8 +161,8 @@ static RegisterInfoInterface *
CreateRegisterInfoInterface(const ArchSpec &target_arch) {
assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
"Register setting path assumes this is a 64-bit host");
- // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the
- // x86_64 register context.
+ // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64
+ // register context.
return new RegisterContextNetBSD_x86_64(target_arch);
}
@@ -805,8 +805,7 @@ Status NativeRegisterContextNetBSD_x86_64::SetHardwareWatchpointWithIndex(
if (error.Fail())
return error;
- // for watchpoints 0, 1, 2, or 3, respectively,
- // set bits 1, 3, 5, or 7
+ // for watchpoints 0, 1, 2, or 3, respectively, set bits 1, 3, 5, or 7
uint64_t enable_bit = 1 << (2 * wp_index);
// set bits 16-17, 20-21, 24-25, or 28-29
@@ -845,8 +844,8 @@ bool NativeRegisterContextNetBSD_x86_64::ClearHardwareWatchpoint(
RegisterValue reg_value;
- // for watchpoints 0, 1, 2, or 3, respectively,
- // clear bits 0, 1, 2, or 3 of the debug status register (DR6)
+ // for watchpoints 0, 1, 2, or 3, respectively, clear bits 0, 1, 2, or 3 of
+ // the debug status register (DR6)
const RegisterInfo *const reg_info_dr6 =
GetRegisterInfoAtIndex(lldb_dr6_x86_64);
Status error = ReadRegister(reg_info_dr6, reg_value);
@@ -858,9 +857,9 @@ bool NativeRegisterContextNetBSD_x86_64::ClearHardwareWatchpoint(
if (error.Fail())
return false;
- // for watchpoints 0, 1, 2, or 3, respectively,
- // clear bits {0-1,16-19}, {2-3,20-23}, {4-5,24-27}, or {6-7,28-31}
- // of the debug control register (DR7)
+ // for watchpoints 0, 1, 2, or 3, respectively, clear bits {0-1,16-19},
+ // {2-3,20-23}, {4-5,24-27}, or {6-7,28-31} of the debug control register
+ // (DR7)
const RegisterInfo *const reg_info_dr7 =
GetRegisterInfoAtIndex(lldb_dr7_x86_64);
error = ReadRegister(reg_info_dr7, reg_value);
diff --git a/source/Plugins/Process/POSIX/CMakeLists.txt b/source/Plugins/Process/POSIX/CMakeLists.txt
index d9a4508df0a3..f058e01c7439 100644
--- a/source/Plugins/Process/POSIX/CMakeLists.txt
+++ b/source/Plugins/Process/POSIX/CMakeLists.txt
@@ -1,6 +1,3 @@
-include_directories(.)
-include_directories(../Utility)
-
add_lldb_library(lldbPluginProcessPOSIX PLUGIN
CrashReason.cpp
ProcessMessage.cpp
diff --git a/source/Plugins/Process/POSIX/CrashReason.cpp b/source/Plugins/Process/POSIX/CrashReason.cpp
index 864418c90031..4b24d31226a9 100644
--- a/source/Plugins/Process/POSIX/CrashReason.cpp
+++ b/source/Plugins/Process/POSIX/CrashReason.cpp
@@ -47,8 +47,7 @@ CrashReason GetCrashReasonForSIGSEGV(const siginfo_t &info) {
#ifdef SI_KERNEL
case SI_KERNEL:
// Some platforms will occasionally send nonstandard spurious SI_KERNEL
- // codes.
- // One way to get this is via unaligned SIMD loads.
+ // codes. One way to get this is via unaligned SIMD loads.
return CrashReason::eInvalidAddress; // for lack of anything better
#endif
case SEGV_MAPERR:
diff --git a/source/Plugins/Process/Utility/CMakeLists.txt b/source/Plugins/Process/Utility/CMakeLists.txt
index 3780fb5e4c18..b43756acea63 100644
--- a/source/Plugins/Process/Utility/CMakeLists.txt
+++ b/source/Plugins/Process/Utility/CMakeLists.txt
@@ -1,5 +1,3 @@
-include_directories(../../../Utility/)
-
add_lldb_library(lldbPluginProcessUtility PLUGIN
DynamicRegisterInfo.cpp
FreeBSDSignals.cpp
@@ -60,7 +58,6 @@ add_lldb_library(lldbPluginProcessUtility PLUGIN
lldbSymbol
lldbTarget
lldbUtility
- lldbPluginProcessElfCore
LINK_COMPONENTS
Support
)
diff --git a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
index 61e5bf4481d6..5f34e9915ede 100644
--- a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
+++ b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
@@ -12,6 +12,7 @@
#include "lldb/Core/StreamFile.h"
#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Host/StringConvert.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/StringExtractor.h"
@@ -20,21 +21,42 @@
using namespace lldb;
using namespace lldb_private;
-DynamicRegisterInfo::DynamicRegisterInfo()
- : m_regs(), m_sets(), m_set_reg_nums(), m_set_names(), m_value_regs_map(),
- m_invalidate_regs_map(), m_dynamic_reg_size_map(),
- m_reg_data_byte_size(0), m_finalized(false) {}
-
DynamicRegisterInfo::DynamicRegisterInfo(
const lldb_private::StructuredData::Dictionary &dict,
- const lldb_private::ArchSpec &arch)
- : m_regs(), m_sets(), m_set_reg_nums(), m_set_names(), m_value_regs_map(),
- m_invalidate_regs_map(), m_dynamic_reg_size_map(),
- m_reg_data_byte_size(0), m_finalized(false) {
+ const lldb_private::ArchSpec &arch) {
SetRegisterInfo(dict, arch);
}
-DynamicRegisterInfo::~DynamicRegisterInfo() {}
+DynamicRegisterInfo::DynamicRegisterInfo(DynamicRegisterInfo &&info) {
+ MoveFrom(std::move(info));
+}
+
+DynamicRegisterInfo &
+DynamicRegisterInfo::operator=(DynamicRegisterInfo &&info) {
+ MoveFrom(std::move(info));
+ return *this;
+}
+
+void DynamicRegisterInfo::MoveFrom(DynamicRegisterInfo &&info) {
+ m_regs = std::move(info.m_regs);
+ m_sets = std::move(info.m_sets);
+ m_set_reg_nums = std::move(info.m_set_reg_nums);
+ m_set_names = std::move(info.m_set_names);
+ m_value_regs_map = std::move(info.m_value_regs_map);
+ m_invalidate_regs_map = std::move(info.m_invalidate_regs_map);
+ m_dynamic_reg_size_map = std::move(info.m_dynamic_reg_size_map);
+
+ m_reg_data_byte_size = info.m_reg_data_byte_size;
+ m_finalized = info.m_finalized;
+
+ if (m_finalized) {
+ const size_t num_sets = m_sets.size();
+ for (size_t set = 0; set < num_sets; ++set)
+ m_sets[set].registers = m_set_reg_nums[set].data();
+ }
+
+ info.Clear();
+}
size_t
DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
@@ -44,13 +66,9 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
if (dict.GetValueForKeyAsArray("sets", sets)) {
const uint32_t num_sets = sets->GetSize();
for (uint32_t i = 0; i < num_sets; ++i) {
- llvm::StringRef set_name_str;
ConstString set_name;
- if (sets->GetItemAtIndexAsString(i, set_name_str))
- set_name.SetString(set_name_str);
- if (set_name) {
- RegisterSet new_set = {set_name.AsCString(), NULL, 0, NULL};
- m_sets.push_back(new_set);
+ if (sets->GetItemAtIndexAsString(i, set_name) && !set_name.IsEmpty()) {
+ m_sets.push_back({ set_name.AsCString(), NULL, 0, NULL });
} else {
Clear();
printf("error: register sets must have valid names\n");
@@ -59,6 +77,7 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
}
m_set_reg_nums.resize(m_sets.size());
}
+
StructuredData::Array *regs = nullptr;
if (!dict.GetValueForKeyAsArray("registers", regs))
return 0;
@@ -76,8 +95,8 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
return 0;
}
- // { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint'
- // , 'format':'hex' , 'set': 0, 'ehframe' : 2,
+ // { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16,
+ // 'encoding':'uint' , 'format':'hex' , 'set': 0, 'ehframe' : 2,
// 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', },
RegisterInfo reg_info;
std::vector<uint32_t> value_regs;
@@ -102,14 +121,11 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
const ByteOrder byte_order = arch.GetByteOrder();
if (reg_info.byte_offset == UINT32_MAX) {
- // No offset for this register, see if the register has a value expression
- // which indicates this register is part of another register. Value
- // expressions
- // are things like "rax[31:0]" which state that the current register's
- // value
- // is in a concrete register "rax" in bits 31:0. If there is a value
- // expression
- // we can calculate the offset
+ // No offset for this register, see if the register has a value
+ // expression which indicates this register is part of another register.
+ // Value expressions are things like "rax[31:0]" which state that the
+ // current register's value is in a concrete register "rax" in bits 31:0.
+ // If there is a value expression we can calculate the offset
bool success = false;
llvm::StringRef slice_str;
if (reg_info_dict->GetValueForKeyAsString("slice", slice_str, nullptr)) {
@@ -141,7 +157,7 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
ConstString containing_reg_name(reg_name_str);
- RegisterInfo *containing_reg_info =
+ const RegisterInfo *containing_reg_info =
GetRegisterInfo(containing_reg_name);
if (containing_reg_info) {
const uint32_t max_bit = containing_reg_info->byte_size * 8;
@@ -210,7 +226,7 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
ConstString composite_reg_name;
if (composite_reg_list->GetItemAtIndexAsString(
composite_idx, composite_reg_name, nullptr)) {
- RegisterInfo *composite_reg_info =
+ const RegisterInfo *composite_reg_info =
GetRegisterInfo(composite_reg_name);
if (composite_reg_info) {
composite_offset = std::min(composite_offset,
@@ -286,7 +302,8 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
llvm::StringRef format_str;
if (reg_info_dict->GetValueForKeyAsString("format", format_str, nullptr)) {
- if (Args::StringToFormat(format_str.str().c_str(), reg_info.format, NULL)
+ if (OptionArgParser::ToFormat(format_str.str().c_str(), reg_info.format,
+ NULL)
.Fail()) {
Clear();
printf("error: invalid 'format' value in register dictionary\n");
@@ -349,7 +366,7 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
uint64_t invalidate_reg_num;
if (invalidate_reg_list->GetItemAtIndexAsString(
idx, invalidate_reg_name)) {
- RegisterInfo *invalidate_reg_info =
+ const RegisterInfo *invalidate_reg_info =
GetRegisterInfo(invalidate_reg_name);
if (invalidate_reg_info) {
m_invalidate_regs_map[i].push_back(
@@ -437,7 +454,7 @@ void DynamicRegisterInfo::Finalize(const ArchSpec &arch) {
for (size_t set = 0; set < num_sets; ++set) {
assert(m_sets.size() == m_set_reg_nums.size());
m_sets[set].num_registers = m_set_reg_nums[set].size();
- m_sets[set].registers = &m_set_reg_nums[set][0];
+ m_sets[set].registers = m_set_reg_nums[set].data();
}
// sort and unique all value registers and make sure each is terminated with
@@ -492,8 +509,7 @@ void DynamicRegisterInfo::Finalize(const ArchSpec &arch) {
}
// sort and unique all invalidate registers and make sure each is terminated
- // with
- // LLDB_INVALID_REGNUM
+ // with LLDB_INVALID_REGNUM
for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(),
end = m_invalidate_regs_map.end();
pos != end; ++pos) {
@@ -517,8 +533,8 @@ void DynamicRegisterInfo::Finalize(const ArchSpec &arch) {
m_regs[i].invalidate_regs = NULL;
}
- // Check if we need to automatically set the generic registers in case
- // they weren't set
+ // Check if we need to automatically set the generic registers in case they
+ // weren't set
bool generic_regs_specified = false;
for (const auto &reg : m_regs) {
if (reg.kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM) {
@@ -730,11 +746,11 @@ void DynamicRegisterInfo::Dump() const {
}
}
-lldb_private::RegisterInfo *DynamicRegisterInfo::GetRegisterInfo(
- const lldb_private::ConstString &reg_name) {
+const lldb_private::RegisterInfo *DynamicRegisterInfo::GetRegisterInfo(
+ const lldb_private::ConstString &reg_name) const {
for (auto &reg_info : m_regs) {
- // We can use pointer comparison since we used a ConstString to set
- // the "name" member in AddRegister()
+ // We can use pointer comparison since we used a ConstString to set the
+ // "name" member in AddRegister()
if (reg_info.name == reg_name.GetCString()) {
return &reg_info;
}
diff --git a/source/Plugins/Process/Utility/DynamicRegisterInfo.h b/source/Plugins/Process/Utility/DynamicRegisterInfo.h
index 228acfbed4ee..acb3e3eb8a84 100644
--- a/source/Plugins/Process/Utility/DynamicRegisterInfo.h
+++ b/source/Plugins/Process/Utility/DynamicRegisterInfo.h
@@ -23,12 +23,18 @@
class DynamicRegisterInfo {
public:
- DynamicRegisterInfo();
+ DynamicRegisterInfo() = default;
DynamicRegisterInfo(const lldb_private::StructuredData::Dictionary &dict,
const lldb_private::ArchSpec &arch);
- virtual ~DynamicRegisterInfo();
+ virtual ~DynamicRegisterInfo() = default;
+
+ DynamicRegisterInfo(DynamicRegisterInfo &) = delete;
+ void operator=(DynamicRegisterInfo &) = delete;
+
+ DynamicRegisterInfo(DynamicRegisterInfo &&info);
+ DynamicRegisterInfo &operator=(DynamicRegisterInfo &&info);
size_t SetRegisterInfo(const lldb_private::StructuredData::Dictionary &dict,
const lldb_private::ArchSpec &arch);
@@ -75,8 +81,10 @@ protected:
typedef std::vector<uint8_t> dwarf_opcode;
typedef std::map<uint32_t, dwarf_opcode> dynamic_reg_size_map;
- lldb_private::RegisterInfo *
- GetRegisterInfo(const lldb_private::ConstString &reg_name);
+ const lldb_private::RegisterInfo *
+ GetRegisterInfo(const lldb_private::ConstString &reg_name) const;
+
+ void MoveFrom(DynamicRegisterInfo &&info);
reg_collection m_regs;
set_collection m_sets;
@@ -85,9 +93,8 @@ protected:
reg_to_regs_map m_value_regs_map;
reg_to_regs_map m_invalidate_regs_map;
dynamic_reg_size_map m_dynamic_reg_size_map;
- size_t m_reg_data_byte_size; // The number of bytes required to store all
- // registers
- bool m_finalized;
+ size_t m_reg_data_byte_size = 0u; // The number of bytes required to store
+ // all registers
+ bool m_finalized = false;
};
-
#endif // lldb_DynamicRegisterInfo_h_
diff --git a/source/Plugins/Process/Utility/HistoryThread.h b/source/Plugins/Process/Utility/HistoryThread.h
index 363ba2669637..7675a95246a7 100644
--- a/source/Plugins/Process/Utility/HistoryThread.h
+++ b/source/Plugins/Process/Utility/HistoryThread.h
@@ -29,13 +29,13 @@ namespace lldb_private {
//----------------------------------------------------------------------
/// @class HistoryThread HistoryThread.h "HistoryThread.h"
-/// @brief A thread object representing a backtrace from a previous point in the
+/// A thread object representing a backtrace from a previous point in the
/// process execution
///
/// This subclass of Thread is used to provide a backtrace from earlier in
/// process execution. It is given a backtrace list of pc addresses and
-/// optionally a stop_id of when those pc addresses were collected, and it will
-/// create stack frames for them.
+/// optionally a stop_id of when those pc addresses were collected, and it
+/// will create stack frames for them.
//----------------------------------------------------------------------
class HistoryThread : public lldb_private::Thread {
diff --git a/source/Plugins/Process/Utility/InstructionUtils.h b/source/Plugins/Process/Utility/InstructionUtils.h
index e422a96200c8..186d525ce499 100644
--- a/source/Plugins/Process/Utility/InstructionUtils.h
+++ b/source/Plugins/Process/Utility/InstructionUtils.h
@@ -10,6 +10,9 @@
#ifndef lldb_InstructionUtils_h_
#define lldb_InstructionUtils_h_
+#include <cassert>
+#include <cstdint>
+
// Common utilities for manipulating instruction bit fields.
namespace lldb_private {
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwinConstants.h b/source/Plugins/Process/Utility/RegisterContextDarwinConstants.h
new file mode 100644
index 000000000000..ff57464be2de
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContextDarwinConstants.h
@@ -0,0 +1,26 @@
+//===-- RegisterContextDarwinConstants.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_REGISTERCONTEXTDARWINCONSTANTS_H
+#define LLDB_REGISTERCONTEXTDARWINCONSTANTS_H
+
+namespace lldb_private {
+
+/// Constants returned by various RegisterContextDarwin_*** functions.
+#ifndef KERN_SUCCESS
+#define KERN_SUCCESS 0
+#endif
+
+#ifndef KERN_INVALID_ARGUMENT
+#define KERN_INVALID_ARGUMENT 4
+#endif
+
+} // namespace lldb_private
+
+#endif // LLDB_REGISTERCONTEXTDARWINCONSTANTS_H
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
index 64a697ff53c8..5d9ff02fafdd 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
@@ -7,13 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#if defined(__APPLE__)
-
#include "RegisterContextDarwin_arm.h"
-
-// C Includes
-#include <mach/mach_types.h>
-#include <mach/thread_act.h>
+#include "RegisterContextDarwinConstants.h"
// C++ Includes
// Other libraries and framework includes
@@ -34,7 +29,7 @@
#endif
// Project includes
-#include "ARM_DWARF_Registers.h"
+#include "Utility/ARM_DWARF_Registers.h"
#include "Utility/ARM_ehframe_Registers.h"
#include "llvm/ADT/STLExtras.h"
@@ -968,9 +963,9 @@ const size_t k_num_fpu_registers = llvm::array_lengthof(g_fpu_regnums);
const size_t k_num_exc_registers = llvm::array_lengthof(g_exc_regnums);
//----------------------------------------------------------------------
-// Register set definitions. The first definitions at register set index
-// of zero is for all registers, followed by other registers sets. The
-// register information for the all register set need not be filled in.
+// Register set definitions. The first definitions at register set index of
+// zero is for all registers, followed by other registers sets. The register
+// information for the all register set need not be filled in.
//----------------------------------------------------------------------
static const RegisterSet g_reg_sets[] = {
{
@@ -1510,7 +1505,7 @@ uint32_t RegisterContextDarwin_arm::ConvertRegisterKindToRegisterNumber(
}
uint32_t RegisterContextDarwin_arm::NumSupportedHardwareBreakpoints() {
-#if defined(__arm__)
+#if defined(__APPLE__) && defined(__arm__)
// Set the init value to something that will let us know that we need to
// autodetect how many breakpoints are supported dynamically...
static uint32_t g_num_supported_hw_breakpoints = UINT32_MAX;
@@ -1642,7 +1637,7 @@ bool RegisterContextDarwin_arm::ClearHardwareBreakpoint(uint32_t hw_index) {
}
uint32_t RegisterContextDarwin_arm::NumSupportedHardwareWatchpoints() {
-#if defined(__arm__)
+#if defined(__APPLE__) && defined(__arm__)
// Set the init value to something that will let us know that we need to
// autodetect how many watchpoints are supported dynamically...
static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX;
@@ -1766,5 +1761,3 @@ bool RegisterContextDarwin_arm::ClearHardwareWatchpoint(uint32_t hw_index) {
}
return false;
}
-
-#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
index 344c08965fad..03ce7ef9f524 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
@@ -8,14 +8,8 @@
//
//===----------------------------------------------------------------------===//
-#if defined(__APPLE__)
-
#include "RegisterContextDarwin_arm64.h"
-
-// C Includes
-#include <mach/mach_types.h>
-#include <mach/thread_act.h>
-#include <sys/sysctl.h>
+#include "RegisterContextDarwinConstants.h"
// C++ Includes
// Other libraries and framework includes
@@ -39,7 +33,7 @@
#endif
// Project includes
-#include "ARM64_DWARF_Registers.h"
+#include "Utility/ARM64_DWARF_Registers.h"
using namespace lldb;
using namespace lldb_private;
@@ -149,9 +143,9 @@ const size_t k_num_fpu_registers = llvm::array_lengthof(g_fpu_regnums);
const size_t k_num_exc_registers = llvm::array_lengthof(g_exc_regnums);
//----------------------------------------------------------------------
-// Register set definitions. The first definitions at register set index
-// of zero is for all registers, followed by other registers sets. The
-// register information for the all register set need not be filled in.
+// Register set definitions. The first definitions at register set index of
+// zero is for all registers, followed by other registers sets. The register
+// information for the all register set need not be filled in.
//----------------------------------------------------------------------
static const RegisterSet g_reg_sets[] = {
{
@@ -299,8 +293,9 @@ int RegisterContextDarwin_arm64::WriteRegisterSet(uint32_t set) {
void RegisterContextDarwin_arm64::LogDBGRegisters(Log *log, const DBG &dbg) {
if (log) {
for (uint32_t i = 0; i < 16; i++)
- log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8llx, 0x%8.8llx } WVR%-2u/WCR%-2u "
- "= { 0x%8.8llx, 0x%8.8llx }",
+ log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8" PRIu64 ", 0x%8.8" PRIu64
+ " } WVR%-2u/WCR%-2u "
+ "= { 0x%8.8" PRIu64 ", 0x%8.8" PRIu64 " }",
i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]);
}
}
@@ -921,7 +916,7 @@ uint32_t RegisterContextDarwin_arm64::ConvertRegisterKindToRegisterNumber(
}
uint32_t RegisterContextDarwin_arm64::NumSupportedHardwareWatchpoints() {
-#if defined(__arm64__) || defined(__aarch64__)
+#if defined(__APPLE__) && (defined(__arm64__) || defined(__aarch64__))
// autodetect how many watchpoints are supported dynamically...
static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX;
if (g_num_supported_hw_watchpoints == UINT32_MAX) {
@@ -1043,5 +1038,3 @@ bool RegisterContextDarwin_arm64::ClearHardwareWatchpoint(uint32_t hw_index) {
}
return false;
}
-
-#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
index c818fad9ac0e..24414211d9aa 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
@@ -147,9 +147,9 @@ enum {
sizeof(RegisterContextDarwin_i386::FPU))
// These macros will auto define the register name, alt name, register size,
-// register offset, encoding, format and native register. This ensures that
-// the register state structures are defined correctly and have the correct
-// sizes and offsets.
+// register offset, encoding, format and native register. This ensures that the
+// register state structures are defined correctly and have the correct sizes
+// and offsets.
#define DEFINE_GPR(reg, alt) \
#reg, alt, sizeof(((RegisterContextDarwin_i386::GPR *) NULL)->reg), \
GPR_OFFSET(reg), eEncodingUint, eFormatHex
@@ -464,9 +464,9 @@ const size_t k_num_fpu_registers = llvm::array_lengthof(g_fpu_regnums);
const size_t k_num_exc_registers = llvm::array_lengthof(g_exc_regnums);
//----------------------------------------------------------------------
-// Register set definitions. The first definitions at register set index
-// of zero is for all registers, followed by other registers sets. The
-// register information for the all register set need not be filled in.
+// Register set definitions. The first definitions at register set index of
+// zero is for all registers, followed by other registers sets. The register
+// information for the all register set need not be filled in.
//----------------------------------------------------------------------
static const RegisterSet g_reg_sets[] = {
{
@@ -680,8 +680,7 @@ bool RegisterContextDarwin_i386::ReadRegister(const RegisterInfo *reg_info,
case fpu_stmm6:
case fpu_stmm7:
// These values don't fit into scalar types,
- // RegisterContext::ReadRegisterBytes() must be used for these
- // registers
+ // RegisterContext::ReadRegisterBytes() must be used for these registers
//::memcpy (reg_value.value.vector.uint8, fpu.stmm[reg - fpu_stmm0].bytes,
//10);
return false;
@@ -695,8 +694,7 @@ bool RegisterContextDarwin_i386::ReadRegister(const RegisterInfo *reg_info,
case fpu_xmm6:
case fpu_xmm7:
// These values don't fit into scalar types,
- // RegisterContext::ReadRegisterBytes()
- // must be used for these registers
+ // RegisterContext::ReadRegisterBytes() must be used for these registers
//::memcpy (reg_value.value.vector.uint8, fpu.xmm[reg - fpu_xmm0].bytes,
//16);
return false;
@@ -799,8 +797,7 @@ bool RegisterContextDarwin_i386::WriteRegister(const RegisterInfo *reg_info,
case fpu_stmm6:
case fpu_stmm7:
// These values don't fit into scalar types,
- // RegisterContext::ReadRegisterBytes()
- // must be used for these registers
+ // RegisterContext::ReadRegisterBytes() must be used for these registers
::memcpy(fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(),
value.GetByteSize());
return false;
@@ -814,8 +811,7 @@ bool RegisterContextDarwin_i386::WriteRegister(const RegisterInfo *reg_info,
case fpu_xmm6:
case fpu_xmm7:
// These values don't fit into scalar types,
- // RegisterContext::ReadRegisterBytes()
- // must be used for these registers
+ // RegisterContext::ReadRegisterBytes() must be used for these registers
::memcpy(fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(),
value.GetByteSize());
return false;
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
index 50e7292f86b1..ecad8240b294 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
@@ -165,9 +165,9 @@ enum ehframe_dwarf_regnums {
sizeof(RegisterContextDarwin_x86_64::FPU))
// These macros will auto define the register name, alt name, register size,
-// register offset, encoding, format and native register. This ensures that
-// the register state structures are defined correctly and have the correct
-// sizes and offsets.
+// register offset, encoding, format and native register. This ensures that the
+// register state structures are defined correctly and have the correct sizes
+// and offsets.
#define DEFINE_GPR(reg, alt) \
#reg, alt, sizeof(((RegisterContextDarwin_x86_64::GPR *) NULL)->reg), \
GPR_OFFSET(reg), eEncodingUint, eFormatHex
@@ -525,9 +525,9 @@ const size_t k_num_fpu_registers = llvm::array_lengthof(g_fpu_regnums);
const size_t k_num_exc_registers = llvm::array_lengthof(g_exc_regnums);
//----------------------------------------------------------------------
-// Register set definitions. The first definitions at register set index
-// of zero is for all registers, followed by other registers sets. The
-// register information for the all register set need not be filled in.
+// Register set definitions. The first definitions at register set index of
+// zero is for all registers, followed by other registers sets. The register
+// information for the all register set need not be filled in.
//----------------------------------------------------------------------
static const RegisterSet g_reg_sets[] = {
{
diff --git a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index 5435a02433ab..ba9a8071bcfb 100644
--- a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -104,8 +104,7 @@ bool RegisterContextLLDB::IsUnwindPlanValidForCurrentPC(
}
// Initialize a RegisterContextLLDB which is the first frame of a stack -- the
-// zeroth frame or currently
-// executing frame.
+// zeroth frame or currently executing frame.
void RegisterContextLLDB::InitializeZerothFrame() {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
@@ -131,25 +130,26 @@ void RegisterContextLLDB::InitializeZerothFrame() {
// Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs
// this will strip bit zero in case we read a PC from memory or from the LR.
// (which would be a no-op in frame 0 where we get it from the register set,
- // but still a good idea to make the call here for other ABIs that may exist.)
+ // but still a good idea to make the call here for other ABIs that may
+ // exist.)
ABI *abi = process->GetABI().get();
if (abi)
current_pc = abi->FixCodeAddress(current_pc);
- // Initialize m_current_pc, an Address object, based on current_pc, an addr_t.
+ // Initialize m_current_pc, an Address object, based on current_pc, an
+ // addr_t.
m_current_pc.SetLoadAddress(current_pc, &process->GetTarget());
// If we don't have a Module for some reason, we're not going to find
- // symbol/function information - just
- // stick in some reasonable defaults and hope we can unwind past this frame.
+ // symbol/function information - just stick in some reasonable defaults and
+ // hope we can unwind past this frame.
ModuleSP pc_module_sp(m_current_pc.GetModule());
if (!m_current_pc.IsValid() || !pc_module_sp) {
UnwindLogMsg("using architectural default unwind method");
}
// We require either a symbol or function in the symbols context to be
- // successfully
- // filled in or this context is of no use to us.
+ // successfully filled in or this context is of no use to us.
const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
if (pc_module_sp.get() && (pc_module_sp->ResolveSymbolContextForAddress(
m_current_pc, resolve_scope, m_sym_ctx) &
@@ -180,18 +180,17 @@ void RegisterContextLLDB::InitializeZerothFrame() {
}
// If we were able to find a symbol/function, set addr_range to the bounds of
- // that symbol/function.
- // else treat the current pc value as the start_pc and record no offset.
+ // that symbol/function. else treat the current pc value as the start_pc and
+ // record no offset.
if (addr_range.GetBaseAddress().IsValid()) {
m_start_pc = addr_range.GetBaseAddress();
if (m_current_pc.GetSection() == m_start_pc.GetSection()) {
m_current_offset = m_current_pc.GetOffset() - m_start_pc.GetOffset();
} else if (m_current_pc.GetModule() == m_start_pc.GetModule()) {
- // This means that whatever symbol we kicked up isn't really correct
- // --- we should not cross section boundaries ... We really should NULL
- // out
- // the function/symbol in this case unless there is a bad assumption
- // here due to inlined functions?
+ // This means that whatever symbol we kicked up isn't really correct ---
+ // we should not cross section boundaries ... We really should NULL out
+ // the function/symbol in this case unless there is a bad assumption here
+ // due to inlined functions?
m_current_offset =
m_current_pc.GetFileAddress() - m_start_pc.GetFileAddress();
}
@@ -266,8 +265,7 @@ void RegisterContextLLDB::InitializeZerothFrame() {
}
// Initialize a RegisterContextLLDB for the non-zeroth frame -- rely on the
-// RegisterContextLLDB "below" it
-// to provide things like its current pc value.
+// RegisterContextLLDB "below" it to provide things like its current pc value.
void RegisterContextLLDB::InitializeNonZerothFrame() {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
@@ -333,8 +331,8 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
m_current_pc.SetLoadAddress(pc, &process->GetTarget(), allow_section_end);
// If we don't have a Module for some reason, we're not going to find
- // symbol/function information - just
- // stick in some reasonable defaults and hope we can unwind past this frame.
+ // symbol/function information - just stick in some reasonable defaults and
+ // hope we can unwind past this frame.
ModuleSP pc_module_sp(m_current_pc.GetModule());
if (!m_current_pc.IsValid() || !pc_module_sp) {
UnwindLogMsg("using architectural default unwind method");
@@ -345,12 +343,10 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
if (process->GetLoadAddressPermissions(pc, permissions) &&
(permissions & ePermissionsExecutable) == 0) {
// If this is the second frame off the stack, we may have unwound the
- // first frame
- // incorrectly. But using the architecture default unwind plan may get us
- // back on
- // track -- albeit possibly skipping a real frame. Give this frame a
- // clearly-invalid
- // pc and see if we can get any further.
+ // first frame incorrectly. But using the architecture default unwind
+ // plan may get us back on track -- albeit possibly skipping a real
+ // frame. Give this frame a clearly-invalid pc and see if we can get any
+ // further.
if (GetNextFrame().get() && GetNextFrame()->IsValid() &&
GetNextFrame()->IsFrameZero()) {
UnwindLogMsg("had a pc of 0x%" PRIx64 " which is not in executable "
@@ -359,8 +355,8 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
(uint64_t)pc);
m_frame_type = eSkipFrame;
} else {
- // anywhere other than the second frame, a non-executable pc means we're
- // off in the weeds -- stop now.
+ // anywhere other than the second frame, a non-executable pc means
+ // we're off in the weeds -- stop now.
m_frame_type = eNotAValidFrame;
UnwindLogMsg("pc is in a non-executable section of memory and this "
"isn't the 2nd frame in the stack walk.");
@@ -399,8 +395,7 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
}
// m_cfa should point into the stack memory; if we can query memory
- // region permissions,
- // see if the memory is allocated & readable.
+ // region permissions, see if the memory is allocated & readable.
if (process->GetLoadAddressPermissions(m_cfa, permissions) &&
(permissions & ePermissionsReadable) == 0) {
m_frame_type = eNotAValidFrame;
@@ -435,19 +430,18 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
bool resolve_tail_call_address = false; // m_current_pc can be one past the
// address range of the function...
- // If the saved pc does not point to a function/symbol because it is
- // beyond the bounds of the correct function and there's no symbol there,
- // we do *not* want ResolveSymbolContextForAddress to back up the pc by 1,
- // because then we might not find the correct unwind information later.
- // Instead, let ResolveSymbolContextForAddress fail, and handle the case
- // via decr_pc_and_recompute_addr_range below.
+ // If the saved pc does not point to a function/symbol because it is beyond
+ // the bounds of the correct function and there's no symbol there, we do
+ // *not* want ResolveSymbolContextForAddress to back up the pc by 1, because
+ // then we might not find the correct unwind information later. Instead, let
+ // ResolveSymbolContextForAddress fail, and handle the case via
+ // decr_pc_and_recompute_addr_range below.
const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
uint32_t resolved_scope = pc_module_sp->ResolveSymbolContextForAddress(
m_current_pc, resolve_scope, m_sym_ctx, resolve_tail_call_address);
// We require either a symbol or function in the symbols context to be
- // successfully
- // filled in or this context is of no use to us.
+ // successfully filled in or this context is of no use to us.
if (resolve_scope & resolved_scope) {
m_sym_ctx_valid = true;
}
@@ -476,8 +470,7 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
decr_pc_and_recompute_addr_range = true;
// Or if we're in the middle of the stack (and not "above" an asynchronous
- // event like sigtramp),
- // and our "current" pc is the start of a function...
+ // event like sigtramp), and our "current" pc is the start of a function...
if (GetNextFrame()->m_frame_type != eTrapHandlerFrame &&
GetNextFrame()->m_frame_type != eDebuggerFrame &&
(!m_sym_ctx_valid ||
@@ -488,9 +481,8 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
}
// We need to back up the pc by 1 byte and re-search for the Symbol to handle
- // the case where the "saved pc"
- // value is pointing to the next function, e.g. if a function ends with a CALL
- // instruction.
+ // the case where the "saved pc" value is pointing to the next function, e.g.
+ // if a function ends with a CALL instruction.
// FIXME this may need to be an architectural-dependent behavior; if so we'll
// need to add a member function
// to the ABI plugin and consult that.
@@ -516,9 +508,9 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
}
- // If we were able to find a symbol/function, set addr_range_ptr to the bounds
- // of that symbol/function.
- // else treat the current pc value as the start_pc and record no offset.
+ // If we were able to find a symbol/function, set addr_range_ptr to the
+ // bounds of that symbol/function. else treat the current pc value as the
+ // start_pc and record no offset.
if (addr_range.GetBaseAddress().IsValid()) {
m_start_pc = addr_range.GetBaseAddress();
m_current_offset = pc - m_start_pc.GetLoadAddress(&process->GetTarget());
@@ -553,9 +545,8 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
RegisterKind row_register_kind = eRegisterKindGeneric;
// Try to get by with just the fast UnwindPlan if possible - the full
- // UnwindPlan may be expensive to get
- // (e.g. if we have to parse the entire eh_frame section of an ObjectFile for
- // the first time.)
+ // UnwindPlan may be expensive to get (e.g. if we have to parse the entire
+ // eh_frame section of an ObjectFile for the first time.)
if (m_fast_unwind_plan_sp &&
m_fast_unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
@@ -616,16 +607,14 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
bool RegisterContextLLDB::CheckIfLoopingStack() {
// If we have a bad stack setup, we can get the same CFA value multiple times
- // -- or even
- // more devious, we can actually oscillate between two CFA values. Detect that
- // here and
- // break out to avoid a possible infinite loop in lldb trying to unwind the
- // stack.
- // To detect when we have the same CFA value multiple times, we compare the
+ // -- or even more devious, we can actually oscillate between two CFA values.
+ // Detect that here and break out to avoid a possible infinite loop in lldb
+ // trying to unwind the stack. To detect when we have the same CFA value
+ // multiple times, we compare the
// CFA of the current
// frame with the 2nd next frame because in some specail case (e.g. signal
- // hanlders, hand
- // written assembly without ABI compiance) we can have 2 frames with the same
+ // hanlders, hand written assembly without ABI compiance) we can have 2
+ // frames with the same
// CFA (in theory we
// can have arbitrary number of frames with the same CFA, but more then 2 is
// very very unlikely)
@@ -734,15 +723,12 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
}
// If we've done a jmp 0x0 / bl 0x0 (called through a null function pointer)
- // so the pc is 0x0
- // in the zeroth frame, we need to use the "unwind at first instruction" arch
- // default UnwindPlan
- // Also, if this Process can report on memory region attributes, any
- // non-executable region means
- // we jumped through a bad function pointer - handle the same way as 0x0.
- // Note, if we have a symbol context & a symbol, we don't want to follow this
- // code path. This is
- // for jumping to memory regions without any information available.
+ // so the pc is 0x0 in the zeroth frame, we need to use the "unwind at first
+ // instruction" arch default UnwindPlan Also, if this Process can report on
+ // memory region attributes, any non-executable region means we jumped
+ // through a bad function pointer - handle the same way as 0x0. Note, if we
+ // have a symbol context & a symbol, we don't want to follow this code path.
+ // This is for jumping to memory regions without any information available.
if ((!m_sym_ctx_valid ||
(m_sym_ctx.function == NULL && m_sym_ctx.symbol == NULL)) &&
@@ -780,12 +766,10 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
}
// No FuncUnwinders available for this pc (stripped function symbols, lldb
- // could not augment its
- // function table with another source, like LC_FUNCTION_STARTS or eh_frame in
- // ObjectFileMachO).
- // See if eh_frame or the .ARM.exidx tables have unwind information for this
- // address, else fall
- // back to the architectural default unwind.
+ // could not augment its function table with another source, like
+ // LC_FUNCTION_STARTS or eh_frame in ObjectFileMachO). See if eh_frame or the
+ // .ARM.exidx tables have unwind information for this address, else fall back
+ // to the architectural default unwind.
if (!func_unwinders_sp) {
m_frame_type = eNormalFrame;
@@ -793,7 +777,8 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
!m_current_pc.IsValid())
return arch_default_unwind_plan_sp;
- // Even with -fomit-frame-pointer, we can try eh_frame to get back on track.
+ // Even with -fomit-frame-pointer, we can try eh_frame to get back on
+ // track.
DWARFCallFrameInfo *eh_frame =
pc_module_sp->GetObjectFile()->GetUnwindTable().GetEHFrameInfo();
if (eh_frame) {
@@ -819,11 +804,10 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
}
// If we're in _sigtramp(), unwinding past this frame requires special
- // knowledge. On Mac OS X this knowledge
- // is properly encoded in the eh_frame section, so prefer that if available.
- // On other platforms we may need to provide a platform-specific UnwindPlan
- // which encodes the details of
- // how to unwind out of sigtramp.
+ // knowledge. On Mac OS X this knowledge is properly encoded in the eh_frame
+ // section, so prefer that if available. On other platforms we may need to
+ // provide a platform-specific UnwindPlan which encodes the details of how to
+ // unwind out of sigtramp.
if (m_frame_type == eTrapHandlerFrame && process) {
m_fast_unwind_plan_sp.reset();
unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan(
@@ -835,24 +819,19 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
}
// Ask the DynamicLoader if the eh_frame CFI should be trusted in this frame
- // even when it's frame zero
- // This comes up if we have hand-written functions in a Module and
- // hand-written eh_frame. The assembly
- // instruction inspection may fail and the eh_frame CFI were probably written
- // with some care to do the
- // right thing. It'd be nice if there was a way to ask the eh_frame directly
- // if it is asynchronous
- // (can be trusted at every instruction point) or synchronous (the normal case
- // - only at call sites).
+ // even when it's frame zero This comes up if we have hand-written functions
+ // in a Module and hand-written eh_frame. The assembly instruction
+ // inspection may fail and the eh_frame CFI were probably written with some
+ // care to do the right thing. It'd be nice if there was a way to ask the
+ // eh_frame directly if it is asynchronous (can be trusted at every
+ // instruction point) or synchronous (the normal case - only at call sites).
// But there is not.
if (process && process->GetDynamicLoader() &&
process->GetDynamicLoader()->AlwaysRelyOnEHUnwindInfo(m_sym_ctx)) {
// We must specifically call the GetEHFrameUnwindPlan() method here --
- // normally we would
- // call GetUnwindPlanAtCallSite() -- because CallSite may return an unwind
- // plan sourced from
- // either eh_frame (that's what we intend) or compact unwind (this won't
- // work)
+ // normally we would call GetUnwindPlanAtCallSite() -- because CallSite may
+ // return an unwind plan sourced from either eh_frame (that's what we
+ // intend) or compact unwind (this won't work)
unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan(
process->GetTarget(), m_current_offset_backed_up_one);
if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
@@ -871,22 +850,16 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
if (unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) {
// We probably have an UnwindPlan created by inspecting assembly
- // instructions. The
- // assembly profilers work really well with compiler-generated functions
- // but hand-
- // written assembly can be problematic. We set the eh_frame based unwind
- // plan as our
- // fallback unwind plan if instruction emulation doesn't work out even
- // for non call
- // sites if it is available and use the architecture default unwind plan
- // if it is
+ // instructions. The assembly profilers work really well with compiler-
+ // generated functions but hand- written assembly can be problematic.
+ // We set the eh_frame based unwind plan as our fallback unwind plan if
+ // instruction emulation doesn't work out even for non call sites if it
+ // is available and use the architecture default unwind plan if it is
// not available. The eh_frame unwind plan is more reliable even on non
- // call sites
- // then the architecture default plan and for hand written assembly code
- // it is often
- // written in a way that it valid at all location what helps in the most
- // common
- // cases when the instruction emulation fails.
+ // call sites then the architecture default plan and for hand written
+ // assembly code it is often written in a way that it valid at all
+ // location what helps in the most common cases when the instruction
+ // emulation fails.
UnwindPlanSP call_site_unwind_plan =
func_unwinders_sp->GetUnwindPlanAtCallSite(
process->GetTarget(), m_current_offset_backed_up_one);
@@ -919,9 +892,8 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
}
// We'd prefer to use an UnwindPlan intended for call sites when we're at a
- // call site but if we've
- // struck out on that, fall back to using the non-call-site assembly
- // inspection UnwindPlan if possible.
+ // call site but if we've struck out on that, fall back to using the non-
+ // call-site assembly inspection UnwindPlan if possible.
if (process) {
unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite(
process->GetTarget(), m_thread, m_current_offset_backed_up_one);
@@ -929,19 +901,14 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
if (unwind_plan_sp &&
unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) {
// We probably have an UnwindPlan created by inspecting assembly
- // instructions. The assembly
- // profilers work really well with compiler-generated functions but hand-
- // written assembly
- // can be problematic. We set the eh_frame based unwind plan as our fallback
- // unwind plan if
+ // instructions. The assembly profilers work really well with compiler-
+ // generated functions but hand- written assembly can be problematic. We
+ // set the eh_frame based unwind plan as our fallback unwind plan if
// instruction emulation doesn't work out even for non call sites if it is
- // available and use
- // the architecture default unwind plan if it is not available. The eh_frame
- // unwind plan is
- // more reliable even on non call sites then the architecture default plan
- // and for hand
- // written assembly code it is often written in a way that it valid at all
- // location what
+ // available and use the architecture default unwind plan if it is not
+ // available. The eh_frame unwind plan is more reliable even on non call
+ // sites then the architecture default plan and for hand written assembly
+ // code it is often written in a way that it valid at all location what
// helps in the most common cases when the instruction emulation fails.
UnwindPlanSP call_site_unwind_plan =
func_unwinders_sp->GetUnwindPlanAtCallSite(
@@ -963,8 +930,8 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
}
// If we're on the first instruction of a function, and we have an
- // architectural default UnwindPlan
- // for the initial instruction of a function, use that.
+ // architectural default UnwindPlan for the initial instruction of a
+ // function, use that.
if (m_current_offset_backed_up_one == 0) {
unwind_plan_sp =
func_unwinders_sp->GetUnwindPlanArchitectureDefaultAtFunctionEntry(
@@ -1115,12 +1082,10 @@ bool RegisterContextLLDB::IsValid() const {
}
// After the final stack frame in a stack walk we'll get one invalid
-// (eNotAValidFrame) stack frame --
-// one past the end of the stack walk. But higher-level code will need to tell
-// the differnece between
-// "the unwind plan below this frame failed" versus "we successfully completed
-// the stack walk" so
-// this method helps to disambiguate that.
+// (eNotAValidFrame) stack frame -- one past the end of the stack walk. But
+// higher-level code will need to tell the differnece between "the unwind plan
+// below this frame failed" versus "we successfully completed the stack walk"
+// so this method helps to disambiguate that.
bool RegisterContextLLDB::IsTrapHandlerFrame() const {
return m_frame_type == eTrapHandlerFrame;
@@ -1129,12 +1094,10 @@ bool RegisterContextLLDB::IsTrapHandlerFrame() const {
// A skip frame is a bogus frame on the stack -- but one where we're likely to
// find a real frame farther
// up the stack if we keep looking. It's always the second frame in an unwind
-// (i.e. the first frame after
-// frame zero) where unwinding can be the trickiest. Ideally we'll mark up this
-// frame in some way so the
-// user knows we're displaying bad data and we may have skipped one frame of
-// their real program in the
-// process of getting back on track.
+// (i.e. the first frame after frame zero) where unwinding can be the
+// trickiest. Ideally we'll mark up this frame in some way so the user knows
+// we're displaying bad data and we may have skipped one frame of their real
+// program in the process of getting back on track.
bool RegisterContextLLDB::IsSkipFrame() const {
return m_frame_type == eSkipFrame;
@@ -1231,8 +1194,8 @@ RegisterContextLLDB::SavedLocationForRegister(
RegisterNumber return_address_reg;
// If we're fetching the saved pc and this UnwindPlan defines a
- // ReturnAddress register (e.g. lr on arm),
- // look for the return address register number in the UnwindPlan's row.
+ // ReturnAddress register (e.g. lr on arm), look for the return address
+ // register number in the UnwindPlan's row.
if (pc_regnum.IsValid() && pc_regnum == regnum &&
m_full_unwind_plan_sp->GetReturnAddressRegister() !=
LLDB_INVALID_REGNUM) {
@@ -1272,10 +1235,8 @@ RegisterContextLLDB::SavedLocationForRegister(
}
// This is frame 0 and we're retrieving the PC and it's saved in a Return
- // Address register and
- // it hasn't been saved anywhere yet -- that is, it's still live in the
- // actual register.
- // Handle this specially.
+ // Address register and it hasn't been saved anywhere yet -- that is,
+ // it's still live in the actual register. Handle this specially.
if (have_unwindplan_regloc == false && return_address_reg.IsValid() &&
IsFrameZero()) {
@@ -1298,22 +1259,18 @@ RegisterContextLLDB::SavedLocationForRegister(
}
// If this architecture stores the return address in a register (it
- // defines a Return Address register)
- // and we're on a non-zero stack frame and the Full UnwindPlan says that
- // the pc is stored in the
+ // defines a Return Address register) and we're on a non-zero stack frame
+ // and the Full UnwindPlan says that the pc is stored in the
// RA registers (e.g. lr on arm), then we know that the full unwindplan is
// not trustworthy -- this
// is an impossible situation and the instruction emulation code has
- // likely been misled.
- // If this stack frame meets those criteria, we need to throw away the
- // Full UnwindPlan that the
- // instruction emulation came up with and fall back to the architecture's
- // Default UnwindPlan so
- // the stack walk can get past this point.
+ // likely been misled. If this stack frame meets those criteria, we need
+ // to throw away the Full UnwindPlan that the instruction emulation came
+ // up with and fall back to the architecture's Default UnwindPlan so the
+ // stack walk can get past this point.
// Special note: If the Full UnwindPlan was generated from the compiler,
- // don't second-guess it
- // when we're at a call site location.
+ // don't second-guess it when we're at a call site location.
// arch_default_ra_regnum is the return address register # in the Full
// UnwindPlan register numbering
@@ -1376,11 +1333,10 @@ RegisterContextLLDB::SavedLocationForRegister(
ExecutionContext exe_ctx(m_thread.shared_from_this());
Process *process = exe_ctx.GetProcessPtr();
if (have_unwindplan_regloc == false) {
- // If the UnwindPlan failed to give us an unwind location for this register,
- // we may be able to fall back
- // to some ABI-defined default. For example, some ABIs allow to determine
- // the caller's SP via the CFA.
- // Also, the ABI may set volatile registers to the undefined state.
+ // If the UnwindPlan failed to give us an unwind location for this
+ // register, we may be able to fall back to some ABI-defined default. For
+ // example, some ABIs allow to determine the caller's SP via the CFA. Also,
+ // the ABI may set volatile registers to the undefined state.
ABI *abi = process ? process->GetABI().get() : NULL;
if (abi) {
const RegisterInfo *reg_info =
@@ -1558,24 +1514,19 @@ RegisterContextLLDB::SavedLocationForRegister(
// TryFallbackUnwindPlan() -- this method is a little tricky.
//
// When this is called, the frame above -- the caller frame, the "previous"
-// frame --
-// is invalid or bad.
+// frame -- is invalid or bad.
//
-// Instead of stopping the stack walk here, we'll try a different UnwindPlan and
-// see
-// if we can get a valid frame above us.
+// Instead of stopping the stack walk here, we'll try a different UnwindPlan
+// and see if we can get a valid frame above us.
//
// This most often happens when an unwind plan based on assembly instruction
-// inspection
-// is not correct -- mostly with hand-written assembly functions or functions
-// where the
-// stack frame is set up "out of band", e.g. the kernel saved the register
-// context and
-// then called an asynchronous trap handler like _sigtramp.
+// inspection is not correct -- mostly with hand-written assembly functions or
+// functions where the stack frame is set up "out of band", e.g. the kernel
+// saved the register context and then called an asynchronous trap handler like
+// _sigtramp.
//
// Often in these cases, if we just do a dumb stack walk we'll get past this
-// tricky
-// frame and our usual techniques can continue to be used.
+// tricky frame and our usual techniques can continue to be used.
bool RegisterContextLLDB::TryFallbackUnwindPlan() {
if (m_fallback_unwind_plan_sp.get() == nullptr)
@@ -1591,15 +1542,13 @@ bool RegisterContextLLDB::TryFallbackUnwindPlan() {
}
// If a compiler generated unwind plan failed, trying the arch default
- // unwindplan
- // isn't going to do any better.
+ // unwindplan isn't going to do any better.
if (m_full_unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes)
return false;
- // Get the caller's pc value and our own CFA value.
- // Swap in the fallback unwind plan, re-fetch the caller's pc value and CFA
- // value.
- // If they're the same, then the fallback unwind plan provides no benefit.
+ // Get the caller's pc value and our own CFA value. Swap in the fallback
+ // unwind plan, re-fetch the caller's pc value and CFA value. If they're the
+ // same, then the fallback unwind plan provides no benefit.
RegisterNumber pc_regnum(m_thread, eRegisterKindGeneric,
LLDB_REGNUM_GENERIC_PC);
@@ -1622,23 +1571,18 @@ bool RegisterContextLLDB::TryFallbackUnwindPlan() {
}
// This is a tricky wrinkle! If SavedLocationForRegister() detects a really
- // impossible
- // register location for the full unwind plan, it may call
- // ForceSwitchToFallbackUnwindPlan()
- // which in turn replaces the full unwindplan with the fallback... in short,
- // we're done,
- // we're using the fallback UnwindPlan.
- // We checked if m_fallback_unwind_plan_sp was nullptr at the top -- the only
- // way it
- // became nullptr since then is via SavedLocationForRegister().
+ // impossible register location for the full unwind plan, it may call
+ // ForceSwitchToFallbackUnwindPlan() which in turn replaces the full
+ // unwindplan with the fallback... in short, we're done, we're using the
+ // fallback UnwindPlan. We checked if m_fallback_unwind_plan_sp was nullptr
+ // at the top -- the only way it became nullptr since then is via
+ // SavedLocationForRegister().
if (m_fallback_unwind_plan_sp.get() == nullptr)
return true;
// Switch the full UnwindPlan to be the fallback UnwindPlan. If we decide
- // this isn't
- // working, we need to restore.
- // We'll also need to save & restore the value of the m_cfa ivar. Save is
- // down below a bit in 'old_cfa'.
+ // this isn't working, we need to restore. We'll also need to save & restore
+ // the value of the m_cfa ivar. Save is down below a bit in 'old_cfa'.
UnwindPlanSP original_full_unwind_plan_sp = m_full_unwind_plan_sp;
addr_t old_cfa = m_cfa;
@@ -2049,10 +1993,9 @@ bool RegisterContextLLDB::ReadPC(addr_t &pc) {
// A pc value of 0 or 1 is impossible in the middle of the stack -- it
// indicates the end of a stack walk.
// On the currently executing frame (or such a frame interrupted
- // asynchronously by sigtramp et al) this may
- // occur if code has jumped through a NULL pointer -- we want to be able to
- // unwind past that frame to help
- // find the bug.
+ // asynchronously by sigtramp et al) this may occur if code has jumped
+ // through a NULL pointer -- we want to be able to unwind past that frame
+ // to help find the bug.
ProcessSP process_sp (m_thread.GetProcess());
if (process_sp)
diff --git a/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp b/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp
index 2d24bdaed2cd..77c1bea34851 100644
--- a/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp
@@ -19,7 +19,7 @@
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/StreamString.h"
// Project includes
-#include "Utility/StringExtractorGDBRemote.h"
+#include "lldb/Utility/StringExtractorGDBRemote.h"
using namespace lldb;
using namespace lldb_private;
@@ -139,8 +139,8 @@ bool RegisterContextMacOSXFrameBackchain::ReadRegister(
bool RegisterContextMacOSXFrameBackchain::WriteRegister(
const RegisterInfo *reg_info, const RegisterValue &value) {
- // Not supported yet. We could easily add support for this by remembering
- // the address of each entry (it would need to be part of the cursor)
+ // Not supported yet. We could easily add support for this by remembering the
+ // address of each entry (it would need to be part of the cursor)
return false;
}
@@ -154,10 +154,10 @@ bool RegisterContextMacOSXFrameBackchain::ReadAllRegisterValues(
bool RegisterContextMacOSXFrameBackchain::WriteAllRegisterValues(
const lldb::DataBufferSP &data_sp) {
- // Since this class doesn't respond to "ReadAllRegisterValues()", it must
- // not have been the one that saved all the register values. So we just let
- // the thread's register context (the register context for frame zero) do
- // the writing.
+ // Since this class doesn't respond to "ReadAllRegisterValues()", it must not
+ // have been the one that saved all the register values. So we just let the
+ // thread's register context (the register context for frame zero) do the
+ // writing.
return m_thread.GetRegisterContext()->WriteAllRegisterValues(data_sp);
}
diff --git a/source/Plugins/Process/Utility/RegisterContextMemory.cpp b/source/Plugins/Process/Utility/RegisterContextMemory.cpp
index 8f0dfd2a5b50..76189ea781de 100644
--- a/source/Plugins/Process/Utility/RegisterContextMemory.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextMemory.cpp
@@ -32,9 +32,9 @@ RegisterContextMemory::RegisterContextMemory(Thread &thread,
addr_t reg_data_addr)
: RegisterContext(thread, concrete_frame_idx), m_reg_infos(reg_infos),
m_reg_valid(), m_reg_data(), m_reg_data_addr(reg_data_addr) {
- // Resize our vector of bools to contain one bool for every register.
- // We will use these boolean values to know when a register value
- // is valid in m_reg_data.
+ // Resize our vector of bools to contain one bool for every register. We will
+ // use these boolean values to know when a register value is valid in
+ // m_reg_data.
const size_t num_regs = reg_infos.GetNumRegisters();
assert(num_regs > 0);
m_reg_valid.resize(num_regs);
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
index bb3509330eec..352e251e3b64 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
@@ -13,6 +13,7 @@
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
+#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
@@ -20,7 +21,6 @@
#include "lldb/Utility/Endian.h"
#include "llvm/Support/Compiler.h"
-#include "Plugins/Process/elf-core/ProcessElfCore.h"
#include "RegisterContextPOSIX_arm.h"
using namespace lldb;
@@ -107,11 +107,6 @@ RegisterContextPOSIX_arm::RegisterContextPOSIX_arm(
}
::memset(&m_fpr, 0, sizeof m_fpr);
-
- // elf-core yet to support ReadFPR()
- lldb::ProcessSP base = CalculateProcess();
- if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
- return;
}
RegisterContextPOSIX_arm::~RegisterContextPOSIX_arm() {}
@@ -142,8 +137,8 @@ size_t RegisterContextPOSIX_arm::GetGPRSize() {
const lldb_private::RegisterInfo *RegisterContextPOSIX_arm::GetRegisterInfo() {
// Commonly, this method is overridden and g_register_infos is copied and
- // specialized.
- // So, use GetRegisterInfo() rather than g_register_infos in this scope.
+ // specialized. So, use GetRegisterInfo() rather than g_register_infos in
+ // this scope.
return m_register_info_ap->GetRegisterInfo();
}
@@ -199,8 +194,8 @@ bool RegisterContextPOSIX_arm::IsRegisterSetAvailable(size_t set_index) {
return set_index < k_num_register_sets;
}
-// Used when parsing DWARF and EH frame information and any other
-// object file sections that contain register numbers in them.
+// Used when parsing DWARF and EH frame information and any other object file
+// sections that contain register numbers in them.
uint32_t RegisterContextPOSIX_arm::ConvertRegisterKindToRegisterNumber(
lldb::RegisterKind kind, uint32_t num) {
const uint32_t num_regs = GetRegisterCount();
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
index 89384c8f5190..3ff93cde2347 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
@@ -13,6 +13,7 @@
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
+#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
@@ -20,7 +21,6 @@
#include "lldb/Utility/Endian.h"
#include "llvm/Support/Compiler.h"
-#include "Plugins/Process/elf-core/ProcessElfCore.h"
#include "RegisterContextPOSIX_arm64.h"
using namespace lldb;
@@ -126,11 +126,6 @@ RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64(
}
::memset(&m_fpr, 0, sizeof m_fpr);
-
- // elf-core yet to support ReadFPR()
- lldb::ProcessSP base = CalculateProcess();
- if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
- return;
}
RegisterContextPOSIX_arm64::~RegisterContextPOSIX_arm64() {}
@@ -162,8 +157,8 @@ size_t RegisterContextPOSIX_arm64::GetGPRSize() {
const lldb_private::RegisterInfo *
RegisterContextPOSIX_arm64::GetRegisterInfo() {
// Commonly, this method is overridden and g_register_infos is copied and
- // specialized.
- // So, use GetRegisterInfo() rather than g_register_infos in this scope.
+ // specialized. So, use GetRegisterInfo() rather than g_register_infos in
+ // this scope.
return m_register_info_ap->GetRegisterInfo();
}
@@ -219,8 +214,8 @@ bool RegisterContextPOSIX_arm64::IsRegisterSetAvailable(size_t set_index) {
return set_index < k_num_register_sets;
}
-// Used when parsing DWARF and EH frame information and any other
-// object file sections that contain register numbers in them.
+// Used when parsing DWARF and EH frame information and any other object file
+// sections that contain register numbers in them.
uint32_t RegisterContextPOSIX_arm64::ConvertRegisterKindToRegisterNumber(
lldb::RegisterKind kind, uint32_t num) {
const uint32_t num_regs = GetRegisterCount();
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp
index 6a55947ba5c2..98d1e6fa8817 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp
@@ -13,6 +13,7 @@
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
+#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
@@ -20,11 +21,10 @@
#include "lldb/Utility/Endian.h"
#include "llvm/Support/Compiler.h"
-#include "Plugins/Process/elf-core/ProcessElfCore.h"
#include "RegisterContextPOSIX_mips64.h"
#include "RegisterContextFreeBSD_mips64.h"
#include "RegisterContextLinux_mips64.h"
-#include "RegisterContextLinux_mips.h"
+#include "RegisterContextLinux_mips.h"
using namespace lldb_private;
using namespace lldb;
@@ -59,11 +59,6 @@ RegisterContextPOSIX_mips64::RegisterContextPOSIX_mips64(
static_cast<uint32_t>(m_registers_count[gpr_registers_count] +
m_registers_count[fpr_registers_count] +
m_registers_count[msa_registers_count]));
-
- // elf-core yet to support ReadFPR()
- ProcessSP base = CalculateProcess();
- if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
- return;
}
RegisterContextPOSIX_mips64::~RegisterContextPOSIX_mips64() {}
@@ -92,8 +87,8 @@ size_t RegisterContextPOSIX_mips64::GetGPRSize() {
const RegisterInfo *RegisterContextPOSIX_mips64::GetRegisterInfo() {
// Commonly, this method is overridden and g_register_infos is copied and
- // specialized.
- // So, use GetRegisterInfo() rather than g_register_infos in this scope.
+ // specialized. So, use GetRegisterInfo() rather than g_register_infos in
+ // this scope.
return m_register_info_ap->GetRegisterInfo();
}
@@ -172,8 +167,8 @@ bool RegisterContextPOSIX_mips64::IsRegisterSetAvailable(size_t set_index) {
return (set_index < num_sets);
}
-// Used when parsing DWARF and EH frame information and any other
-// object file sections that contain register numbers in them.
+// Used when parsing DWARF and EH frame information and any other object file
+// sections that contain register numbers in them.
uint32_t RegisterContextPOSIX_mips64::ConvertRegisterKindToRegisterNumber(
lldb::RegisterKind kind, uint32_t num) {
const uint32_t num_regs = m_num_registers;
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
index c2b73e226165..9f0552539723 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
@@ -14,6 +14,7 @@
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
+#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
@@ -21,7 +22,6 @@
#include "lldb/Utility/Endian.h"
#include "llvm/Support/Compiler.h"
-#include "Plugins/Process/elf-core/ProcessElfCore.h"
#include "RegisterContextPOSIX_powerpc.h"
using namespace lldb_private;
@@ -95,11 +95,6 @@ RegisterContextPOSIX_powerpc::RegisterContextPOSIX_powerpc(
RegisterInfoInterface *register_info)
: RegisterContext(thread, concrete_frame_idx) {
m_register_info_ap.reset(register_info);
-
- // elf-core yet to support ReadFPR()
- ProcessSP base = CalculateProcess();
- if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
- return;
}
RegisterContextPOSIX_powerpc::~RegisterContextPOSIX_powerpc() {}
@@ -129,8 +124,8 @@ size_t RegisterContextPOSIX_powerpc::GetGPRSize() {
const RegisterInfo *RegisterContextPOSIX_powerpc::GetRegisterInfo() {
// Commonly, this method is overridden and g_register_infos is copied and
- // specialized.
- // So, use GetRegisterInfo() rather than g_register_infos in this scope.
+ // specialized. So, use GetRegisterInfo() rather than g_register_infos in
+ // this scope.
return m_register_info_ap->GetRegisterInfo();
}
@@ -181,8 +176,8 @@ bool RegisterContextPOSIX_powerpc::IsRegisterSetAvailable(size_t set_index) {
return (set_index < num_sets);
}
-// Used when parsing DWARF and EH frame information and any other
-// object file sections that contain register numbers in them.
+// Used when parsing DWARF and EH frame information and any other object file
+// sections that contain register numbers in them.
uint32_t RegisterContextPOSIX_powerpc::ConvertRegisterKindToRegisterNumber(
lldb::RegisterKind kind, uint32_t num) {
const uint32_t num_regs = GetRegisterCount();
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp
index de410f063b53..41ae5ec6b51a 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp
@@ -13,6 +13,7 @@
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
+#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
@@ -20,7 +21,6 @@
#include "lldb/Utility/Endian.h"
#include "llvm/Support/Compiler.h"
-#include "Plugins/Process/elf-core/ProcessElfCore.h"
#include "RegisterContextPOSIX_ppc64le.h"
using namespace lldb_private;
@@ -117,10 +117,6 @@ RegisterContextPOSIX_ppc64le::RegisterContextPOSIX_ppc64le(
RegisterInfoInterface *register_info)
: RegisterContext(thread, concrete_frame_idx) {
m_register_info_ap.reset(register_info);
-
- ProcessSP base = CalculateProcess();
- if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
- return;
}
void RegisterContextPOSIX_ppc64le::InvalidateAllRegisters() {}
@@ -146,8 +142,8 @@ size_t RegisterContextPOSIX_ppc64le::GetGPRSize() {
const RegisterInfo *RegisterContextPOSIX_ppc64le::GetRegisterInfo() {
// Commonly, this method is overridden and g_register_infos is copied and
- // specialized.
- // So, use GetRegisterInfo() rather than g_register_infos in this scope.
+ // specialized. So, use GetRegisterInfo() rather than g_register_infos in
+ // this scope.
return m_register_info_ap->GetRegisterInfo();
}
@@ -198,8 +194,8 @@ bool RegisterContextPOSIX_ppc64le::IsRegisterSetAvailable(size_t set_index) {
return (set_index < num_sets);
}
-// Used when parsing DWARF and EH frame information and any other
-// object file sections that contain register numbers in them.
+// Used when parsing DWARF and EH frame information and any other object file
+// sections that contain register numbers in them.
uint32_t RegisterContextPOSIX_ppc64le::ConvertRegisterKindToRegisterNumber(
lldb::RegisterKind kind, uint32_t num) {
const uint32_t num_regs = GetRegisterCount();
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp
index b3365ee2f098..662ac38405ef 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp
@@ -174,8 +174,8 @@ lldb::ByteOrder RegisterContextPOSIX_s390x::GetByteOrder() {
return byte_order;
}
-// Used when parsing DWARF and EH frame information and any other
-// object file sections that contain register numbers in them.
+// Used when parsing DWARF and EH frame information and any other object file
+// sections that contain register numbers in them.
uint32_t RegisterContextPOSIX_s390x::ConvertRegisterKindToRegisterNumber(
lldb::RegisterKind kind, uint32_t num) {
const uint32_t num_regs = GetRegisterCount();
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
index 41cec8add987..d2a06e1b7897 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
@@ -414,8 +414,8 @@ size_t RegisterContextPOSIX_x86::GetFXSAVEOffset() {
const RegisterInfo *RegisterContextPOSIX_x86::GetRegisterInfo() {
// Commonly, this method is overridden and g_register_infos is copied and
- // specialized.
- // So, use GetRegisterInfo() rather than g_register_infos in this scope.
+ // specialized. So, use GetRegisterInfo() rather than g_register_infos in
+ // this scope.
return m_register_info_ap->GetRegisterInfo();
}
@@ -531,8 +531,8 @@ bool RegisterContextPOSIX_x86::IsRegisterSetAvailable(size_t set_index) {
return (set_index < num_sets);
}
-// Used when parsing DWARF and EH frame information and any other
-// object file sections that contain register numbers in them.
+// Used when parsing DWARF and EH frame information and any other object file
+// sections that contain register numbers in them.
uint32_t RegisterContextPOSIX_x86::ConvertRegisterKindToRegisterNumber(
lldb::RegisterKind kind, uint32_t num) {
const uint32_t num_regs = GetRegisterCount();
diff --git a/source/Plugins/Process/Utility/RegisterInfoInterface.h b/source/Plugins/Process/Utility/RegisterInfoInterface.h
index 1894b5368122..5d7ad89ad394 100644
--- a/source/Plugins/Process/Utility/RegisterInfoInterface.h
+++ b/source/Plugins/Process/Utility/RegisterInfoInterface.h
@@ -19,7 +19,7 @@ namespace lldb_private {
///------------------------------------------------------------------------------
/// @class RegisterInfoInterface
///
-/// @brief RegisterInfo interface to patch RegisterInfo structure for archs.
+/// RegisterInfo interface to patch RegisterInfo structure for archs.
///------------------------------------------------------------------------------
class RegisterInfoInterface {
public:
diff --git a/source/Plugins/Process/Utility/RegisterInfos_ppc64.h b/source/Plugins/Process/Utility/RegisterInfos_ppc64.h
new file mode 100644
index 000000000000..69f00e4ba885
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterInfos_ppc64.h
@@ -0,0 +1,331 @@
+//===-- RegisterInfos_ppc64.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifdef DECLARE_REGISTER_INFOS_PPC64_STRUCT
+
+// C Includes
+#include <stddef.h>
+
+// Computes the offset of the given GPR_PPC64 in the user data area.
+#define GPR_PPC64_OFFSET(regname) (offsetof(GPR_PPC64, regname))
+#define FPR_PPC64_OFFSET(regname) (offsetof(FPR_PPC64, regname) \
+ + sizeof(GPR_PPC64))
+#define VMX_PPC64_OFFSET(regname) (offsetof(VMX_PPC64, regname) \
+ + sizeof(GPR_PPC64) + sizeof(FPR_PPC64))
+#define GPR_PPC64_SIZE(regname) (sizeof(((GPR_PPC64 *)NULL)->regname))
+
+#include "Utility/PPC64_DWARF_Registers.h"
+#include "lldb-ppc64-register-enums.h"
+
+// Note that the size and offset will be updated by platform-specific classes.
+#define DEFINE_GPR_PPC64(reg, alt, lldb_kind) \
+ { \
+ #reg, alt, GPR_PPC64_SIZE(reg), GPR_PPC64_OFFSET(reg), lldb::eEncodingUint,\
+ lldb::eFormatHex, \
+ {ppc64_dwarf::dwarf_##reg##_ppc64, \
+ ppc64_dwarf::dwarf_##reg##_ppc64, \
+ lldb_kind, \
+ LLDB_INVALID_REGNUM, \
+ gpr_##reg##_ppc64 }, \
+ NULL, NULL, NULL, 0 \
+ }
+#define DEFINE_FPR_PPC64(reg, alt, lldb_kind) \
+ { \
+#reg, alt, 8, FPR_PPC64_OFFSET(reg), lldb::eEncodingIEEE754, \
+ lldb::eFormatFloat, \
+ {ppc64_dwarf::dwarf_##reg##_ppc64, \
+ ppc64_dwarf::dwarf_##reg##_ppc64, lldb_kind, LLDB_INVALID_REGNUM, \
+ fpr_##reg##_ppc64 }, \
+ NULL, NULL, NULL, 0 \
+ }
+#define DEFINE_VMX_PPC64(reg, lldb_kind) \
+ { \
+#reg, NULL, 16, VMX_PPC64_OFFSET(reg), lldb::eEncodingVector, \
+ lldb::eFormatVectorOfUInt32, \
+ {ppc64_dwarf::dwarf_##reg##_ppc64, \
+ ppc64_dwarf::dwarf_##reg##_ppc64, lldb_kind, LLDB_INVALID_REGNUM, \
+ vmx_##reg##_ppc64 }, \
+ NULL, NULL, NULL, 0 \
+ }
+
+// General purpose registers.
+// EH_Frame, Generic, Process Plugin
+#define PPC64_REGS \
+ DEFINE_GPR_PPC64(r0, NULL, LLDB_INVALID_REGNUM) \
+ , DEFINE_GPR_PPC64(r1, "sp", LLDB_REGNUM_GENERIC_SP), \
+ DEFINE_GPR_PPC64(r2, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(r3, "arg1", LLDB_REGNUM_GENERIC_ARG1), \
+ DEFINE_GPR_PPC64(r4, "arg2", LLDB_REGNUM_GENERIC_ARG2), \
+ DEFINE_GPR_PPC64(r5, "arg3", LLDB_REGNUM_GENERIC_ARG3), \
+ DEFINE_GPR_PPC64(r6, "arg4", LLDB_REGNUM_GENERIC_ARG4), \
+ DEFINE_GPR_PPC64(r7, "arg5", LLDB_REGNUM_GENERIC_ARG5), \
+ DEFINE_GPR_PPC64(r8, "arg6", LLDB_REGNUM_GENERIC_ARG6), \
+ DEFINE_GPR_PPC64(r9, "arg7", LLDB_REGNUM_GENERIC_ARG7), \
+ DEFINE_GPR_PPC64(r10, "arg8", LLDB_REGNUM_GENERIC_ARG8), \
+ DEFINE_GPR_PPC64(r11, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(r12, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(r13, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(r14, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(r15, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(r16, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(r17, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(r18, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(r19, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(r20, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(r21, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(r22, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(r23, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(r24, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(r25, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(r26, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(r27, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(r28, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(r29, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(r30, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(r31, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(cr, "cr", LLDB_REGNUM_GENERIC_FLAGS), \
+ DEFINE_GPR_PPC64(msr, "msr", LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(xer, "xer", LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(lr, "lr", LLDB_REGNUM_GENERIC_RA), \
+ DEFINE_GPR_PPC64(ctr, "ctr", LLDB_INVALID_REGNUM), \
+ DEFINE_GPR_PPC64(pc, "pc", LLDB_REGNUM_GENERIC_PC), \
+ DEFINE_FPR_PPC64(f0, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f1, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f2, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f3, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f4, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f5, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f6, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f7, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f8, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f9, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f10, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f11, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f12, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f13, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f14, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f15, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f16, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f17, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f18, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f19, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f20, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f21, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f22, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f23, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f24, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f25, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f26, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f27, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f28, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f29, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f30, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR_PPC64(f31, NULL, LLDB_INVALID_REGNUM), \
+ {"fpscr", \
+ NULL, \
+ 8, \
+ FPR_PPC64_OFFSET(fpscr), \
+ lldb::eEncodingUint, \
+ lldb::eFormatHex, \
+ {ppc64_dwarf::dwarf_fpscr_ppc64, \
+ ppc64_dwarf::dwarf_fpscr_ppc64, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, fpr_fpscr_ppc64}, \
+ NULL, \
+ NULL, \
+ NULL, \
+ 0}, \
+ DEFINE_VMX_PPC64(vr0, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr1, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr2, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr3, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr4, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr5, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr6, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr7, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr8, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr9, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr10, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr11, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr12, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr13, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr14, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr15, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr16, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr17, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr18, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr19, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr20, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr21, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr22, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr23, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr24, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr25, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr26, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr27, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr28, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr29, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr30, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX_PPC64(vr31, LLDB_INVALID_REGNUM), \
+ {"vscr", \
+ NULL, \
+ 4, \
+ VMX_PPC64_OFFSET(vscr), \
+ lldb::eEncodingUint, \
+ lldb::eFormatHex, \
+ {ppc64_dwarf::dwarf_vscr_ppc64, ppc64_dwarf::dwarf_vscr_ppc64, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, vmx_vscr_ppc64}, \
+ NULL, \
+ NULL, \
+ NULL, \
+ 0}, \
+ {"vrsave", \
+ NULL, \
+ 4, \
+ VMX_PPC64_OFFSET(vrsave), \
+ lldb::eEncodingUint, \
+ lldb::eFormatHex, \
+ {ppc64_dwarf::dwarf_vrsave_ppc64, \
+ ppc64_dwarf::dwarf_vrsave_ppc64, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, vmx_vrsave_ppc64}, \
+ NULL, \
+ NULL, \
+ NULL, \
+ 0}, /* */
+
+typedef struct _GPR_PPC64 {
+ uint64_t r0;
+ uint64_t r1;
+ uint64_t r2;
+ uint64_t r3;
+ uint64_t r4;
+ uint64_t r5;
+ uint64_t r6;
+ uint64_t r7;
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ uint64_t r16;
+ uint64_t r17;
+ uint64_t r18;
+ uint64_t r19;
+ uint64_t r20;
+ uint64_t r21;
+ uint64_t r22;
+ uint64_t r23;
+ uint64_t r24;
+ uint64_t r25;
+ uint64_t r26;
+ uint64_t r27;
+ uint64_t r28;
+ uint64_t r29;
+ uint64_t r30;
+ uint64_t r31;
+ uint64_t cr;
+ uint64_t msr;
+ uint64_t xer;
+ uint64_t lr;
+ uint64_t ctr;
+ uint64_t pc;
+ uint64_t pad[3];
+} GPR_PPC64;
+
+typedef struct _FPR_PPC64 {
+ uint64_t f0;
+ uint64_t f1;
+ uint64_t f2;
+ uint64_t f3;
+ uint64_t f4;
+ uint64_t f5;
+ uint64_t f6;
+ uint64_t f7;
+ uint64_t f8;
+ uint64_t f9;
+ uint64_t f10;
+ uint64_t f11;
+ uint64_t f12;
+ uint64_t f13;
+ uint64_t f14;
+ uint64_t f15;
+ uint64_t f16;
+ uint64_t f17;
+ uint64_t f18;
+ uint64_t f19;
+ uint64_t f20;
+ uint64_t f21;
+ uint64_t f22;
+ uint64_t f23;
+ uint64_t f24;
+ uint64_t f25;
+ uint64_t f26;
+ uint64_t f27;
+ uint64_t f28;
+ uint64_t f29;
+ uint64_t f30;
+ uint64_t f31;
+ uint64_t fpscr;
+} FPR_PPC64;
+
+typedef struct _VMX_PPC64 {
+ uint32_t vr0[4];
+ uint32_t vr1[4];
+ uint32_t vr2[4];
+ uint32_t vr3[4];
+ uint32_t vr4[4];
+ uint32_t vr5[4];
+ uint32_t vr6[4];
+ uint32_t vr7[4];
+ uint32_t vr8[4];
+ uint32_t vr9[4];
+ uint32_t vr10[4];
+ uint32_t vr11[4];
+ uint32_t vr12[4];
+ uint32_t vr13[4];
+ uint32_t vr14[4];
+ uint32_t vr15[4];
+ uint32_t vr16[4];
+ uint32_t vr17[4];
+ uint32_t vr18[4];
+ uint32_t vr19[4];
+ uint32_t vr20[4];
+ uint32_t vr21[4];
+ uint32_t vr22[4];
+ uint32_t vr23[4];
+ uint32_t vr24[4];
+ uint32_t vr25[4];
+ uint32_t vr26[4];
+ uint32_t vr27[4];
+ uint32_t vr28[4];
+ uint32_t vr29[4];
+ uint32_t vr30[4];
+ uint32_t vr31[4];
+ uint32_t pad[2];
+ uint32_t vscr[2];
+ uint32_t vrsave;
+} VMX_PPC64;
+
+
+static lldb_private::RegisterInfo g_register_infos_ppc64[] = {
+ PPC64_REGS
+};
+
+static_assert((sizeof(g_register_infos_ppc64) /
+ sizeof(g_register_infos_ppc64[0])) ==
+ k_num_registers_ppc64,
+ "g_register_infos_powerpc64 has wrong number of register infos");
+
+#undef DEFINE_FPR_PPC64
+#undef DEFINE_GPR_PPC64
+#undef DEFINE_VMX_PPC64
+
+#endif // DECLARE_REGISTER_INFOS_PPC64_STRUCT
diff --git a/source/Plugins/Process/Utility/StopInfoMachException.cpp b/source/Plugins/Process/Utility/StopInfoMachException.cpp
index 3e860874183c..3dbfe611e713 100644
--- a/source/Plugins/Process/Utility/StopInfoMachException.cpp
+++ b/source/Plugins/Process/Utility/StopInfoMachException.cpp
@@ -356,8 +356,8 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
if (exc_code == 0x10003) // EXC_SOFT_SIGNAL
{
if (exc_sub_code == 5) {
- // On MacOSX, a SIGTRAP can signify that a process has called
- // exec, so we should check with our dynamic loader to verify.
+ // On MacOSX, a SIGTRAP can signify that a process has called exec,
+ // so we should check with our dynamic loader to verify.
ProcessSP process_sp(thread.GetProcess());
if (process_sp) {
DynamicLoader *dynamic_loader = process_sp->GetDynamicLoader();
@@ -403,10 +403,8 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
if (!exc_sub_code) {
// This looks like a plain trap.
// Have to check if there is a breakpoint here as well. When you
- // single-step onto a trap,
- // the single step stops you not to trap. Since we also do that
- // check below, let's just use
- // that logic.
+ // single-step onto a trap, the single step stops you not to trap.
+ // Since we also do that check below, let's just use that logic.
is_actual_breakpoint = true;
is_trace_if_actual_breakpoint_missing = true;
} else {
@@ -419,8 +417,8 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
(lldb::addr_t)exc_sub_code);
if (wp_sp && wp_sp->IsEnabled()) {
// Debugserver may piggyback the hardware index of the fired
- // watchpoint in the exception data.
- // Set the hardware index if that's the case.
+ // watchpoint in the exception data. Set the hardware index if
+ // that's the case.
if (exc_data_count >= 3)
wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
return StopInfo::CreateStopReasonWithWatchpointID(thread,
@@ -450,16 +448,15 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
{
// It's a watchpoint, then, if the exc_sub_code indicates a
- // known/enabled
- // data break address from our watchpoint list.
+ // known/enabled data break address from our watchpoint list.
lldb::WatchpointSP wp_sp;
if (target)
wp_sp = target->GetWatchpointList().FindByAddress(
(lldb::addr_t)exc_sub_code);
if (wp_sp && wp_sp->IsEnabled()) {
// Debugserver may piggyback the hardware index of the fired
- // watchpoint in the exception data.
- // Set the hardware index if that's the case.
+ // watchpoint in the exception data. Set the hardware index if
+ // that's the case.
if (exc_data_count >= 3)
wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
return StopInfo::CreateStopReasonWithWatchpointID(thread,
@@ -473,9 +470,9 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
is_actual_breakpoint = true;
is_trace_if_actual_breakpoint_missing = true;
} else if (exc_code == 0) // FIXME not EXC_ARM_BREAKPOINT but a kernel
- // is currently returning this so accept it as
- // indicating a breakpoint until the kernel is
- // fixed
+ // is currently returning this so accept it
+ // as indicating a breakpoint until the
+ // kernel is fixed
{
is_actual_breakpoint = true;
is_trace_if_actual_breakpoint_missing = true;
@@ -493,16 +490,15 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
{
// It's a watchpoint, then, if the exc_sub_code indicates a
- // known/enabled
- // data break address from our watchpoint list.
+ // known/enabled data break address from our watchpoint list.
lldb::WatchpointSP wp_sp;
if (target)
wp_sp = target->GetWatchpointList().FindByAddress(
(lldb::addr_t)exc_sub_code);
if (wp_sp && wp_sp->IsEnabled()) {
// Debugserver may piggyback the hardware index of the fired
- // watchpoint in the exception data.
- // Set the hardware index if that's the case.
+ // watchpoint in the exception data. Set the hardware index if
+ // that's the case.
if (exc_data_count >= 3)
wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
return StopInfo::CreateStopReasonWithWatchpointID(thread,
@@ -514,8 +510,7 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
return StopInfo::CreateStopReasonToTrace(thread);
}
// It looks like exc_sub_code has the 4 bytes of the instruction that
- // triggered the
- // exception, i.e. our breakpoint opcode
+ // triggered the exception, i.e. our breakpoint opcode
is_actual_breakpoint = exc_code == 1;
break;
}
@@ -534,23 +529,21 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
if (process_sp)
bp_site_sp = process_sp->GetBreakpointSiteList().FindByAddress(pc);
if (bp_site_sp && bp_site_sp->IsEnabled()) {
- // Update the PC if we were asked to do so, but only do
- // so if we find a breakpoint that we know about cause
- // this could be a trap instruction in the code
+ // Update the PC if we were asked to do so, but only do so if we find
+ // a breakpoint that we know about cause this could be a trap
+ // instruction in the code
if (pc_decrement > 0 && adjust_pc_if_needed)
reg_ctx_sp->SetPC(pc);
// If the breakpoint is for this thread, then we'll report the hit,
- // but if it is for another thread,
- // we can just report no reason. We don't need to worry about
- // stepping over the breakpoint here, that
+ // but if it is for another thread, we can just report no reason. We
+ // don't need to worry about stepping over the breakpoint here, that
// will be taken care of when the thread resumes and notices that
- // there's a breakpoint under the pc.
- // If we have an operating system plug-in, we might have set a thread
- // specific breakpoint using the
+ // there's a breakpoint under the pc. If we have an operating system
+ // plug-in, we might have set a thread specific breakpoint using the
// operating system thread ID, so we can't make any assumptions about
- // the thread ID so we must always
- // report the breakpoint regardless of the thread.
+ // the thread ID so we must always report the breakpoint regardless
+ // of the thread.
if (bp_site_sp->ValidForThisThread(&thread) ||
thread.GetProcess()->GetOperatingSystem() != NULL)
return StopInfo::CreateStopReasonWithBreakpointSiteID(
diff --git a/source/Plugins/Process/Utility/ThreadMemory.cpp b/source/Plugins/Process/Utility/ThreadMemory.cpp
index 5ff928c69e59..0c7c195815a4 100644
--- a/source/Plugins/Process/Utility/ThreadMemory.cpp
+++ b/source/Plugins/Process/Utility/ThreadMemory.cpp
@@ -62,7 +62,7 @@ ThreadMemory::CreateRegisterContextForFrame(StackFrame *frame) {
reg_ctx_sp = GetRegisterContext();
} else {
Unwind *unwinder = GetUnwinder();
- if (unwinder)
+ if (unwinder != nullptr)
reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
}
return reg_ctx_sp;
diff --git a/source/Plugins/Process/Utility/UnwindLLDB.cpp b/source/Plugins/Process/Utility/UnwindLLDB.cpp
index 2b34bddd90b2..55559f07f1e5 100644
--- a/source/Plugins/Process/Utility/UnwindLLDB.cpp
+++ b/source/Plugins/Process/Utility/UnwindLLDB.cpp
@@ -132,16 +132,12 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
// We want to detect an unwind that cycles erroneously and stop backtracing.
// Don't want this maximum unwind limit to be too low -- if you have a
- // backtrace
- // with an "infinitely recursing" bug, it will crash when the stack blows out
- // and the first 35,000 frames are uninteresting - it's the top most 5 frames
- // that
- // you actually care about. So you can't just cap the unwind at 10,000 or
- // something.
- // Realistically anything over around 200,000 is going to blow out the stack
- // space.
- // If we're still unwinding at that point, we're probably never going to
- // finish.
+ // backtrace with an "infinitely recursing" bug, it will crash when the stack
+ // blows out and the first 35,000 frames are uninteresting - it's the top
+ // most 5 frames that you actually care about. So you can't just cap the
+ // unwind at 10,000 or something. Realistically anything over around 200,000
+ // is going to blow out the stack space. If we're still unwinding at that
+ // point, we're probably never going to finish.
if (cur_idx > 300000) {
if (log)
log->Printf("%*sFrame %d unwound too many frames, assuming unwind has "
@@ -152,13 +148,12 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
if (reg_ctx_sp.get() == NULL) {
// If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to
- // that and return
- // true. Subsequent calls to TryFallbackUnwindPlan() will return false.
+ // that and return true. Subsequent calls to TryFallbackUnwindPlan() will
+ // return false.
if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
// TryFallbackUnwindPlan for prev_frame succeeded and updated
- // reg_ctx_lldb_sp field of
- // prev_frame. However, cfa field of prev_frame still needs to be updated.
- // Hence updating it.
+ // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame
+ // still needs to be updated. Hence updating it.
if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
return nullptr;
@@ -172,15 +167,13 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
}
if (!reg_ctx_sp->IsValid()) {
- // We failed to get a valid RegisterContext.
- // See if the regctx below this on the stack has a fallback unwind plan it
- // can use.
- // Subsequent calls to TryFallbackUnwindPlan() will return false.
+ // We failed to get a valid RegisterContext. See if the regctx below this
+ // on the stack has a fallback unwind plan it can use. Subsequent calls to
+ // TryFallbackUnwindPlan() will return false.
if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
// TryFallbackUnwindPlan for prev_frame succeeded and updated
- // reg_ctx_lldb_sp field of
- // prev_frame. However, cfa field of prev_frame still needs to be updated.
- // Hence updating it.
+ // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame
+ // still needs to be updated. Hence updating it.
if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
return nullptr;
@@ -195,13 +188,12 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
}
if (!reg_ctx_sp->GetCFA(cursor_sp->cfa)) {
// If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to
- // that and return
- // true. Subsequent calls to TryFallbackUnwindPlan() will return false.
+ // that and return true. Subsequent calls to TryFallbackUnwindPlan() will
+ // return false.
if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
// TryFallbackUnwindPlan for prev_frame succeeded and updated
- // reg_ctx_lldb_sp field of
- // prev_frame. However, cfa field of prev_frame still needs to be updated.
- // Hence updating it.
+ // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame
+ // still needs to be updated. Hence updating it.
if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
return nullptr;
@@ -216,27 +208,21 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
}
if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa)) {
// On Mac OS X, the _sigtramp asynchronous signal trampoline frame may not
- // have
- // its (constructed) CFA aligned correctly -- don't do the abi alignment
- // check for
- // these.
+ // have its (constructed) CFA aligned correctly -- don't do the abi
+ // alignment check for these.
if (reg_ctx_sp->IsTrapHandlerFrame() == false) {
// See if we can find a fallback unwind plan for THIS frame. It may be
// that the UnwindPlan we're using for THIS frame was bad and gave us a
- // bad CFA.
- // If that's not it, then see if we can change the UnwindPlan for the
- // frame
- // below us ("NEXT") -- see if using that other UnwindPlan gets us a
- // better
- // unwind state.
+ // bad CFA. If that's not it, then see if we can change the UnwindPlan
+ // for the frame below us ("NEXT") -- see if using that other UnwindPlan
+ // gets us a better unwind state.
if (reg_ctx_sp->TryFallbackUnwindPlan() == false ||
reg_ctx_sp->GetCFA(cursor_sp->cfa) == false ||
abi->CallFrameAddressIsValid(cursor_sp->cfa) == false) {
if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
// TryFallbackUnwindPlan for prev_frame succeeded and updated
- // reg_ctx_lldb_sp field of
- // prev_frame. However, cfa field of prev_frame still needs to be
- // updated. Hence updating it.
+ // reg_ctx_lldb_sp field of prev_frame. However, cfa field of
+ // prev_frame still needs to be updated. Hence updating it.
if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
return nullptr;
@@ -259,13 +245,12 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
}
if (!reg_ctx_sp->ReadPC(cursor_sp->start_pc)) {
// If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to
- // that and return
- // true. Subsequent calls to TryFallbackUnwindPlan() will return false.
+ // that and return true. Subsequent calls to TryFallbackUnwindPlan() will
+ // return false.
if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
// TryFallbackUnwindPlan for prev_frame succeeded and updated
- // reg_ctx_lldb_sp field of
- // prev_frame. However, cfa field of prev_frame still needs to be updated.
- // Hence updating it.
+ // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame
+ // still needs to be updated. Hence updating it.
if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
return nullptr;
@@ -280,13 +265,12 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
}
if (abi && !abi->CodeAddressIsValid(cursor_sp->start_pc)) {
// If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to
- // that and return
- // true. Subsequent calls to TryFallbackUnwindPlan() will return false.
+ // that and return true. Subsequent calls to TryFallbackUnwindPlan() will
+ // return false.
if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
// TryFallbackUnwindPlan for prev_frame succeeded and updated
- // reg_ctx_lldb_sp field of
- // prev_frame. However, cfa field of prev_frame still needs to be updated.
- // Hence updating it.
+ // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame
+ // still needs to be updated. Hence updating it.
if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
return nullptr;
@@ -320,13 +304,12 @@ void UnwindLLDB::UpdateUnwindPlanForFirstFrameIfInvalid(ABI *abi) {
CursorSP old_m_candidate_frame = m_candidate_frame;
// Try to unwind 2 more frames using the Unwinder. It uses Full UnwindPlan
- // and if Full UnwindPlan fails, then uses FallBack UnwindPlan. Also
- // update the cfa of Frame 0 (if required).
+ // and if Full UnwindPlan fails, then uses FallBack UnwindPlan. Also update
+ // the cfa of Frame 0 (if required).
AddOneMoreFrame(abi);
- // Remove all the frames added by above function as the purpose of
- // using above function was just to check whether Unwinder of Frame 0
- // works or not.
+ // Remove all the frames added by above function as the purpose of using
+ // above function was just to check whether Unwinder of Frame 0 works or not.
for (uint32_t i = 1; i < m_frames.size(); i++)
m_frames.pop_back();
@@ -362,51 +345,44 @@ bool UnwindLLDB::AddOneMoreFrame(ABI *abi) {
m_frames.push_back(new_frame);
- // If we can get one more frame further then accept that we get back a correct
- // frame.
+ // If we can get one more frame further then accept that we get back a
+ // correct frame.
m_candidate_frame = GetOneMoreFrame(abi);
if (m_candidate_frame)
return true;
// We can't go further from the frame returned by GetOneMore frame. Lets try
- // to get a
- // different frame with using the fallback unwind plan.
+ // to get a different frame with using the fallback unwind plan.
if (!m_frames[m_frames.size() - 2]
->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
// We don't have a valid fallback unwind plan. Accept the frame as it is.
- // This is a
- // valid situation when we are at the bottom of the stack.
+ // This is a valid situation when we are at the bottom of the stack.
return true;
}
// Remove the possibly incorrect frame from the frame list and try to add a
- // different one with
- // the newly selected fallback unwind plan.
+ // different one with the newly selected fallback unwind plan.
m_frames.pop_back();
CursorSP new_frame_v2 = GetOneMoreFrame(abi);
if (new_frame_v2 == nullptr) {
// We haven't got a new frame from the fallback unwind plan. Accept the
- // frame from the
- // original unwind plan. This is a valid situation when we are at the bottom
- // of the stack.
+ // frame from the original unwind plan. This is a valid situation when we
+ // are at the bottom of the stack.
m_frames.push_back(new_frame);
return true;
}
// Push the new frame to the list and try to continue from this frame. If we
- // can get a new frame
- // then accept it as the correct one.
+ // can get a new frame then accept it as the correct one.
m_frames.push_back(new_frame_v2);
m_candidate_frame = GetOneMoreFrame(abi);
if (m_candidate_frame) {
// If control reached here then TryFallbackUnwindPlan had succeeded for
- // Cursor::m_frames[m_frames.size() - 2].
- // It also succeeded to Unwind next 2 frames i.e. m_frames[m_frames.size() -
- // 1] and a frame after that.
- // For Cursor::m_frames[m_frames.size() - 2], reg_ctx_lldb_sp field was
- // already updated during TryFallbackUnwindPlan
- // call above. However, cfa field still needs to be updated. Hence updating
- // it here and then returning.
+ // Cursor::m_frames[m_frames.size() - 2]. It also succeeded to Unwind next
+ // 2 frames i.e. m_frames[m_frames.size() - 1] and a frame after that. For
+ // Cursor::m_frames[m_frames.size() - 2], reg_ctx_lldb_sp field was already
+ // updated during TryFallbackUnwindPlan call above. However, cfa field
+ // still needs to be updated. Hence updating it here and then returning.
if (!(m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->GetCFA(
m_frames[m_frames.size() - 2]->cfa)))
return false;
@@ -414,8 +390,7 @@ bool UnwindLLDB::AddOneMoreFrame(ABI *abi) {
}
// The new frame hasn't helped in unwinding. Fall back to the original one as
- // the default unwind
- // plan is usually more reliable then the fallback one.
+ // the default unwind plan is usually more reliable then the fallback one.
m_frames.pop_back();
m_frames.push_back(new_frame);
return true;
@@ -486,10 +461,9 @@ bool UnwindLLDB::SearchForSavedLocationForRegister(
if (static_cast<size_t>(frame_num) >= m_frames.size())
return false;
- // Never interrogate more than one level while looking for the saved pc value.
- // If the value
- // isn't saved by frame_num, none of the frames lower on the stack will have a
- // useful value.
+ // Never interrogate more than one level while looking for the saved pc
+ // value. If the value isn't saved by frame_num, none of the frames lower on
+ // the stack will have a useful value.
if (pc_reg) {
UnwindLLDB::RegisterSearchResult result;
result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister(
@@ -505,8 +479,7 @@ bool UnwindLLDB::SearchForSavedLocationForRegister(
lldb_regnum, regloc);
// We descended down to the live register context aka stack frame 0 and are
- // reading the value
- // out of a live register.
+ // reading the value out of a live register.
if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound &&
regloc.type ==
UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext) {
@@ -514,11 +487,9 @@ bool UnwindLLDB::SearchForSavedLocationForRegister(
}
// If we have unwind instructions saying that register N is saved in
- // register M in the middle of
- // the stack (and N can equal M here, meaning the register was not used in
- // this function), then
- // change the register number we're looking for to M and keep looking for a
- // concrete location
+ // register M in the middle of the stack (and N can equal M here, meaning
+ // the register was not used in this function), then change the register
+ // number we're looking for to M and keep looking for a concrete location
// down the stack, or an actual value from a live RegisterContext at frame
// 0.
if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound &&
diff --git a/source/Plugins/Process/Utility/UnwindLLDB.h b/source/Plugins/Process/Utility/UnwindLLDB.h
index 3f84649aa05f..3d1f85a3dec3 100644
--- a/source/Plugins/Process/Utility/UnwindLLDB.h
+++ b/source/Plugins/Process/Utility/UnwindLLDB.h
@@ -17,6 +17,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Symbol/FuncUnwinders.h"
+#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Unwind.h"
diff --git a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
index d831011cb661..2115b4e179c0 100644
--- a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
+++ b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
@@ -133,8 +133,8 @@ size_t UnwindMacOSXFrameBackchain::GetStackFrameData_i386(
if (addr_range_ptr) {
if (first_frame->GetFrameCodeAddress() ==
addr_range_ptr->GetBaseAddress()) {
- // We are at the first instruction, so we can recover the
- // previous PC by dereferencing the SP
+ // We are at the first instruction, so we can recover the previous PC
+ // by dereferencing the SP
lldb::addr_t first_frame_sp = reg_ctx->GetSP(0);
// Read the real second frame return address into frame.pc
if (first_frame_sp &&
@@ -224,8 +224,8 @@ size_t UnwindMacOSXFrameBackchain::GetStackFrameData_x86_64(
if (addr_range_ptr) {
if (first_frame->GetFrameCodeAddress() ==
addr_range_ptr->GetBaseAddress()) {
- // We are at the first instruction, so we can recover the
- // previous PC by dereferencing the SP
+ // We are at the first instruction, so we can recover the previous PC
+ // by dereferencing the SP
lldb::addr_t first_frame_sp = reg_ctx->GetSP(0);
// Read the real second frame return address into frame.pc
if (process->ReadMemory(first_frame_sp, &frame.pc, sizeof(frame.pc),
diff --git a/source/Plugins/Process/Utility/lldb-ppc64-register-enums.h b/source/Plugins/Process/Utility/lldb-ppc64-register-enums.h
new file mode 100644
index 000000000000..9ea81c00b666
--- /dev/null
+++ b/source/Plugins/Process/Utility/lldb-ppc64-register-enums.h
@@ -0,0 +1,139 @@
+//===-- lldb-ppc64-register-enums.h ---------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_ppc64_register_enums_h
+#define lldb_ppc64_register_enums_h
+
+// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
+
+// ---------------------------------------------------------------------------
+// Internal codes for all ppc64 registers.
+// ---------------------------------------------------------------------------
+enum {
+ k_first_gpr_ppc64,
+ gpr_r0_ppc64 = k_first_gpr_ppc64,
+ gpr_r1_ppc64,
+ gpr_r2_ppc64,
+ gpr_r3_ppc64,
+ gpr_r4_ppc64,
+ gpr_r5_ppc64,
+ gpr_r6_ppc64,
+ gpr_r7_ppc64,
+ gpr_r8_ppc64,
+ gpr_r9_ppc64,
+ gpr_r10_ppc64,
+ gpr_r11_ppc64,
+ gpr_r12_ppc64,
+ gpr_r13_ppc64,
+ gpr_r14_ppc64,
+ gpr_r15_ppc64,
+ gpr_r16_ppc64,
+ gpr_r17_ppc64,
+ gpr_r18_ppc64,
+ gpr_r19_ppc64,
+ gpr_r20_ppc64,
+ gpr_r21_ppc64,
+ gpr_r22_ppc64,
+ gpr_r23_ppc64,
+ gpr_r24_ppc64,
+ gpr_r25_ppc64,
+ gpr_r26_ppc64,
+ gpr_r27_ppc64,
+ gpr_r28_ppc64,
+ gpr_r29_ppc64,
+ gpr_r30_ppc64,
+ gpr_r31_ppc64,
+ gpr_cr_ppc64,
+ gpr_msr_ppc64,
+ gpr_xer_ppc64,
+ gpr_lr_ppc64,
+ gpr_ctr_ppc64,
+ gpr_pc_ppc64,
+ k_last_gpr_ppc64 = gpr_pc_ppc64,
+
+ k_first_fpr_ppc64,
+ fpr_f0_ppc64 = k_first_fpr_ppc64,
+ fpr_f1_ppc64,
+ fpr_f2_ppc64,
+ fpr_f3_ppc64,
+ fpr_f4_ppc64,
+ fpr_f5_ppc64,
+ fpr_f6_ppc64,
+ fpr_f7_ppc64,
+ fpr_f8_ppc64,
+ fpr_f9_ppc64,
+ fpr_f10_ppc64,
+ fpr_f11_ppc64,
+ fpr_f12_ppc64,
+ fpr_f13_ppc64,
+ fpr_f14_ppc64,
+ fpr_f15_ppc64,
+ fpr_f16_ppc64,
+ fpr_f17_ppc64,
+ fpr_f18_ppc64,
+ fpr_f19_ppc64,
+ fpr_f20_ppc64,
+ fpr_f21_ppc64,
+ fpr_f22_ppc64,
+ fpr_f23_ppc64,
+ fpr_f24_ppc64,
+ fpr_f25_ppc64,
+ fpr_f26_ppc64,
+ fpr_f27_ppc64,
+ fpr_f28_ppc64,
+ fpr_f29_ppc64,
+ fpr_f30_ppc64,
+ fpr_f31_ppc64,
+ fpr_fpscr_ppc64,
+ k_last_fpr_ppc64 = fpr_fpscr_ppc64,
+
+ k_first_vmx_ppc64,
+ vmx_vr0_ppc64 = k_first_vmx_ppc64,
+ vmx_vr1_ppc64,
+ vmx_vr2_ppc64,
+ vmx_vr3_ppc64,
+ vmx_vr4_ppc64,
+ vmx_vr5_ppc64,
+ vmx_vr6_ppc64,
+ vmx_vr7_ppc64,
+ vmx_vr8_ppc64,
+ vmx_vr9_ppc64,
+ vmx_vr10_ppc64,
+ vmx_vr11_ppc64,
+ vmx_vr12_ppc64,
+ vmx_vr13_ppc64,
+ vmx_vr14_ppc64,
+ vmx_vr15_ppc64,
+ vmx_vr16_ppc64,
+ vmx_vr17_ppc64,
+ vmx_vr18_ppc64,
+ vmx_vr19_ppc64,
+ vmx_vr20_ppc64,
+ vmx_vr21_ppc64,
+ vmx_vr22_ppc64,
+ vmx_vr23_ppc64,
+ vmx_vr24_ppc64,
+ vmx_vr25_ppc64,
+ vmx_vr26_ppc64,
+ vmx_vr27_ppc64,
+ vmx_vr28_ppc64,
+ vmx_vr29_ppc64,
+ vmx_vr30_ppc64,
+ vmx_vr31_ppc64,
+ vmx_vscr_ppc64,
+ vmx_vrsave_ppc64,
+ k_last_vmx_ppc64 = vmx_vrsave_ppc64,
+
+ k_num_registers_ppc64,
+ k_num_gpr_registers_ppc64 = k_last_gpr_ppc64 - k_first_gpr_ppc64 + 1,
+ k_num_fpr_registers_ppc64 = k_last_fpr_ppc64 - k_first_fpr_ppc64 + 1,
+ k_num_vmx_registers_ppc64 = k_last_vmx_ppc64 - k_first_vmx_ppc64 + 1,
+};
+
+#endif // #ifndef lldb_ppc64_register_enums_h
diff --git a/source/Plugins/Process/Windows/Common/CMakeLists.txt b/source/Plugins/Process/Windows/Common/CMakeLists.txt
index 009a289bae39..092629086183 100644
--- a/source/Plugins/Process/Windows/Common/CMakeLists.txt
+++ b/source/Plugins/Process/Windows/Common/CMakeLists.txt
@@ -1,6 +1,3 @@
-include_directories(.)
-include_directories(../../Utility)
-
set(PROC_WINDOWS_COMMON_SOURCES
DebuggerThread.cpp
LocalDebugDelegate.cpp
diff --git a/source/Plugins/Process/Windows/Common/DebuggerThread.cpp b/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
index ac9e65c3c108..ad43551a4c6d 100644
--- a/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
+++ b/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
@@ -112,8 +112,7 @@ lldb::thread_result_t DebuggerThread::DebuggerThreadAttachRoutine(void *data) {
lldb::thread_result_t DebuggerThread::DebuggerThreadLaunchRoutine(
const ProcessLaunchInfo &launch_info) {
// Grab a shared_ptr reference to this so that we know it won't get deleted
- // until after the
- // thread routine has exited.
+ // until after the thread routine has exited.
std::shared_ptr<DebuggerThread> this_ref(shared_from_this());
Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
@@ -124,14 +123,11 @@ lldb::thread_result_t DebuggerThread::DebuggerThreadLaunchRoutine(
ProcessLauncherWindows launcher;
HostProcess process(launcher.LaunchProcess(launch_info, error));
// If we couldn't create the process, notify waiters immediately. Otherwise
- // enter the debug
- // loop and wait until we get the create process debug notification. Note
- // that if the process
- // was created successfully, we can throw away the process handle we got from
- // CreateProcess
- // because Windows will give us another (potentially more useful?) handle when
- // it sends us the
- // CREATE_PROCESS_DEBUG_EVENT.
+ // enter the debug loop and wait until we get the create process debug
+ // notification. Note that if the process was created successfully, we can
+ // throw away the process handle we got from CreateProcess because Windows
+ // will give us another (potentially more useful?) handle when it sends us
+ // the CREATE_PROCESS_DEBUG_EVENT.
if (error.Success())
DebugLoop();
else
@@ -143,8 +139,7 @@ lldb::thread_result_t DebuggerThread::DebuggerThreadLaunchRoutine(
lldb::thread_result_t DebuggerThread::DebuggerThreadAttachRoutine(
lldb::pid_t pid, const ProcessAttachInfo &attach_info) {
// Grab a shared_ptr reference to this so that we know it won't get deleted
- // until after the
- // thread routine has exited.
+ // until after the thread routine has exited.
std::shared_ptr<DebuggerThread> this_ref(shared_from_this());
Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
@@ -157,11 +152,9 @@ lldb::thread_result_t DebuggerThread::DebuggerThreadAttachRoutine(
return 0;
}
- // The attach was successful, enter the debug loop. From here on out, this is
- // no different than
- // a create process operation, so all the same comments in DebugLaunch should
- // apply from this
- // point out.
+ // The attach was successful, enter the debug loop. From here on out, this
+ // is no different than a create process operation, so all the same comments
+ // in DebugLaunch should apply from this point out.
DebugLoop();
return 0;
@@ -188,21 +181,25 @@ Status DebuggerThread::StopDebugging(bool terminate) {
lldb::process_t handle = m_process.GetNativeProcess().GetSystemHandle();
if (terminate) {
- // Initiate the termination before continuing the exception, so that the
- // next debug
- // event we get is the exit process event, and not some other event.
- BOOL terminate_suceeded = TerminateProcess(handle, 0);
- LLDB_LOG(log,
- "calling TerminateProcess({0}, 0) (inferior={1}), success={2}",
- handle, pid, terminate_suceeded);
+ if (handle != nullptr && handle != LLDB_INVALID_PROCESS) {
+ // Initiate the termination before continuing the exception, so that the
+ // next debug event we get is the exit process event, and not some other
+ // event.
+ BOOL terminate_suceeded = TerminateProcess(handle, 0);
+ LLDB_LOG(log,
+ "calling TerminateProcess({0}, 0) (inferior={1}), success={2}",
+ handle, pid, terminate_suceeded);
+ } else {
+ LLDB_LOG(log,
+ "NOT calling TerminateProcess because the inferior is not valid ({0}, 0) (inferior={1})",
+ handle, pid);
+ }
}
// If we're stuck waiting for an exception to continue (e.g. the user is at a
- // breakpoint
- // messing around in the debugger), continue it now. But only AFTER calling
- // TerminateProcess
- // to make sure that the very next call to WaitForDebugEvent is an exit
- // process event.
+ // breakpoint messing around in the debugger), continue it now. But only
+ // AFTER calling TerminateProcess to make sure that the very next call to
+ // WaitForDebugEvent is an exit process event.
if (m_active_exception.get()) {
LLDB_LOG(log, "masking active exception");
ContinueAsyncException(ExceptionResult::MaskException);
@@ -355,8 +352,7 @@ DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info,
}
// Don't perform any blocking operations while we're shutting down. That
- // will
- // cause TerminateProcess -> WaitForSingleObject to time out.
+ // will cause TerminateProcess -> WaitForSingleObject to time out.
return ExceptionResult::SendToApplication;
}
@@ -373,8 +369,8 @@ DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info,
m_exception_pred.SetValue(result, eBroadcastNever);
LLDB_LOG(log, "waiting for ExceptionPred != BreakInDebugger");
- m_exception_pred.WaitForValueNotEqualTo(ExceptionResult::BreakInDebugger,
- result);
+ result = *m_exception_pred.WaitForValueNotEqualTo(
+ ExceptionResult::BreakInDebugger);
LLDB_LOG(log, "got ExceptionPred = {0}", (int)m_exception_pred.GetValue());
return result;
diff --git a/source/Plugins/Process/Windows/Common/ProcessWindows.cpp b/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
index a1c9cfaed41c..b14081f76617 100644
--- a/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
+++ b/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
@@ -77,8 +77,8 @@ std::string GetProcessExecutableName(DWORD pid) {
namespace lldb_private {
// We store a pointer to this class in the ProcessWindows, so that we don't
-// expose Windows-specific types and implementation details from a public header
-// file.
+// expose Windows-specific types and implementation details from a public
+// header file.
class ProcessWindowsData {
public:
ProcessWindowsData(bool stop_at_entry) : m_stop_at_entry(stop_at_entry) {
@@ -186,9 +186,9 @@ Status ProcessWindows::DoDetach(bool keep_stopped) {
StateType private_state;
{
// Acquire the lock only long enough to get the DebuggerThread.
- // StopDebugging() will trigger a call back into ProcessWindows which
- // will also acquire the lock. Thus we have to release the lock before
- // calling StopDebugging().
+ // StopDebugging() will trigger a call back into ProcessWindows which will
+ // also acquire the lock. Thus we have to release the lock before calling
+ // StopDebugging().
llvm::sys::ScopedLock lock(m_mutex);
private_state = GetPrivateState();
@@ -228,14 +228,22 @@ Status ProcessWindows::DoDetach(bool keep_stopped) {
Status ProcessWindows::DoLaunch(Module *exe_module,
ProcessLaunchInfo &launch_info) {
- // Even though m_session_data is accessed here, it is before a debugger thread
- // has been
- // kicked off. So there's no race conditions, and it shouldn't be necessary
- // to acquire
- // the mutex.
+ // Even though m_session_data is accessed here, it is before a debugger
+ // thread has been kicked off. So there's no race conditions, and it
+ // shouldn't be necessary to acquire the mutex.
Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
Status result;
+
+ FileSpec working_dir = launch_info.GetWorkingDirectory();
+ namespace fs = llvm::sys::fs;
+ if (working_dir && (!working_dir.ResolvePath() ||
+ !fs::is_directory(working_dir.GetPath()))) {
+ result.SetErrorStringWithFormat("No such file or directory: %s",
+ working_dir.GetCString());
+ return result;
+ }
+
if (!launch_info.GetFlags().Test(eLaunchFlagDebug)) {
StreamString stream;
stream.Printf("ProcessWindows unable to launch '%s'. ProcessWindows can "
@@ -251,7 +259,6 @@ Status ProcessWindows::DoLaunch(Module *exe_module,
bool stop_at_entry = launch_info.GetFlags().Test(eLaunchFlagStopAtEntry);
m_session_data.reset(new ProcessWindowsData(stop_at_entry));
- SetPrivateState(eStateLaunching);
DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
m_session_data->m_debugger.reset(new DebuggerThread(delegate));
DebuggerThreadSP debugger = m_session_data->m_debugger;
@@ -276,12 +283,10 @@ Status ProcessWindows::DoLaunch(Module *exe_module,
launch_info.GetExecutableFile().GetPath());
// We've hit the initial stop. If eLaunchFlagsStopAtEntry was specified, the
- // private state
- // should already be set to eStateStopped as a result of hitting the initial
- // breakpoint. If
- // it was not set, the breakpoint should have already been resumed from and
- // the private state
- // should already be eStateRunning.
+ // private state should already be set to eStateStopped as a result of
+ // hitting the initial breakpoint. If it was not set, the breakpoint should
+ // have already been resumed from and the private state should already be
+ // eStateRunning.
launch_info.SetProcessID(process.GetProcessId());
SetID(process.GetProcessId());
@@ -322,12 +327,10 @@ ProcessWindows::DoAttachToProcessWithID(lldb::pid_t pid,
LLDB_LOG(log, "successfully attached to process with pid={0}", process_id);
// We've hit the initial stop. If eLaunchFlagsStopAtEntry was specified, the
- // private state
- // should already be set to eStateStopped as a result of hitting the initial
- // breakpoint. If
- // it was not set, the breakpoint should have already been resumed from and
- // the private state
- // should already be eStateRunning.
+ // private state should already be set to eStateStopped as a result of
+ // hitting the initial breakpoint. If it was not set, the breakpoint should
+ // have already been resumed from and the private state should already be
+ // eStateRunning.
SetID(process.GetProcessId());
return error;
}
@@ -346,22 +349,35 @@ Status ProcessWindows::DoResume() {
ExceptionRecordSP active_exception =
m_session_data->m_debugger->GetActiveException().lock();
if (active_exception) {
- // Resume the process and continue processing debug events. Mask
- // the exception so that from the process's view, there is no
- // indication that anything happened.
+ // Resume the process and continue processing debug events. Mask the
+ // exception so that from the process's view, there is no indication that
+ // anything happened.
m_session_data->m_debugger->ContinueAsyncException(
ExceptionResult::MaskException);
}
LLDB_LOG(log, "resuming {0} threads.", m_thread_list.GetSize());
+ bool failed = false;
for (uint32_t i = 0; i < m_thread_list.GetSize(); ++i) {
auto thread = std::static_pointer_cast<TargetThreadWindows>(
m_thread_list.GetThreadAtIndex(i));
- thread->DoResume();
+ Status result = thread->DoResume();
+ if (result.Fail()) {
+ failed = true;
+ LLDB_LOG(
+ log,
+ "Trying to resume thread at index {0}, but failed with error {1}.",
+ i, result);
+ }
}
- SetPrivateState(eStateRunning);
+ if (failed) {
+ error.SetErrorString("ProcessWindows::DoResume failed");
+ return error;
+ } else {
+ SetPrivateState(eStateRunning);
+ }
} else {
LLDB_LOG(log, "error: process %I64u is in state %u. Returning...",
m_session_data->m_debugger->GetProcess().GetProcessId(),
@@ -376,10 +392,9 @@ Status ProcessWindows::DoDestroy() {
StateType private_state;
{
// Acquire this lock inside an inner scope, only long enough to get the
- // DebuggerThread.
- // StopDebugging() will trigger a call back into ProcessWindows which will
- // acquire the lock
- // again, so we need to not deadlock.
+ // DebuggerThread. StopDebugging() will trigger a call back into
+ // ProcessWindows which will acquire the lock again, so we need to not
+ // deadlock.
llvm::sys::ScopedLock lock(m_mutex);
private_state = GetPrivateState();
@@ -461,8 +476,9 @@ void ProcessWindows::RefreshStateAfterStop() {
m_session_data->m_debugger->GetActiveException();
ExceptionRecordSP active_exception = exception_record.lock();
if (!active_exception) {
- LLDB_LOG(log, "there is no active exception in process {0}. Why is the "
- "process stopped?",
+ LLDB_LOG(log,
+ "there is no active exception in process {0}. Why is the "
+ "process stopped?",
m_session_data->m_debugger->GetProcess().GetProcessId());
return;
}
@@ -479,8 +495,9 @@ void ProcessWindows::RefreshStateAfterStop() {
const uint64_t pc = register_context->GetPC();
BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc));
if (site && site->ValidForThisThread(stop_thread.get())) {
- LLDB_LOG(log, "Single-stepped onto a breakpoint in process {0} at "
- "address {1:x} with breakpoint site {2}",
+ LLDB_LOG(log,
+ "Single-stepped onto a breakpoint in process {0} at "
+ "address {1:x} with breakpoint site {2}",
m_session_data->m_debugger->GetProcess().GetProcessId(), pc,
site->GetID());
stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*stop_thread,
@@ -502,22 +519,25 @@ void ProcessWindows::RefreshStateAfterStop() {
BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc));
if (site) {
- LLDB_LOG(log, "detected breakpoint in process {0} at address {1:x} with "
- "breakpoint site {2}",
+ LLDB_LOG(log,
+ "detected breakpoint in process {0} at address {1:x} with "
+ "breakpoint site {2}",
m_session_data->m_debugger->GetProcess().GetProcessId(), pc,
site->GetID());
if (site->ValidForThisThread(stop_thread.get())) {
- LLDB_LOG(log, "Breakpoint site {0} is valid for this thread ({1:x}), "
- "creating stop info.",
+ LLDB_LOG(log,
+ "Breakpoint site {0} is valid for this thread ({1:x}), "
+ "creating stop info.",
site->GetID(), stop_thread->GetID());
stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(
*stop_thread, site->GetID());
register_context->SetPC(pc);
} else {
- LLDB_LOG(log, "Breakpoint site {0} is not valid for this thread, "
- "creating empty stop info.",
+ LLDB_LOG(log,
+ "Breakpoint site {0} is not valid for this thread, "
+ "creating empty stop info.",
site->GetID());
}
stop_thread->SetStopInfo(stop_info);
@@ -558,8 +578,8 @@ bool ProcessWindows::CanDebug(lldb::TargetSP target_sp,
ModuleSP exe_module_sp(target_sp->GetExecutableModule());
if (exe_module_sp.get())
return exe_module_sp->GetFileSpec().Exists();
- // However, if there is no executable module, we return true since we might be
- // preparing to attach.
+ // However, if there is no executable module, we return true since we might
+ // be preparing to attach.
return true;
}
@@ -589,8 +609,8 @@ bool ProcessWindows::UpdateThreadList(ThreadList &old_thread_list,
}
}
- // Also add all the threads that are new since the last time we broke into the
- // debugger.
+ // Also add all the threads that are new since the last time we broke into
+ // the debugger.
for (const auto &thread_info : m_session_data->m_new_threads) {
ThreadSP thread(new TargetThreadWindows(*this, thread_info.second));
thread->SetID(thread_info.first);
@@ -639,8 +659,13 @@ size_t ProcessWindows::DoReadMemory(lldb::addr_t vm_addr, void *buf,
SIZE_T bytes_read = 0;
if (!ReadProcessMemory(process.GetNativeProcess().GetSystemHandle(), addr,
buf, size, &bytes_read)) {
+ // Reading from the process can fail for a number of reasons - set the
+ // error code and make sure that the number of bytes read is set back to 0
+ // because in some scenarios the value of bytes_read returned from the API
+ // is garbage.
error.SetError(GetLastError(), eErrorTypeWin32);
LLDB_LOG(log, "reading failed with error: {0}", error);
+ bytes_read = 0;
}
return bytes_read;
}
@@ -699,11 +724,9 @@ Status ProcessWindows::GetMemoryRegionInfo(lldb::addr_t vm_addr,
SIZE_T result = ::VirtualQueryEx(handle, addr, &mem_info, sizeof(mem_info));
if (result == 0) {
if (::GetLastError() == ERROR_INVALID_PARAMETER) {
- // ERROR_INVALID_PARAMETER is returned if VirtualQueryEx is called with an
- // address
- // past the highest accessible address. We should return a range from the
- // vm_addr
- // to LLDB_INVALID_ADDRESS
+ // ERROR_INVALID_PARAMETER is returned if VirtualQueryEx is called with
+ // an address past the highest accessible address. We should return a
+ // range from the vm_addr to LLDB_INVALID_ADDRESS
info.GetRange().SetRangeBase(vm_addr);
info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
info.SetReadable(MemoryRegionInfo::eNo);
@@ -713,8 +736,9 @@ Status ProcessWindows::GetMemoryRegionInfo(lldb::addr_t vm_addr,
return error;
} else {
error.SetError(::GetLastError(), eErrorTypeWin32);
- LLDB_LOG(log, "VirtualQueryEx returned error {0} while getting memory "
- "region info for address {1:x}",
+ LLDB_LOG(log,
+ "VirtualQueryEx returned error {0} while getting memory "
+ "region info for address {1:x}",
error, vm_addr);
return error;
}
@@ -744,10 +768,8 @@ Status ProcessWindows::GetMemoryRegionInfo(lldb::addr_t vm_addr,
info.SetMapped(MemoryRegionInfo::eYes);
} else {
// In the unmapped case we need to return the distance to the next block of
- // memory.
- // VirtualQueryEx nearly does that except that it gives the distance from
- // the start
- // of the page containing vm_addr.
+ // memory. VirtualQueryEx nearly does that except that it gives the
+ // distance from the start of the page containing vm_addr.
SYSTEM_INFO data;
GetSystemInfo(&data);
DWORD page_offset = vm_addr % data.dwPageSize;
@@ -757,8 +779,9 @@ Status ProcessWindows::GetMemoryRegionInfo(lldb::addr_t vm_addr,
}
error.SetError(::GetLastError(), eErrorTypeWin32);
- LLDB_LOGV(log, "Memory region info for address {0}: readable={1}, "
- "executable={2}, writable={3}",
+ LLDB_LOGV(log,
+ "Memory region info for address {0}: readable={1}, "
+ "executable={2}, writable={3}",
vm_addr, info.GetReadable(), info.GetExecutable(),
info.GetWritable());
return error;
@@ -779,7 +802,7 @@ void ProcessWindows::OnExitProcess(uint32_t exit_code) {
Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
LLDB_LOG(log, "Process {0} exited with code {1}", GetID(), exit_code);
- TargetSP target = m_target_sp.lock();
+ TargetSP target = CalculateTarget();
if (target) {
ModuleSP executable_module = target->GetExecutableModule();
ModuleList unloaded_modules;
@@ -825,10 +848,9 @@ void ProcessWindows::OnDebuggerConnected(lldb::addr_t image_base) {
GetTarget().ModulesDidLoad(loaded_modules);
// Add the main executable module to the list of pending module loads. We
- // can't call
- // GetTarget().ModulesDidLoad() here because we still haven't returned from
- // DoLaunch() / DoAttach() yet
- // so the target may not have set the process instance to `this` yet.
+ // can't call GetTarget().ModulesDidLoad() here because we still haven't
+ // returned from DoLaunch() / DoAttach() yet so the target may not have set
+ // the process instance to `this` yet.
llvm::sys::ScopedLock lock(m_mutex);
const HostThreadWindows &wmain_thread =
debugger->GetMainThread().GetNativeThread();
@@ -845,15 +867,14 @@ ProcessWindows::OnDebugException(bool first_chance,
// FIXME: Without this check, occasionally when running the test suite there
// is
// an issue where m_session_data can be null. It's not clear how this could
- // happen
- // but it only surfaces while running the test suite. In order to properly
- // diagnose
- // this, we probably need to first figure allow the test suite to print out
- // full
- // lldb logs, and then add logging to the process plugin.
+ // happen but it only surfaces while running the test suite. In order to
+ // properly diagnose this, we probably need to first figure allow the test
+ // suite to print out full lldb logs, and then add logging to the process
+ // plugin.
if (!m_session_data) {
- LLDB_LOG(log, "Debugger thread reported exception {0:x} at address {1:x}, "
- "but there is no session.",
+ LLDB_LOG(log,
+ "Debugger thread reported exception {0:x} at address {1:x}, "
+ "but there is no session.",
record.GetExceptionCode(), record.GetExceptionAddress());
return ExceptionResult::SendToApplication;
}
@@ -887,8 +908,9 @@ ProcessWindows::OnDebugException(bool first_chance,
SetPrivateState(eStateStopped);
break;
default:
- LLDB_LOG(log, "Debugger thread reported exception {0:x} at address {1:x} "
- "(first_chance={2})",
+ LLDB_LOG(log,
+ "Debugger thread reported exception {0:x} at address {1:x} "
+ "(first_chance={2})",
record.GetExceptionCode(), record.GetExceptionAddress(),
first_chance);
// For non-breakpoints, give the application a chance to handle the
@@ -929,9 +951,8 @@ void ProcessWindows::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) {
void ProcessWindows::OnLoadDll(const ModuleSpec &module_spec,
lldb::addr_t module_addr) {
// Confusingly, there is no Target::AddSharedModule. Instead, calling
- // GetSharedModule() with
- // a new module will add it to the module list and return a corresponding
- // ModuleSP.
+ // GetSharedModule() with a new module will add it to the module list and
+ // return a corresponding ModuleSP.
Status error;
ModuleSP module = GetTarget().GetSharedModule(module_spec, &error);
bool load_addr_changed = false;
@@ -961,17 +982,16 @@ void ProcessWindows::OnDebuggerError(const Status &error, uint32_t type) {
Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
if (m_session_data->m_initial_stop_received) {
- // This happened while debugging. Do we shutdown the debugging session, try
- // to continue, or do something else?
- LLDB_LOG(log, "Error {0} occurred during debugging. Unexpected behavior "
- "may result. {1}",
+ // This happened while debugging. Do we shutdown the debugging session,
+ // try to continue, or do something else?
+ LLDB_LOG(log,
+ "Error {0} occurred during debugging. Unexpected behavior "
+ "may result. {1}",
error.GetError(), error);
} else {
// If we haven't actually launched the process yet, this was an error
- // launching the
- // process. Set the internal error and signal the initial stop event so
- // that the DoLaunch
- // method wakes up and returns a failure.
+ // launching the process. Set the internal error and signal the initial
+ // stop event so that the DoLaunch method wakes up and returns a failure.
m_session_data->m_launch_error = error;
::SetEvent(m_session_data->m_initial_stop_event);
LLDB_LOG(
@@ -1001,9 +1021,9 @@ Status ProcessWindows::WaitForDebuggerConnection(DebuggerThreadSP debugger,
}
// The Windows page protection bits are NOT independent masks that can be
-// bitwise-ORed together. For example, PAGE_EXECUTE_READ is not
-// (PAGE_EXECUTE | PAGE_READ). To test for an access type, it's necessary to
-// test for any of the bits that provide that access type.
+// bitwise-ORed together. For example, PAGE_EXECUTE_READ is not (PAGE_EXECUTE
+// | PAGE_READ). To test for an access type, it's necessary to test for any of
+// the bits that provide that access type.
bool ProcessWindows::IsPageReadable(uint32_t protect) {
return (protect & PAGE_NOACCESS) == 0;
}
diff --git a/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp b/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp
index a4d60303877e..3903280918cc 100644
--- a/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp
+++ b/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp
@@ -16,10 +16,10 @@
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Logging.h"
+#include "Plugins/Process/Utility/UnwindLLDB.h"
#include "ProcessWindows.h"
#include "ProcessWindowsLog.h"
#include "TargetThreadWindows.h"
-#include "UnwindLLDB.h"
#if defined(_WIN64)
#include "x64/RegisterContextWindows_x64.h"
@@ -33,7 +33,7 @@ using namespace lldb_private;
TargetThreadWindows::TargetThreadWindows(ProcessWindows &process,
const HostThread &thread)
: Thread(process, thread.GetNativeThread().GetThreadId()),
- m_host_thread(thread) {}
+ m_thread_reg_ctx_sp(), m_host_thread(thread) {}
TargetThreadWindows::~TargetThreadWindows() { DestroyThread(); }
@@ -49,40 +49,53 @@ void TargetThreadWindows::DidStop() {}
RegisterContextSP TargetThreadWindows::GetRegisterContext() {
if (!m_reg_context_sp)
- m_reg_context_sp = CreateRegisterContextForFrameIndex(0);
+ m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
return m_reg_context_sp;
}
RegisterContextSP
TargetThreadWindows::CreateRegisterContextForFrame(StackFrame *frame) {
- return CreateRegisterContextForFrameIndex(frame->GetConcreteFrameIndex());
-}
+ RegisterContextSP reg_ctx_sp;
+ uint32_t concrete_frame_idx = 0;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
-RegisterContextSP
-TargetThreadWindows::CreateRegisterContextForFrameIndex(uint32_t idx) {
- if (!m_reg_context_sp) {
- ArchSpec arch = HostInfo::GetArchitecture();
- switch (arch.GetMachine()) {
- case llvm::Triple::x86:
+ if (frame)
+ concrete_frame_idx = frame->GetConcreteFrameIndex();
+
+ if (concrete_frame_idx == 0) {
+ if (!m_thread_reg_ctx_sp) {
+ ArchSpec arch = HostInfo::GetArchitecture();
+ switch (arch.GetMachine()) {
+ case llvm::Triple::x86:
#if defined(_WIN64)
-// FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64
+ // FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64
+ LLDB_LOG(log, "This is a Wow64 process, we should create a "
+ "RegisterContextWindows_Wow64, but we don't.");
#else
- m_reg_context_sp.reset(new RegisterContextWindows_x86(*this, idx));
+ m_thread_reg_ctx_sp.reset(
+ new RegisterContextWindows_x86(*this, concrete_frame_idx));
#endif
- break;
- case llvm::Triple::x86_64:
+ break;
+ case llvm::Triple::x86_64:
#if defined(_WIN64)
- m_reg_context_sp.reset(new RegisterContextWindows_x64(*this, idx));
+ m_thread_reg_ctx_sp.reset(
+ new RegisterContextWindows_x64(*this, concrete_frame_idx));
#else
-// LLDB is 32-bit, but the target process is 64-bit. We probably can't debug
-// this.
+ LLDB_LOG(log, "LLDB is 32-bit, but the target process is 64-bit.");
#endif
- default:
- break;
+ default:
+ break;
+ }
}
+ reg_ctx_sp = m_thread_reg_ctx_sp;
+ } else {
+ Unwind *unwinder = GetUnwinder();
+ if (unwinder != nullptr)
+ reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
}
- return m_reg_context_sp;
+
+ return reg_ctx_sp;
}
bool TargetThreadWindows::CalculateStopInfo() {
@@ -93,16 +106,16 @@ bool TargetThreadWindows::CalculateStopInfo() {
Unwind *TargetThreadWindows::GetUnwinder() {
// FIXME: Implement an unwinder based on the Windows unwinder exposed through
// DIA SDK.
- if (m_unwinder_ap.get() == NULL)
+ if (!m_unwinder_ap)
m_unwinder_ap.reset(new UnwindLLDB(*this));
return m_unwinder_ap.get();
}
-bool TargetThreadWindows::DoResume() {
+Status TargetThreadWindows::DoResume() {
StateType resume_state = GetTemporaryResumeState();
StateType current_state = GetState();
if (resume_state == current_state)
- return true;
+ return Status();
if (resume_state == eStateStepping) {
uint32_t flags_index =
@@ -118,8 +131,17 @@ bool TargetThreadWindows::DoResume() {
DWORD previous_suspend_count = 0;
HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
do {
+ // ResumeThread returns -1 on error, or the thread's *previous* suspend
+ // count on success. This means that the return value is 1 when the thread
+ // was restarted. Note that DWORD is an unsigned int, so we need to
+ // explicitly compare with -1.
previous_suspend_count = ::ResumeThread(thread_handle);
- } while (previous_suspend_count > 0);
+
+ if (previous_suspend_count == (DWORD)-1)
+ return Status(::GetLastError(), eErrorTypeWin32);
+
+ } while (previous_suspend_count > 1);
}
- return true;
+
+ return Status();
}
diff --git a/source/Plugins/Process/Windows/Common/TargetThreadWindows.h b/source/Plugins/Process/Windows/Common/TargetThreadWindows.h
index 8b4e3dfdda4a..952c0f55b57f 100644
--- a/source/Plugins/Process/Windows/Common/TargetThreadWindows.h
+++ b/source/Plugins/Process/Windows/Common/TargetThreadWindows.h
@@ -37,15 +37,14 @@ public:
bool CalculateStopInfo() override;
Unwind *GetUnwinder() override;
- bool DoResume();
+ Status DoResume();
HostThread GetHostThread() const { return m_host_thread; }
private:
- lldb::RegisterContextSP CreateRegisterContextForFrameIndex(uint32_t idx);
-
+ lldb::RegisterContextSP m_thread_reg_ctx_sp;
HostThread m_host_thread;
};
-}
+} // namespace lldb_private
#endif
diff --git a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp b/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp
index e64bade5ff90..4aa6c785f83c 100644
--- a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp
+++ b/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp
@@ -14,9 +14,9 @@
#include "lldb/lldb-private-types.h"
#include "RegisterContextWindows_x64.h"
-#include "RegisterContext_x86.h"
+#include "Plugins/Process/Utility/RegisterContext_x86.h"
#include "TargetThreadWindows.h"
-#include "lldb-x86-register-enums.h"
+#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
#include "llvm/ADT/STLExtras.h"
@@ -29,14 +29,11 @@ using namespace lldb_private;
namespace {
// This enum defines the layout of the global RegisterInfo array. This is
-// necessary because
-// lldb register sets are defined in terms of indices into the register array.
-// As such, the
-// order of RegisterInfos defined in global registers array must match the order
-// defined here.
-// When defining the register set layouts, these values can appear in an
-// arbitrary order, and that
-// determines the order that register values are displayed in a dump.
+// necessary because lldb register sets are defined in terms of indices into
+// the register array. As such, the order of RegisterInfos defined in global
+// registers array must match the order defined here. When defining the
+// register set layouts, these values can appear in an arbitrary order, and
+// that determines the order that register values are displayed in a dump.
enum RegisterIndex {
eRegisterIndexRax,
eRegisterIndexRbx,
@@ -44,6 +41,8 @@ enum RegisterIndex {
eRegisterIndexRdx,
eRegisterIndexRdi,
eRegisterIndexRsi,
+ eRegisterIndexRbp,
+ eRegisterIndexRsp,
eRegisterIndexR8,
eRegisterIndexR9,
eRegisterIndexR10,
@@ -52,8 +51,6 @@ enum RegisterIndex {
eRegisterIndexR13,
eRegisterIndexR14,
eRegisterIndexR15,
- eRegisterIndexRbp,
- eRegisterIndexRsp,
eRegisterIndexRip,
eRegisterIndexRflags
};
@@ -96,6 +93,16 @@ RegisterInfo g_register_infos[] = {
LLDB_INVALID_REGNUM, lldb_rsi_x86_64},
nullptr,
nullptr},
+ {DEFINE_GPR(rbp, "fp"),
+ {dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP,
+ LLDB_INVALID_REGNUM, lldb_rbp_x86_64},
+ nullptr,
+ nullptr},
+ {DEFINE_GPR(rsp, "sp"),
+ {dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP,
+ LLDB_INVALID_REGNUM, lldb_rsp_x86_64},
+ nullptr,
+ nullptr},
{DEFINE_GPR(r8, nullptr),
{dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, lldb_r8_x86_64},
@@ -136,16 +143,6 @@ RegisterInfo g_register_infos[] = {
LLDB_INVALID_REGNUM, lldb_r15_x86_64},
nullptr,
nullptr},
- {DEFINE_GPR(rbp, "fp"),
- {dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP,
- LLDB_INVALID_REGNUM, lldb_rbp_x86_64},
- nullptr,
- nullptr},
- {DEFINE_GPR(rsp, "sp"),
- {dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP,
- LLDB_INVALID_REGNUM, lldb_rsp_x86_64},
- nullptr,
- nullptr},
{DEFINE_GPR(rip, "pc"),
{dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC,
LLDB_INVALID_REGNUM, lldb_rip_x86_64},
@@ -165,10 +162,10 @@ static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
uint32_t g_gpr_reg_indices[] = {
eRegisterIndexRax, eRegisterIndexRbx, eRegisterIndexRcx,
eRegisterIndexRdx, eRegisterIndexRdi, eRegisterIndexRsi,
- eRegisterIndexR8, eRegisterIndexR9, eRegisterIndexR10,
- eRegisterIndexR11, eRegisterIndexR12, eRegisterIndexR13,
- eRegisterIndexR14, eRegisterIndexR15, eRegisterIndexRbp,
- eRegisterIndexRsp, eRegisterIndexRip, eRegisterIndexRflags};
+ eRegisterIndexRbp, eRegisterIndexRsp, eRegisterIndexR8,
+ eRegisterIndexR9, eRegisterIndexR10, eRegisterIndexR11,
+ eRegisterIndexR12, eRegisterIndexR13, eRegisterIndexR14,
+ eRegisterIndexR15, eRegisterIndexRip, eRegisterIndexRflags};
RegisterSet g_register_sets[] = {
{"General Purpose Registers", "gpr",
@@ -209,6 +206,9 @@ bool RegisterContextWindows_x64::ReadRegister(const RegisterInfo *reg_info,
if (!CacheAllRegisterValues())
return false;
+ if (reg_info == nullptr)
+ return false;
+
switch (reg_info->kinds[eRegisterKindLLDB]) {
case lldb_rax_x86_64:
reg_value.SetUInt64(m_context.Rax);
@@ -270,11 +270,10 @@ bool RegisterContextWindows_x64::ReadRegister(const RegisterInfo *reg_info,
bool RegisterContextWindows_x64::WriteRegister(const RegisterInfo *reg_info,
const RegisterValue &reg_value) {
- // Since we cannot only write a single register value to the inferior, we need
- // to make sure
- // our cached copy of the register values are fresh. Otherwise when writing
- // EAX, for example,
- // we may also overwrite some other register with a stale value.
+ // Since we cannot only write a single register value to the inferior, we
+ // need to make sure our cached copy of the register values are fresh.
+ // Otherwise when writing EAX, for example, we may also overwrite some other
+ // register with a stale value.
if (!CacheAllRegisterValues())
return false;
diff --git a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
index f56836de4a67..fd486f3d0829 100644
--- a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
+++ b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
@@ -15,9 +15,9 @@
#include "ProcessWindowsLog.h"
#include "RegisterContextWindows_x86.h"
-#include "RegisterContext_x86.h"
+#include "Plugins/Process/Utility/RegisterContext_x86.h"
#include "TargetThreadWindows.h"
-#include "lldb-x86-register-enums.h"
+#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
#include "llvm/ADT/STLExtras.h"
@@ -30,14 +30,11 @@ using namespace lldb_private;
namespace {
// This enum defines the layout of the global RegisterInfo array. This is
-// necessary because
-// lldb register sets are defined in terms of indices into the register array.
-// As such, the
-// order of RegisterInfos defined in global registers array must match the order
-// defined here.
-// When defining the register set layouts, these values can appear in an
-// arbitrary order, and that
-// determines the order that register values are displayed in a dump.
+// necessary because lldb register sets are defined in terms of indices into
+// the register array. As such, the order of RegisterInfos defined in global
+// registers array must match the order defined here. When defining the
+// register set layouts, these values can appear in an arbitrary order, and
+// that determines the order that register values are displayed in a dump.
enum RegisterIndex {
eRegisterIndexEax,
eRegisterIndexEbx,
@@ -179,6 +176,9 @@ bool RegisterContextWindows_x86::ReadRegister(const RegisterInfo *reg_info,
if (!CacheAllRegisterValues())
return false;
+ if (reg_info == nullptr)
+ return false;
+
uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
switch (reg) {
case lldb_eax_i386:
@@ -212,11 +212,10 @@ bool RegisterContextWindows_x86::ReadRegister(const RegisterInfo *reg_info,
bool RegisterContextWindows_x86::WriteRegister(const RegisterInfo *reg_info,
const RegisterValue &reg_value) {
- // Since we cannot only write a single register value to the inferior, we need
- // to make sure
- // our cached copy of the register values are fresh. Otherwise when writing
- // EAX, for example,
- // we may also overwrite some other register with a stale value.
+ // Since we cannot only write a single register value to the inferior, we
+ // need to make sure our cached copy of the register values are fresh.
+ // Otherwise when writing EAX, for example, we may also overwrite some other
+ // register with a stale value.
if (!CacheAllRegisterValues())
return false;
diff --git a/source/Plugins/Process/elf-core/CMakeLists.txt b/source/Plugins/Process/elf-core/CMakeLists.txt
index 3082c73f6dda..9b6739824c06 100644
--- a/source/Plugins/Process/elf-core/CMakeLists.txt
+++ b/source/Plugins/Process/elf-core/CMakeLists.txt
@@ -1,5 +1,3 @@
-include_directories(../Utility)
-
add_lldb_library(lldbPluginProcessElfCore PLUGIN
ProcessElfCore.cpp
ThreadElfCore.cpp
diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index 7d6a0c9ad2df..7bb7b72eaac1 100644
--- a/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -56,9 +56,9 @@ lldb::ProcessSP ProcessElfCore::CreateInstance(lldb::TargetSP target_sp,
const FileSpec *crash_file) {
lldb::ProcessSP process_sp;
if (crash_file) {
- // Read enough data for a ELF32 header or ELF64 header
- // Note: Here we care about e_type field only, so it is safe
- // to ignore possible presence of the header extension.
+ // Read enough data for a ELF32 header or ELF64 header Note: Here we care
+ // about e_type field only, so it is safe to ignore possible presence of
+ // the header extension.
const size_t header_size = sizeof(llvm::ELF::Elf64_Ehdr);
auto data_sp = DataBufferLLVM::CreateSliceFromPath(crash_file->GetPath(),
@@ -107,10 +107,10 @@ ProcessElfCore::ProcessElfCore(lldb::TargetSP target_sp,
//----------------------------------------------------------------------
ProcessElfCore::~ProcessElfCore() {
Clear();
- // We need to call finalize on the process before destroying ourselves
- // to make sure all of the broadcaster cleanup goes as planned. If we
- // destruct this class, then Process::~Process() might have problems
- // trying to fully destroy the broadcaster.
+ // We need to call finalize on the process before destroying ourselves to
+ // make sure all of the broadcaster cleanup goes as planned. If we destruct
+ // this class, then Process::~Process() might have problems trying to fully
+ // destroy the broadcaster.
Finalize();
}
@@ -206,8 +206,8 @@ Status ProcessElfCore::DoLoadCore() {
m_core_range_infos.Sort();
}
- // Even if the architecture is set in the target, we need to override
- // it to match the core file which is always single arch.
+ // Even if the architecture is set in the target, we need to override it to
+ // match the core file which is always single arch.
ArchSpec arch(m_core_module_sp->GetArchitecture());
ArchSpec target_arch = GetTarget().GetArchitecture();
@@ -241,8 +241,7 @@ Status ProcessElfCore::DoLoadCore() {
}
// Core files are useless without the main executable. See if we can locate
- // the main
- // executable using data we found in the core file notes.
+ // the main executable using data we found in the core file notes.
lldb::ModuleSP exe_module_sp = GetTarget().GetExecutableModule();
if (!exe_module_sp) {
// The first entry in the NT_FILE might be our executable
@@ -250,7 +249,8 @@ Status ProcessElfCore::DoLoadCore() {
ModuleSpec exe_module_spec;
exe_module_spec.GetArchitecture() = arch;
exe_module_spec.GetFileSpec().SetFile(
- m_nt_file_entries[0].path.GetCString(), false);
+ m_nt_file_entries[0].path.GetCString(), false,
+ FileSpec::Style::native);
if (exe_module_spec.GetFileSpec()) {
exe_module_sp = GetTarget().GetSharedModule(exe_module_spec);
if (exe_module_sp)
@@ -297,8 +297,8 @@ bool ProcessElfCore::IsAlive() { return true; }
//------------------------------------------------------------------
size_t ProcessElfCore::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
Status &error) {
- // Don't allow the caching that lldb_private::Process::ReadMemory does
- // since in core files we have it all cached our our core file anyway.
+ // Don't allow the caching that lldb_private::Process::ReadMemory does since
+ // in core files we have it all cached our our core file anyway.
return DoReadMemory(addr, buf, size, error);
}
@@ -368,17 +368,18 @@ size_t ProcessElfCore::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
lldb::addr_t bytes_left =
0; // Number of bytes available in the core file from the given address
- // Don't proceed if core file doesn't contain the actual data for this address range.
+ // Don't proceed if core file doesn't contain the actual data for this
+ // address range.
if (file_start == file_end)
return 0;
- // Figure out how many on-disk bytes remain in this segment
- // starting at the given offset
+ // Figure out how many on-disk bytes remain in this segment starting at the
+ // given offset
if (file_end > file_start + offset)
bytes_left = file_end - (file_start + offset);
- // Figure out how many bytes we need to zero-fill if we are
- // reading more bytes than available in the on-disk segment
+ // Figure out how many bytes we need to zero-fill if we are reading more
+ // bytes than available in the on-disk segment
if (bytes_to_read > bytes_left) {
zero_fill_size = bytes_to_read - bytes_left;
bytes_to_read = bytes_left;
@@ -551,8 +552,8 @@ llvm::Error ProcessElfCore::parseFreeBSDNotes(llvm::ArrayRef<CoreNote> notes) {
llvm::Error ProcessElfCore::parseNetBSDNotes(llvm::ArrayRef<CoreNote> notes) {
ThreadData thread_data;
for (const auto &note : notes) {
- // NetBSD per-thread information is stored in notes named
- // "NetBSD-CORE@nnn" so match on the initial part of the string.
+ // NetBSD per-thread information is stored in notes named "NetBSD-CORE@nnn"
+ // so match on the initial part of the string.
if (!llvm::StringRef(note.info.n_name).startswith("NetBSD-CORE"))
continue;
@@ -585,8 +586,8 @@ llvm::Error ProcessElfCore::parseNetBSDNotes(llvm::ArrayRef<CoreNote> notes) {
llvm::Error ProcessElfCore::parseOpenBSDNotes(llvm::ArrayRef<CoreNote> notes) {
ThreadData thread_data;
for (const auto &note : notes) {
- // OpenBSD per-thread information is stored in notes named
- // "OpenBSD@nnn" so match on the initial part of the string.
+ // OpenBSD per-thread information is stored in notes named "OpenBSD@nnn" so
+ // match on the initial part of the string.
if (!llvm::StringRef(note.info.n_name).startswith("OpenBSD"))
continue;
@@ -665,7 +666,7 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
Status status = prpsinfo.Parse(note.data, arch);
if (status.Fail())
return status.ToError();
- thread_data.name = prpsinfo.pr_fname;
+ thread_data.name.assign (prpsinfo.pr_fname, strnlen (prpsinfo.pr_fname, sizeof (prpsinfo.pr_fname)));
SetID(prpsinfo.pr_pid);
break;
}
@@ -749,9 +750,9 @@ ArchSpec ProcessElfCore::GetArchitecture() {
ArchSpec target_arch = GetTarget().GetArchitecture();
arch.MergeFrom(target_arch);
- // On MIPS there is no way to differentiate betwenn 32bit and 64bit core files
- // and this information can't be merged in from the target arch so we fail
- // back to unconditionally returning the target arch in this config.
+ // On MIPS there is no way to differentiate betwenn 32bit and 64bit core
+ // files and this information can't be merged in from the target arch so we
+ // fail back to unconditionally returning the target arch in this config.
if (target_arch.IsMIPS()) {
return target_arch;
}
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
index e252b5a35e9c..532a1f5c0831 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
@@ -56,7 +56,7 @@ bool RegisterContextCorePOSIX_mips64::ReadRegister(const RegisterInfo *reg_info,
if (IsGPR(reg_info->kinds[lldb::eRegisterKindLLDB])) {
if (reg_info->byte_size == 4 && !(arch.GetMachine() == llvm::Triple::mips64el))
// In case of 32bit core file, the register data are placed at 4 byte
- // offset.
+ // offset.
offset = offset / 2;
v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
value = v;
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
index a5c7ffda1da5..a1f26d52444b 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
@@ -60,8 +60,8 @@ bool RegisterContextCorePOSIX_x86_64::ReadRegister(const RegisterInfo *reg_info,
const uint8_t *src;
size_t offset;
const size_t fxsave_offset = reg_info->byte_offset - GetFXSAVEOffset();
- // make the offset relative to the beginning of the FXSAVE structure
- // because this is the data that we have (not the entire UserArea)
+ // make the offset relative to the beginning of the FXSAVE structure because
+ // this is the data that we have (not the entire UserArea)
if (m_gpregset && reg_info->byte_offset < GetGPRSize()) {
src = m_gpregset.get();
diff --git a/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/source/Plugins/Process/elf-core/ThreadElfCore.cpp
index 10c1ed288b2c..d9b90c8e902e 100644
--- a/source/Plugins/Process/elf-core/ThreadElfCore.cpp
+++ b/source/Plugins/Process/elf-core/ThreadElfCore.cpp
@@ -55,16 +55,9 @@ void ThreadElfCore::RefreshStateAfterStop() {
GetRegisterContext()->InvalidateIfNeeded(false);
}
-void ThreadElfCore::ClearStackFrames() {
- Unwind *unwinder = GetUnwinder();
- if (unwinder)
- unwinder->Clear();
- Thread::ClearStackFrames();
-}
-
RegisterContextSP ThreadElfCore::GetRegisterContext() {
- if (m_reg_context_sp.get() == NULL) {
- m_reg_context_sp = CreateRegisterContextForFrame(NULL);
+ if (!m_reg_context_sp) {
+ m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
}
return m_reg_context_sp;
}
@@ -84,7 +77,7 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
ArchSpec arch = process->GetArchitecture();
- RegisterInfoInterface *reg_interface = NULL;
+ RegisterInfoInterface *reg_interface = nullptr;
switch (arch.GetTriple().getOS()) {
case llvm::Triple::FreeBSD: {
@@ -234,8 +227,10 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
}
reg_ctx_sp = m_thread_reg_ctx_sp;
- } else if (m_unwinder_ap.get()) {
- reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame(frame);
+ } else {
+ Unwind *unwinder = GetUnwinder();
+ if (unwinder != nullptr)
+ reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
}
return reg_ctx_sp;
}
@@ -292,8 +287,8 @@ Status ELFLinuxPrStatus::Parse(const DataExtractor &data,
return error;
}
- // Read field by field to correctly account for endianess
- // of both the core dump and the platform running lldb.
+ // Read field by field to correctly account for endianess of both the core
+ // dump and the platform running lldb.
offset_t offset = 0;
si_signo = data.GetU32(&offset);
si_code = data.GetU32(&offset);
@@ -340,7 +335,7 @@ size_t ELFLinuxPrPsInfo::GetSize(const lldb_private::ArchSpec &arch) {
return sizeof(ELFLinuxPrPsInfo);
return mips_linux_pr_psinfo_size_o32_n32;
}
-
+
switch (arch.GetCore()) {
case lldb_private::ArchSpec::eCore_s390x_generic:
case lldb_private::ArchSpec::eCore_x86_64_x86_64:
@@ -382,9 +377,9 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data,
pr_uid = data.GetU32(&offset);
pr_gid = data.GetU32(&offset);
} else {
- // 16 bit on 32 bit platforms, 32 bit on 64 bit platforms
- pr_uid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1);
- pr_gid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1);
+ // 16 bit on 32 bit platforms, 32 bit on 64 bit platforms
+ pr_uid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1);
+ pr_gid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1);
}
pr_pid = data.GetU32(&offset);
diff --git a/source/Plugins/Process/elf-core/ThreadElfCore.h b/source/Plugins/Process/elf-core/ThreadElfCore.h
index 335f698dbb24..167fd6edc4ce 100644
--- a/source/Plugins/Process/elf-core/ThreadElfCore.h
+++ b/source/Plugins/Process/elf-core/ThreadElfCore.h
@@ -146,8 +146,6 @@ public:
lldb::RegisterContextSP
CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
- void ClearStackFrames() override;
-
static bool ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; }
const char *GetName() override {
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
index 4d4a4f8c5c7a..4e20b56fb111 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
@@ -109,16 +109,14 @@ StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(
const bool should_stop = ShouldStop(signals, response);
response.SetFilePos(0);
- // The packet we should resume with. In the future
- // we should check our thread list and "do the right thing"
- // for new threads that show up while we stop and run async
- // packets. Setting the packet to 'c' to continue all threads
- // is the right thing to do 99.99% of the time because if a
- // thread was single stepping, and we sent an interrupt, we
- // will notice above that we didn't stop due to an interrupt
- // but stopped due to stepping and we would _not_ continue.
- // This packet may get modified by the async actions (e.g. to send a
- // signal).
+ // The packet we should resume with. In the future we should check our
+ // thread list and "do the right thing" for new threads that show up
+ // while we stop and run async packets. Setting the packet to 'c' to
+ // continue all threads is the right thing to do 99.99% of the time
+ // because if a thread was single stepping, and we sent an interrupt, we
+ // will notice above that we didn't stop due to an interrupt but stopped
+ // due to stepping and we would _not_ continue. This packet may get
+ // modified by the async actions (e.g. to send a signal).
m_continue_packet = 'c';
cont_lock.unlock();
@@ -177,6 +175,30 @@ GDBRemoteClientBase::SendPacketAndWaitForResponse(
}
GDBRemoteCommunication::PacketResult
+GDBRemoteClientBase::SendPacketAndReceiveResponseWithOutputSupport(
+ llvm::StringRef payload, StringExtractorGDBRemote &response,
+ bool send_async,
+ llvm::function_ref<void(llvm::StringRef)> output_callback) {
+ Lock lock(*this, send_async);
+ if (!lock) {
+ if (Log *log =
+ ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS))
+ log->Printf("GDBRemoteClientBase::%s failed to get mutex, not sending "
+ "packet '%.*s' (send_async=%d)",
+ __FUNCTION__, int(payload.size()), payload.data(),
+ send_async);
+ return PacketResult::ErrorSendFailed;
+ }
+
+ PacketResult packet_result = SendPacketNoLock(payload);
+ if (packet_result != PacketResult::Success)
+ return packet_result;
+
+ return ReadPacketWithOutputSupport(response, GetPacketTimeout(), true,
+ output_callback);
+}
+
+GDBRemoteCommunication::PacketResult
GDBRemoteClientBase::SendPacketAndWaitForResponseNoLock(
llvm::StringRef payload, StringExtractorGDBRemote &response) {
PacketResult packet_result = SendPacketNoLock(payload);
@@ -239,19 +261,16 @@ bool GDBRemoteClientBase::ShouldStop(const UnixSignals &signals,
if (m_async_count == 0)
return true; // We were not interrupted. The process stopped on its own.
- // Older debugserver stubs (before April 2016) can return two
- // stop-reply packets in response to a ^C packet.
- // Additionally, all debugservers still return two stop replies if
- // the inferior stops due to some other reason before the remote
- // stub manages to interrupt it. We need to wait for this
- // additional packet to make sure the packet sequence does not get
- // skewed.
+ // Older debugserver stubs (before April 2016) can return two stop-reply
+ // packets in response to a ^C packet. Additionally, all debugservers still
+ // return two stop replies if the inferior stops due to some other reason
+ // before the remote stub manages to interrupt it. We need to wait for this
+ // additional packet to make sure the packet sequence does not get skewed.
StringExtractorGDBRemote extra_stop_reply_packet;
ReadPacket(extra_stop_reply_packet, milliseconds(100), false);
- // Interrupting is typically done using SIGSTOP or SIGINT, so if
- // the process stops with some other signal, we definitely want to
- // stop.
+ // Interrupting is typically done using SIGSTOP or SIGINT, so if the process
+ // stops with some other signal, we definitely want to stop.
const uint8_t signo = response.GetHexU8(UINT8_MAX);
if (signo != signals.GetSignalNumberFromName("SIGSTOP") &&
signo != signals.GetSignalNumberFromName("SIGINT"))
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
index 2646405c9b91..3d84ce0ebe18 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
@@ -48,6 +48,11 @@ public:
StringExtractorGDBRemote &response,
bool send_async);
+ PacketResult SendPacketAndReceiveResponseWithOutputSupport(
+ llvm::StringRef payload, StringExtractorGDBRemote &response,
+ bool send_async,
+ llvm::function_ref<void(llvm::StringRef)> output_callback);
+
bool SendvContPacket(llvm::StringRef payload,
StringExtractorGDBRemote &response);
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 949cf19db658..c335b6002861 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -150,9 +150,8 @@ GDBRemoteCommunication::~GDBRemoteCommunication() {
Disconnect();
}
- // Stop the communications read thread which is used to parse all
- // incoming packets. This function will block until the read
- // thread returns.
+ // Stop the communications read thread which is used to parse all incoming
+ // packets. This function will block until the read thread returns.
if (m_read_thread_enabled)
StopReadThread();
}
@@ -217,12 +216,10 @@ GDBRemoteCommunication::SendPacketNoLock(llvm::StringRef payload) {
}
}
- // If logging was just enabled and we have history, then dump out what
- // we have to the log so we get the historical context. The Dump() call
- // that
+ // If logging was just enabled and we have history, then dump out what we
+ // have to the log so we get the historical context. The Dump() call that
// logs all of the packet will set a boolean so that we don't dump this
- // more
- // than once
+ // more than once
if (!m_history.DidDumpToLog())
m_history.Dump(log);
@@ -275,6 +272,23 @@ GDBRemoteCommunication::PacketResult GDBRemoteCommunication::GetAck() {
}
GDBRemoteCommunication::PacketResult
+GDBRemoteCommunication::ReadPacketWithOutputSupport(
+ StringExtractorGDBRemote &response, Timeout<std::micro> timeout,
+ bool sync_on_timeout,
+ llvm::function_ref<void(llvm::StringRef)> output_callback) {
+ auto result = ReadPacket(response, timeout, sync_on_timeout);
+ while (result == PacketResult::Success && response.IsNormalResponse() &&
+ response.PeekChar() == 'O') {
+ response.GetChar();
+ std::string output;
+ if (response.GetHexByteString(output))
+ output_callback(output);
+ result = ReadPacket(response, timeout, sync_on_timeout);
+ }
+ return result;
+}
+
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunication::ReadPacket(StringExtractorGDBRemote &response,
Timeout<std::micro> timeout,
bool sync_on_timeout) {
@@ -286,8 +300,8 @@ GDBRemoteCommunication::ReadPacket(StringExtractorGDBRemote &response,
// This function is called when a packet is requested.
// A whole packet is popped from the packet queue and returned to the caller.
-// Packets are placed into this queue from the communication read thread.
-// See GDBRemoteCommunication::AppendBytesToCache.
+// Packets are placed into this queue from the communication read thread. See
+// GDBRemoteCommunication::AppendBytesToCache.
GDBRemoteCommunication::PacketResult
GDBRemoteCommunication::PopPacketFromQueue(StringExtractorGDBRemote &response,
Timeout<std::micro> timeout) {
@@ -407,11 +421,9 @@ GDBRemoteCommunication::WaitForPacketNoLock(StringExtractorGDBRemote &packet,
break;
} else if (successful_responses == 1) {
// We got something else back as the first successful
- // response, it probably is
- // the response to the packet we actually wanted, so copy it
- // over if this
- // is the first success and continue to try to get the qEcho
- // response
+ // response, it probably is the response to the packet we
+ // actually wanted, so copy it over if this is the first
+ // success and continue to try to get the qEcho response
packet = echo_response;
got_actual_response = true;
}
@@ -424,14 +436,13 @@ GDBRemoteCommunication::WaitForPacketNoLock(StringExtractorGDBRemote &packet,
}
// We weren't able to sync back up with the server, we must abort
- // otherwise
- // all responses might not be from the right packets...
+ // otherwise all responses might not be from the right packets...
if (sync_success) {
// We timed out, but were able to recover
if (got_actual_response) {
// We initially timed out, but we did get a response that came in
- // before the successful
- // reply to our qEcho packet, so lets say everything is fine...
+ // before the successful reply to our qEcho packet, so lets say
+ // everything is fine...
return PacketResult::Success;
}
} else {
@@ -473,10 +484,9 @@ bool GDBRemoteCommunication::DecompressPacket() {
size_t pkt_size = m_bytes.size();
- // Smallest possible compressed packet is $N#00 - an uncompressed empty reply,
- // most commonly indicating
- // an unsupported packet. Anything less than 5 characters, it's definitely
- // not a compressed packet.
+ // Smallest possible compressed packet is $N#00 - an uncompressed empty
+ // reply, most commonly indicating an unsupported packet. Anything less than
+ // 5 characters, it's definitely not a compressed packet.
if (pkt_size < 5)
return true;
@@ -505,17 +515,15 @@ bool GDBRemoteCommunication::DecompressPacket() {
1; // The first character of the two hex checksum characters
// Normally size_of_first_packet == m_bytes.size() but m_bytes may contain
- // multiple packets.
- // size_of_first_packet is the size of the initial packet which we'll replace
- // with the decompressed
- // version of, leaving the rest of m_bytes unmodified.
+ // multiple packets. size_of_first_packet is the size of the initial packet
+ // which we'll replace with the decompressed version of, leaving the rest of
+ // m_bytes unmodified.
size_t size_of_first_packet = hash_mark_idx + 3;
// Compressed packets ("$C") start with a base10 number which is the size of
- // the uncompressed payload,
- // then a : and then the compressed data. e.g. $C1024:<binary>#00
- // Update content_start and content_length to only include the <binary> part
- // of the packet.
+ // the uncompressed payload, then a : and then the compressed data. e.g.
+ // $C1024:<binary>#00 Update content_start and content_length to only include
+ // the <binary> part of the packet.
uint64_t decompressed_bufsize = ULONG_MAX;
if (m_bytes[1] == 'C') {
@@ -564,15 +572,14 @@ bool GDBRemoteCommunication::DecompressPacket() {
}
if (m_bytes[1] == 'N') {
- // This packet was not compressed -- delete the 'N' character at the
- // start and the packet may be processed as-is.
+ // This packet was not compressed -- delete the 'N' character at the start
+ // and the packet may be processed as-is.
m_bytes.erase(1, 1);
return true;
}
- // Reverse the gdb-remote binary escaping that was done to the compressed text
- // to
- // guard characters like '$', '#', '}', etc.
+ // Reverse the gdb-remote binary escaping that was done to the compressed
+ // text to guard characters like '$', '#', '}', etc.
std::vector<uint8_t> unescaped_content;
unescaped_content.reserve(content_length);
size_t i = content_start;
@@ -613,12 +620,10 @@ bool GDBRemoteCommunication::DecompressPacket() {
else if (m_compression_type == CompressionType::LZMA)
compression_type = COMPRESSION_LZMA;
- // If we have the expected size of the decompressed payload, we can allocate
- // the right-sized buffer and do it. If we don't have that information,
- // we'll
- // need to try decoding into a big buffer and if the buffer wasn't big
- // enough,
- // increase it and try again.
+ // If we have the expected size of the decompressed payload, we can
+ // allocate the right-sized buffer and do it. If we don't have that
+ // information, we'll need to try decoding into a big buffer and if the
+ // buffer wasn't big enough, increase it and try again.
if (decompressed_bufsize != ULONG_MAX && decompressed_buffer != nullptr) {
decompressed_bytes = compression_decode_buffer(
@@ -706,9 +711,8 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
// Parse up the packets into gdb remote packets
if (!m_bytes.empty()) {
- // end_idx must be one past the last valid packet byte. Start
- // it off with an invalid value that is the same as the current
- // index.
+ // end_idx must be one past the last valid packet byte. Start it off with
+ // an invalid value that is the same as the current index.
size_t content_start = 0;
size_t content_length = 0;
size_t total_length = 0;
@@ -743,7 +747,8 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
checksum_idx = hash_pos + 1;
// Skip the dollar sign
content_start = 1;
- // Don't include the # in the content or the $ in the content length
+ // Don't include the # in the content or the $ in the content
+ // length
content_length = hash_pos - 1;
total_length =
@@ -757,11 +762,10 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
break;
default: {
- // We have an unexpected byte and we need to flush all bad
- // data that is in m_bytes, so we need to find the first
- // byte that is a '+' (ACK), '-' (NACK), \x03 (CTRL+C interrupt),
- // or '$' character (start of packet header) or of course,
- // the end of the data in m_bytes...
+ // We have an unexpected byte and we need to flush all bad data that is
+ // in m_bytes, so we need to find the first byte that is a '+' (ACK), '-'
+ // (NACK), \x03 (CTRL+C interrupt), or '$' character (start of packet
+ // header) or of course, the end of the data in m_bytes...
const size_t bytes_len = m_bytes.size();
bool done = false;
uint32_t idx;
@@ -802,16 +806,14 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
if (log) {
// If logging was just enabled and we have history, then dump out what
// we have to the log so we get the historical context. The Dump() call
- // that
- // logs all of the packet will set a boolean so that we don't dump this
- // more
- // than once
+ // that logs all of the packet will set a boolean so that we don't dump
+ // this more than once
if (!m_history.DidDumpToLog())
m_history.Dump(log);
bool binary = false;
- // Only detect binary for packets that start with a '$' and have a '#CC'
- // checksum
+ // Only detect binary for packets that start with a '$' and have a
+ // '#CC' checksum
if (m_bytes[0] == '$' && total_length > 4) {
for (size_t i = 0; !binary && i < total_length; ++i) {
unsigned char c = m_bytes[i];
@@ -834,8 +836,8 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
// Remove binary escaped bytes when displaying the packet...
const char ch = m_bytes[i];
if (ch == 0x7d) {
- // 0x7d is the escape character. The next character is to
- // be XOR'd with 0x20.
+ // 0x7d is the escape character. The next character is to be
+ // XOR'd with 0x20.
const char escapee = m_bytes[++i] ^ 0x20;
strm.Printf("%2.2x", escapee);
} else {
@@ -863,26 +865,25 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
// Clear packet_str in case there is some existing data in it.
packet_str.clear();
- // Copy the packet from m_bytes to packet_str expanding the
- // run-length encoding in the process.
- // Reserve enough byte for the most common case (no RLE used)
+ // Copy the packet from m_bytes to packet_str expanding the run-length
+ // encoding in the process. Reserve enough byte for the most common case
+ // (no RLE used)
packet_str.reserve(m_bytes.length());
for (std::string::const_iterator c = m_bytes.begin() + content_start;
c != m_bytes.begin() + content_end; ++c) {
if (*c == '*') {
- // '*' indicates RLE. Next character will give us the
- // repeat count and previous character is what is to be
- // repeated.
+ // '*' indicates RLE. Next character will give us the repeat count
+ // and previous character is what is to be repeated.
char char_to_repeat = packet_str.back();
// Number of time the previous character is repeated
int repeat_count = *++c + 3 - ' ';
- // We have the char_to_repeat and repeat_count. Now push
- // it in the packet.
+ // We have the char_to_repeat and repeat_count. Now push it in the
+ // packet.
for (int i = 0; i < repeat_count; ++i)
packet_str.push_back(char_to_repeat);
} else if (*c == 0x7d) {
- // 0x7d is the escape character. The next character is to
- // be XOR'd with 0x20.
+ // 0x7d is the escape character. The next character is to be XOR'd
+ // with 0x20.
char escapee = *++c ^ 0x20;
packet_str.push_back(escapee);
} else {
@@ -897,7 +898,8 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
if (GetSendAcks()) {
const char *packet_checksum_cstr = &m_bytes[checksum_idx];
char packet_checksum = strtol(packet_checksum_cstr, NULL, 16);
- char actual_checksum = CalculcateChecksum(packet_str);
+ char actual_checksum = CalculcateChecksum(
+ llvm::StringRef(m_bytes).slice(content_start, content_end));
success = packet_checksum == actual_checksum;
if (!success) {
if (log)
@@ -991,11 +993,12 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
char debugserver_path[PATH_MAX];
FileSpec &debugserver_file_spec = launch_info.GetExecutableFile();
- // Always check to see if we have an environment override for the path
- // to the debugserver to use and use it if we do.
+ // Always check to see if we have an environment override for the path to the
+ // debugserver to use and use it if we do.
const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH");
if (env_debugserver_path) {
- debugserver_file_spec.SetFile(env_debugserver_path, false);
+ debugserver_file_spec.SetFile(env_debugserver_path, false,
+ FileSpec::Style::native);
if (log)
log->Printf("GDBRemoteCommunication::%s() gdb-remote stub exe path set "
"from environment variable: %s",
@@ -1004,10 +1007,9 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
debugserver_file_spec = g_debugserver_file_spec;
bool debugserver_exists = debugserver_file_spec.Exists();
if (!debugserver_exists) {
- // The debugserver binary is in the LLDB.framework/Resources
- // directory.
- if (HostInfo::GetLLDBPath(ePathTypeSupportExecutableDir,
- debugserver_file_spec)) {
+ // The debugserver binary is in the LLDB.framework/Resources directory.
+ debugserver_file_spec = HostInfo::GetSupportExeDir();
+ if (debugserver_file_spec) {
debugserver_file_spec.AppendPathComponent(DEBUGSERVER_BASENAME);
debugserver_exists = debugserver_file_spec.Exists();
if (debugserver_exists) {
@@ -1031,8 +1033,7 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
__FUNCTION__, debugserver_file_spec.GetPath().c_str());
}
// Don't cache the platform specific GDB server binary as it could
- // change
- // from platform to platform
+ // change from platform to platform
g_debugserver_file_spec.Clear();
}
}
@@ -1080,14 +1081,14 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
// once data is written to the pipe, debug server is up and running.
Pipe socket_pipe;
- // port is null when debug server should listen on domain socket -
- // we're not interested in port value but rather waiting for debug server
- // to become available.
+ // port is null when debug server should listen on domain socket - we're
+ // not interested in port value but rather waiting for debug server to
+ // become available.
if (pass_comm_fd == -1) {
if (url) {
-// Create a temporary file to get the stdout/stderr and redirect the
-// output of the command into this file. We will later read this file
-// if all goes well and fill the data into "command_output_ptr"
+// Create a temporary file to get the stdout/stderr and redirect the output of
+// the command into this file. We will later read this file if all goes well
+// and fill the data into "command_output_ptr"
#if defined(__APPLE__)
// Binding to port zero, we need to figure out what port it ends up
// using using a named pipe...
@@ -1120,8 +1121,7 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
#endif
} else {
// No host and port given, so lets listen on our end and make the
- // debugserver
- // connect to us..
+ // debugserver connect to us..
error = StartListenThread("127.0.0.1", 0);
if (error.Fail()) {
if (log)
@@ -1134,7 +1134,7 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
ConnectionFileDescriptor *connection =
(ConnectionFileDescriptor *)GetConnection();
// Wait for 10 seconds to resolve the bound port
- uint16_t port_ = connection->GetListeningPort(10);
+ uint16_t port_ = connection->GetListeningPort(std::chrono::seconds(10));
if (port_ > 0) {
char port_cstr[32];
snprintf(port_cstr, sizeof(port_cstr), "127.0.0.1:%i", port_);
@@ -1206,11 +1206,7 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
}
// Copy the current environment to the gdbserver/debugserver instance
- StringList env;
- if (Host::GetEnvironment(env)) {
- for (size_t i = 0; i < env.GetSize(); ++i)
- launch_info.GetEnvironmentEntries().AppendArgument(env[i]);
- }
+ launch_info.GetEnvironment() = Host::GetEnvironment();
// Close STDIN, STDOUT and STDERR.
launch_info.AppendCloseFileAction(STDIN_FILENO);
@@ -1327,14 +1323,11 @@ GDBRemoteCommunication::ScopedTimeout::~ScopedTimeout() {
}
// This function is called via the Communications class read thread when bytes
-// become available
-// for this connection. This function will consume all incoming bytes and try to
-// parse whole
-// packets as they become available. Full packets are placed in a queue, so that
-// all packet
-// requests can simply pop from this queue. Async notification packets will be
-// dispatched
-// immediately to the ProcessGDBRemote Async thread via an event.
+// become available for this connection. This function will consume all
+// incoming bytes and try to parse whole packets as they become available. Full
+// packets are placed in a queue, so that all packet requests can simply pop
+// from this queue. Async notification packets will be dispatched immediately
+// to the ProcessGDBRemote Async thread via an event.
void GDBRemoteCommunication::AppendBytesToCache(const uint8_t *bytes,
size_t len, bool broadcast,
lldb::ConnectionStatus status) {
@@ -1343,8 +1336,8 @@ void GDBRemoteCommunication::AppendBytesToCache(const uint8_t *bytes,
while (true) {
PacketType type = CheckForPacket(bytes, len, packet);
- // scrub the data so we do not pass it back to CheckForPacket
- // on future passes of the loop
+ // scrub the data so we do not pass it back to CheckForPacket on future
+ // passes of the loop
bytes = nullptr;
len = 0;
@@ -1368,8 +1361,8 @@ void GDBRemoteCommunication::AppendBytesToCache(const uint8_t *bytes,
// put this packet into an event
const char *pdata = packet.GetStringRef().c_str();
- // as the communication class, we are a broadcaster and the
- // async thread is tuned to listen to us
+ // as the communication class, we are a broadcaster and the async thread
+ // is tuned to listen to us
BroadcastEvent(eBroadcastBitGdbReadThreadGotNotify,
new EventDataBytes(pdata));
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index ecc9386e49c7..67796e4c61ef 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -24,10 +24,10 @@
#include "lldb/Core/Listener.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Host/Predicate.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Utility/Args.h"
#include "lldb/lldb-public.h"
-#include "Utility/StringExtractorGDBRemote.h"
+#include "lldb/Utility/StringExtractorGDBRemote.h"
namespace lldb_private {
namespace process_gdb_remote {
@@ -232,6 +232,11 @@ protected:
PacketResult ReadPacket(StringExtractorGDBRemote &response,
Timeout<std::micro> timeout, bool sync_on_timeout);
+ PacketResult ReadPacketWithOutputSupport(
+ StringExtractorGDBRemote &response, Timeout<std::micro> timeout,
+ bool sync_on_timeout,
+ llvm::function_ref<void(llvm::StringRef)> output_callback);
+
// Pop a packet from the queue in a thread safe manner
PacketResult PopPacketFromQueue(StringExtractorGDBRemote &response,
Timeout<std::micro> timeout);
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 867f57c475ce..c8b59d5d236b 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -21,11 +21,12 @@
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/State.h"
#include "lldb/Host/HostInfo.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Host/XML.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/UnixSignals.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/JSON.h"
#include "lldb/Utility/LLDBAssert.h"
@@ -35,8 +36,8 @@
// Project includes
#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
-#include "Utility/StringExtractorGDBRemote.h"
#include "lldb/Host/Config.h"
+#include "lldb/Utility/StringExtractorGDBRemote.h"
#include "llvm/ADT/StringSwitch.h"
@@ -81,6 +82,7 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
m_supports_qXfer_libraries_read(eLazyBoolCalculate),
m_supports_qXfer_libraries_svr4_read(eLazyBoolCalculate),
m_supports_qXfer_features_read(eLazyBoolCalculate),
+ m_supports_qXfer_memory_map_read(eLazyBoolCalculate),
m_supports_augmented_libraries_svr4_read(eLazyBoolCalculate),
m_supports_jThreadExtendedInfo(eLazyBoolCalculate),
m_supports_jLoadedDynamicLibrariesInfos(eLazyBoolCalculate),
@@ -98,12 +100,12 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
m_curr_pid(LLDB_INVALID_PROCESS_ID), m_curr_tid(LLDB_INVALID_THREAD_ID),
m_curr_tid_run(LLDB_INVALID_THREAD_ID),
m_num_supported_hardware_watchpoints(0), m_host_arch(), m_process_arch(),
- m_os_version_major(UINT32_MAX), m_os_version_minor(UINT32_MAX),
- m_os_version_update(UINT32_MAX), m_os_build(), m_os_kernel(),
- m_hostname(), m_gdb_server_name(), m_gdb_server_version(UINT32_MAX),
- m_default_packet_timeout(0), m_max_packet_size(0),
- m_qSupported_response(), m_supported_async_json_packets_is_valid(false),
- m_supported_async_json_packets_sp() {}
+ m_os_build(), m_os_kernel(), m_hostname(), m_gdb_server_name(),
+ m_gdb_server_version(UINT32_MAX), m_default_packet_timeout(0),
+ m_max_packet_size(0), m_qSupported_response(),
+ m_supported_async_json_packets_is_valid(false),
+ m_supported_async_json_packets_sp(), m_qXfer_memory_map(),
+ m_qXfer_memory_map_loaded(false) {}
//----------------------------------------------------------------------
// Destructor
@@ -116,8 +118,8 @@ GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() {
bool GDBRemoteCommunicationClient::HandshakeWithServer(Status *error_ptr) {
ResetDiscoverableSettings(false);
- // Start the read thread after we send the handshake ack since if we
- // fail to send the handshake ack, there is no reason to continue...
+ // Start the read thread after we send the handshake ack since if we fail to
+ // send the handshake ack, there is no reason to continue...
if (SendAck()) {
// Wait for any responses that might have been queued up in the remote
// GDB server and flush them all
@@ -127,9 +129,9 @@ bool GDBRemoteCommunicationClient::HandshakeWithServer(Status *error_ptr) {
packet_result = ReadPacket(response, milliseconds(10), false);
// The return value from QueryNoAckModeSupported() is true if the packet
- // was sent and _any_ response (including UNIMPLEMENTED) was received),
- // or false if no response was received. This quickly tells us if we have
- // a live connection to a remote GDB server...
+ // was sent and _any_ response (including UNIMPLEMENTED) was received), or
+ // false if no response was received. This quickly tells us if we have a
+ // live connection to a remote GDB server...
if (QueryNoAckModeSupported()) {
return true;
} else {
@@ -192,6 +194,13 @@ bool GDBRemoteCommunicationClient::GetQXferFeaturesReadSupported() {
return m_supports_qXfer_features_read == eLazyBoolYes;
}
+bool GDBRemoteCommunicationClient::GetQXferMemoryMapReadSupported() {
+ if (m_supports_qXfer_memory_map_read == eLazyBoolCalculate) {
+ GetRemoteQSupported();
+ }
+ return m_supports_qXfer_memory_map_read == eLazyBoolYes;
+}
+
uint64_t GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() {
if (m_max_packet_size == 0) {
GetRemoteQSupported();
@@ -205,9 +214,8 @@ bool GDBRemoteCommunicationClient::QueryNoAckModeSupported() {
m_supports_not_sending_acks = eLazyBoolNo;
// This is the first real packet that we'll send in a debug session and it
- // may take a little
- // longer than normal to receive a reply. Wait at least 6 seconds for a
- // reply to this packet.
+ // may take a little longer than normal to receive a reply. Wait at least
+ // 6 seconds for a reply to this packet.
ScopedTimeout timeout(*this, std::max(GetPacketTimeout(), seconds(6)));
@@ -296,6 +304,7 @@ void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {
m_supports_qXfer_libraries_read = eLazyBoolCalculate;
m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
m_supports_qXfer_features_read = eLazyBoolCalculate;
+ m_supports_qXfer_memory_map_read = eLazyBoolCalculate;
m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
m_supports_qProcessInfoPID = true;
m_supports_qfProcessInfo = true;
@@ -313,9 +322,7 @@ void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {
m_qSymbol_requests_done = false;
m_supports_qModuleInfo = true;
m_host_arch.Clear();
- m_os_version_major = UINT32_MAX;
- m_os_version_minor = UINT32_MAX;
- m_os_version_update = UINT32_MAX;
+ m_os_version = llvm::VersionTuple();
m_os_build.clear();
m_os_kernel.clear();
m_hostname.clear();
@@ -329,8 +336,8 @@ void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {
m_supports_jModulesInfo = true;
}
- // These flags should be reset when we first connect to a GDB server
- // and when our inferior process execs
+ // These flags should be reset when we first connect to a GDB server and when
+ // our inferior process execs
m_qProcessInfo_is_valid = eLazyBoolCalculate;
m_process_arch.Clear();
}
@@ -342,6 +349,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
m_supports_qXfer_libraries_svr4_read = eLazyBoolNo;
m_supports_augmented_libraries_svr4_read = eLazyBoolNo;
m_supports_qXfer_features_read = eLazyBoolNo;
+ m_supports_qXfer_memory_map_read = eLazyBoolNo;
m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if
// not, we assume no limit
@@ -361,8 +369,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
const char *response_cstr = response.GetStringRef().c_str();
// Hang on to the qSupported packet, so that platforms can do custom
- // configuration of the transport before attaching/launching the
- // process.
+ // configuration of the transport before attaching/launching the process.
m_qSupported_response = response_cstr;
if (::strstr(response_cstr, "qXfer:auxv:read+"))
@@ -377,9 +384,12 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
m_supports_qXfer_libraries_read = eLazyBoolYes;
if (::strstr(response_cstr, "qXfer:features:read+"))
m_supports_qXfer_features_read = eLazyBoolYes;
+ if (::strstr(response_cstr, "qXfer:memory-map:read+"))
+ m_supports_qXfer_memory_map_read = eLazyBoolYes;
// Look for a list of compressions in the features list e.g.
- // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-deflate,lzma
+ // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-
+ // deflate,lzma
const char *features_list = ::strstr(response_cstr, "qXfer:features:");
if (features_list) {
const char *compressions =
@@ -543,9 +553,8 @@ GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse(
return SendPacketAndWaitForResponseNoLock(payload.GetString(), response);
}
-// Check if the target supports 'p' packet. It sends out a 'p'
-// packet and checks the response. A normal packet will tell us
-// that support is available.
+// Check if the target supports 'p' packet. It sends out a 'p' packet and
+// checks the response. A normal packet will tell us that support is available.
//
// Takes a valid thread ID because p needs to apply to a thread.
bool GDBRemoteCommunicationClient::GetpPacketSupported(lldb::tid_t tid) {
@@ -600,8 +609,8 @@ bool GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported() {
void GDBRemoteCommunicationClient::EnableErrorStringInPacket() {
if (m_supports_error_string_reply == eLazyBoolCalculate) {
StringExtractorGDBRemote response;
- // We try to enable error strings in remote packets
- // but if we fail, we just work in the older way.
+ // We try to enable error strings in remote packets but if we fail, we just
+ // work in the older way.
m_supports_error_string_reply = eLazyBoolNo;
if (SendPacketAndWaitForResponse("QEnableErrorStrings", response, false) ==
PacketResult::Success) {
@@ -715,12 +724,10 @@ lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) {
return m_curr_pid;
} else {
// If we don't get a response for qProcessInfo, check if $qC gives us a
- // result.
- // $qC only returns a real process id on older debugserver and lldb-platform
- // stubs.
- // The gdb remote protocol documents $qC as returning the thread id, which
- // newer
- // debugserver and lldb-gdbserver stubs return correctly.
+ // result. $qC only returns a real process id on older debugserver and
+ // lldb-platform stubs. The gdb remote protocol documents $qC as returning
+ // the thread id, which newer debugserver and lldb-gdbserver stubs return
+ // correctly.
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse("qC", response, false) ==
PacketResult::Success) {
@@ -775,8 +782,8 @@ bool GDBRemoteCommunicationClient::GetLaunchSuccess(std::string &error_str) {
int GDBRemoteCommunicationClient::SendArgumentsPacket(
const ProcessLaunchInfo &launch_info) {
// Since we don't get the send argv0 separate from the executable path, we
- // need to
- // make sure to use the actual executable path found in the launch_info...
+ // need to make sure to use the actual executable path found in the
+ // launch_info...
std::vector<const char *> argv;
FileSpec exe_file = launch_info.GetExecutableFile();
std::string exe_path;
@@ -822,6 +829,15 @@ int GDBRemoteCommunicationClient::SendArgumentsPacket(
return -1;
}
+int GDBRemoteCommunicationClient::SendEnvironment(const Environment &env) {
+ for (const auto &KV : env) {
+ int r = SendEnvironmentPacket(Environment::compose(KV).c_str());
+ if (r != 0)
+ return r;
+ }
+ return 0;
+}
+
int GDBRemoteCommunicationClient::SendEnvironmentPacket(
char const *name_equal_value) {
if (name_equal_value && name_equal_value[0]) {
@@ -925,18 +941,9 @@ int GDBRemoteCommunicationClient::SendLaunchEventDataPacket(
return -1;
}
-bool GDBRemoteCommunicationClient::GetOSVersion(uint32_t &major,
- uint32_t &minor,
- uint32_t &update) {
- if (GetHostInfo()) {
- if (m_os_version_major != UINT32_MAX) {
- major = m_os_version_major;
- minor = m_os_version_minor;
- update = m_os_version_update;
- return true;
- }
- }
- return false;
+llvm::VersionTuple GDBRemoteCommunicationClient::GetOSVersion() {
+ GetHostInfo();
+ return m_os_version;
}
bool GDBRemoteCommunicationClient::GetOSBuildString(std::string &s) {
@@ -1199,9 +1206,7 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
// "version" key instead of
// "os_version"...
{
- Args::StringToVersion(value, m_os_version_major, m_os_version_minor,
- m_os_version_update);
- if (m_os_version_major != UINT32_MAX)
+ if (!m_os_version.tryParse(value))
++num_keys_decoded;
} else if (name.equals("watchpoint_exceptions_received")) {
m_watchpoints_trigger_after_instruction =
@@ -1451,7 +1456,8 @@ Status GDBRemoteCommunicationClient::GetMemoryRegionInfo(
UNUSED_IF_ASSERT_DISABLED(packet_len);
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse(packet, response, false) ==
- PacketResult::Success) {
+ PacketResult::Success &&
+ response.GetResponseType() == StringExtractorGDBRemote::eResponse) {
llvm::StringRef name;
llvm::StringRef value;
addr_t addr_value = LLDB_INVALID_ADDRESS;
@@ -1527,8 +1533,134 @@ Status GDBRemoteCommunicationClient::GetMemoryRegionInfo(
if (m_supports_memory_region_info == eLazyBoolNo) {
error.SetErrorString("qMemoryRegionInfo is not supported");
}
- if (error.Fail())
- region_info.Clear();
+
+ // Try qXfer:memory-map:read to get region information not included in
+ // qMemoryRegionInfo
+ MemoryRegionInfo qXfer_region_info;
+ Status qXfer_error = GetQXferMemoryMapRegionInfo(addr, qXfer_region_info);
+
+ if (error.Fail()) {
+ // If qMemoryRegionInfo failed, but qXfer:memory-map:read succeeded, use
+ // the qXfer result as a fallback
+ if (qXfer_error.Success()) {
+ region_info = qXfer_region_info;
+ error.Clear();
+ } else {
+ region_info.Clear();
+ }
+ } else if (qXfer_error.Success()) {
+ // If both qMemoryRegionInfo and qXfer:memory-map:read succeeded, and if
+ // both regions are the same range, update the result to include the flash-
+ // memory information that is specific to the qXfer result.
+ if (region_info.GetRange() == qXfer_region_info.GetRange()) {
+ region_info.SetFlash(qXfer_region_info.GetFlash());
+ region_info.SetBlocksize(qXfer_region_info.GetBlocksize());
+ }
+ }
+ return error;
+}
+
+Status GDBRemoteCommunicationClient::GetQXferMemoryMapRegionInfo(
+ lldb::addr_t addr, MemoryRegionInfo &region) {
+ Status error = LoadQXferMemoryMap();
+ if (!error.Success())
+ return error;
+ for (const auto &map_region : m_qXfer_memory_map) {
+ if (map_region.GetRange().Contains(addr)) {
+ region = map_region;
+ return error;
+ }
+ }
+ error.SetErrorString("Region not found");
+ return error;
+}
+
+Status GDBRemoteCommunicationClient::LoadQXferMemoryMap() {
+
+ Status error;
+
+ if (m_qXfer_memory_map_loaded)
+ // Already loaded, return success
+ return error;
+
+ if (!XMLDocument::XMLEnabled()) {
+ error.SetErrorString("XML is not supported");
+ return error;
+ }
+
+ if (!GetQXferMemoryMapReadSupported()) {
+ error.SetErrorString("Memory map is not supported");
+ return error;
+ }
+
+ std::string xml;
+ lldb_private::Status lldberr;
+ if (!ReadExtFeature(ConstString("memory-map"), ConstString(""), xml,
+ lldberr)) {
+ error.SetErrorString("Failed to read memory map");
+ return error;
+ }
+
+ XMLDocument xml_document;
+
+ if (!xml_document.ParseMemory(xml.c_str(), xml.size())) {
+ error.SetErrorString("Failed to parse memory map xml");
+ return error;
+ }
+
+ XMLNode map_node = xml_document.GetRootElement("memory-map");
+ if (!map_node) {
+ error.SetErrorString("Invalid root node in memory map xml");
+ return error;
+ }
+
+ m_qXfer_memory_map.clear();
+
+ map_node.ForEachChildElement([this](const XMLNode &memory_node) -> bool {
+ if (!memory_node.IsElement())
+ return true;
+ if (memory_node.GetName() != "memory")
+ return true;
+ auto type = memory_node.GetAttributeValue("type", "");
+ uint64_t start;
+ uint64_t length;
+ if (!memory_node.GetAttributeValueAsUnsigned("start", start))
+ return true;
+ if (!memory_node.GetAttributeValueAsUnsigned("length", length))
+ return true;
+ MemoryRegionInfo region;
+ region.GetRange().SetRangeBase(start);
+ region.GetRange().SetByteSize(length);
+ if (type == "rom") {
+ region.SetReadable(MemoryRegionInfo::eYes);
+ this->m_qXfer_memory_map.push_back(region);
+ } else if (type == "ram") {
+ region.SetReadable(MemoryRegionInfo::eYes);
+ region.SetWritable(MemoryRegionInfo::eYes);
+ this->m_qXfer_memory_map.push_back(region);
+ } else if (type == "flash") {
+ region.SetFlash(MemoryRegionInfo::eYes);
+ memory_node.ForEachChildElement(
+ [&region](const XMLNode &prop_node) -> bool {
+ if (!prop_node.IsElement())
+ return true;
+ if (prop_node.GetName() != "property")
+ return true;
+ auto propname = prop_node.GetAttributeValue("name", "");
+ if (propname == "blocksize") {
+ uint64_t blocksize;
+ if (prop_node.GetElementTextAsUnsigned(blocksize))
+ region.SetBlocksize(blocksize);
+ }
+ return true;
+ });
+ this->m_qXfer_memory_map.push_back(region);
+ }
+ return true;
+ });
+
+ m_qXfer_memory_map_loaded = true;
+
return error;
}
@@ -1585,13 +1717,13 @@ GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction(
Status error;
llvm::Triple::ArchType atype = arch.GetMachine();
- // we assume watchpoints will happen after running the relevant opcode
- // and we only want to override this behavior if we have explicitly
- // received a qHostInfo telling us otherwise
+ // we assume watchpoints will happen after running the relevant opcode and we
+ // only want to override this behavior if we have explicitly received a
+ // qHostInfo telling us otherwise
if (m_qHostInfo_is_valid != eLazyBoolYes) {
// On targets like MIPS and ppc64le, watchpoint exceptions are always
- // generated before the instruction is executed. The connected target
- // may not support qHostInfo or qWatchpointSupportInfo packets.
+ // generated before the instruction is executed. The connected target may
+ // not support qHostInfo or qWatchpointSupportInfo packets.
if (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel ||
atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el ||
atype == llvm::Triple::ppc64le)
@@ -1789,11 +1921,12 @@ bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse(
process_info.GetArchitecture().SetTriple(triple.c_str());
} else if (name.equals("name")) {
StringExtractor extractor(value);
- // The process name from ASCII hex bytes since we can't
- // control the characters in a process name
+ // The process name from ASCII hex bytes since we can't control the
+ // characters in a process name
std::string name;
extractor.GetHexByteString(name);
- process_info.GetExecutableFile().SetFile(name, false);
+ process_info.GetExecutableFile().SetFile(name, false,
+ FileSpec::Style::native);
} else if (name.equals("cputype")) {
value.getAsInteger(0, cpu);
} else if (name.equals("cpusubtype")) {
@@ -2046,8 +2179,8 @@ uint32_t GDBRemoteCommunicationClient::FindProcesses(
}
}
StringExtractorGDBRemote response;
- // Increase timeout as the first qfProcessInfo packet takes a long time
- // on Android. The value of 1min was arrived at empirically.
+ // Increase timeout as the first qfProcessInfo packet takes a long time on
+ // Android. The value of 1min was arrived at empirically.
ScopedTimeout timeout(*this, minutes(1));
if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
PacketResult::Success) {
@@ -2081,8 +2214,8 @@ bool GDBRemoteCommunicationClient::GetUserName(uint32_t uid,
PacketResult::Success) {
if (response.IsNormalResponse()) {
// Make sure we parsed the right number of characters. The response is
- // the hex encoded user name and should make up the entire packet.
- // If there are any non-hex ASCII bytes, the length won't match below..
+ // the hex encoded user name and should make up the entire packet. If
+ // there are any non-hex ASCII bytes, the length won't match below..
if (response.GetHexByteString(name) * 2 ==
response.GetStringRef().size())
return true;
@@ -2108,8 +2241,8 @@ bool GDBRemoteCommunicationClient::GetGroupName(uint32_t gid,
PacketResult::Success) {
if (response.IsNormalResponse()) {
// Make sure we parsed the right number of characters. The response is
- // the hex encoded group name and should make up the entire packet.
- // If there are any non-hex ASCII bytes, the length won't match below..
+ // the hex encoded group name and should make up the entire packet. If
+ // there are any non-hex ASCII bytes, the length won't match below..
if (response.GetHexByteString(name) * 2 ==
response.GetStringRef().size())
return true;
@@ -2335,8 +2468,8 @@ bool GDBRemoteCommunicationClient::LaunchGDBServer(
// Make the GDB server we launch only accept connections from this host
stream.Printf("host:%s;", hostname.c_str());
} else {
- // Make the GDB server we launch accept connections from any host since we
- // can't figure out the hostname
+ // Make the GDB server we launch accept connections from any host since
+ // we can't figure out the hostname
stream.Printf("host:*;");
}
}
@@ -2650,13 +2783,16 @@ lldb_private::Status GDBRemoteCommunicationClient::RunShellCommand(
// process to exit
std::string
*command_output, // Pass NULL if you don't want the command output
- uint32_t
- timeout_sec) // Timeout in seconds to wait for shell program to finish
-{
+ const Timeout<std::micro> &timeout) {
lldb_private::StreamString stream;
stream.PutCString("qPlatform_shell:");
stream.PutBytesAsRawHex8(command, strlen(command));
stream.PutChar(',');
+ uint32_t timeout_sec = UINT32_MAX;
+ if (timeout) {
+ // TODO: Use chrono version of std::ceil once c++17 is available.
+ timeout_sec = std::ceil(std::chrono::duration<double>(*timeout).count());
+ }
stream.PutHex32(timeout_sec);
if (working_dir) {
std::string path{working_dir.GetPath(false)};
@@ -3125,9 +3261,8 @@ bool GDBRemoteCommunicationClient::SaveRegisterState(lldb::tid_t tid,
bool GDBRemoteCommunicationClient::RestoreRegisterState(lldb::tid_t tid,
uint32_t save_id) {
// We use the "m_supports_QSaveRegisterState" variable here because the
- // QSaveRegisterState and QRestoreRegisterState packets must both be supported
- // in
- // order to be useful
+ // QSaveRegisterState and QRestoreRegisterState packets must both be
+ // supported in order to be useful
if (m_supports_QSaveRegisterState == eLazyBoolNo)
return false;
@@ -3406,7 +3541,7 @@ bool GDBRemoteCommunicationClient::GetModuleInfo(
StringExtractor extractor(value);
std::string uuid;
extractor.GetHexByteString(uuid);
- module_spec.GetUUID().SetFromCString(uuid.c_str(), uuid.size() / 2);
+ module_spec.GetUUID().SetFromStringRef(uuid, uuid.size() / 2);
} else if (name == "triple") {
StringExtractor extractor(value);
std::string triple;
@@ -3523,8 +3658,8 @@ GDBRemoteCommunicationClient::GetModulesInfo(
// query the target remote for extended information using the qXfer packet
//
-// example: object='features', annex='target.xml', out=<xml output>
-// return: 'true' on success
+// example: object='features', annex='target.xml', out=<xml output> return:
+// 'true' on success
// 'false' on failure (err set)
bool GDBRemoteCommunicationClient::ReadExtFeature(
const lldb_private::ConstString object,
@@ -3631,10 +3766,9 @@ bool GDBRemoteCommunicationClient::ReadExtFeature(
void GDBRemoteCommunicationClient::ServeSymbolLookups(
lldb_private::Process *process) {
- // Set to true once we've resolved a symbol to an address for the remote stub.
- // If we get an 'OK' response after this, the remote stub doesn't need any
- // more
- // symbols and we can stop asking.
+ // Set to true once we've resolved a symbol to an address for the remote
+ // stub. If we get an 'OK' response after this, the remote stub doesn't need
+ // any more symbols and we can stop asking.
bool symbol_response_provided = false;
// Is this the initial qSymbol:: packet?
@@ -3659,8 +3793,8 @@ void GDBRemoteCommunicationClient::ServeSymbolLookups(
first_qsymbol_query = false;
if (response.IsUnsupportedResponse()) {
- // qSymbol is not supported by the current GDB server we are connected
- // to
+ // qSymbol is not supported by the current GDB server we are
+ // connected to
m_supports_qSymbol = false;
return;
} else {
@@ -3725,10 +3859,8 @@ void GDBRemoteCommunicationClient::ServeSymbolLookups(
}
}
// This is the normal path where our symbol lookup was successful
- // and we want
- // to send a packet with the new symbol value and see if another
- // lookup needs to be
- // done.
+ // and we want to send a packet with the new symbol value and see
+ // if another lookup needs to be done.
// Change "packet" to contain the requested symbol value and name
packet.Clear();
@@ -3763,8 +3895,7 @@ void GDBRemoteCommunicationClient::ServeSymbolLookups(
StructuredData::Array *
GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() {
if (!m_supported_async_json_packets_is_valid) {
- // Query the server for the array of supported asynchronous JSON
- // packets.
+ // Query the server for the array of supported asynchronous JSON packets.
m_supported_async_json_packets_is_valid = true;
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
@@ -3778,8 +3909,8 @@ GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() {
StructuredData::ParseJSON(response.GetStringRef());
if (m_supported_async_json_packets_sp &&
!m_supported_async_json_packets_sp->GetAsArray()) {
- // We were returned something other than a JSON array. This
- // is invalid. Clear it out.
+ // We were returned something other than a JSON array. This is
+ // invalid. Clear it out.
if (log)
log->Printf("GDBRemoteCommunicationClient::%s(): "
"QSupportedAsyncJSONPackets returned invalid "
@@ -3837,8 +3968,7 @@ Status GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(
return error;
}
- // Build command: Configure{type_name}: serialized config
- // data.
+ // Build command: Configure{type_name}: serialized config data.
StreamGDBRemote stream;
stream.PutCString("QConfigure");
stream.PutCString(type_name.AsCString());
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index ba67b8246398..cf1d249768d7 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -121,6 +121,7 @@ public:
/// response was received.
//------------------------------------------------------------------
int SendEnvironmentPacket(char const *name_equal_value);
+ int SendEnvironment(const Environment &env);
int SendLaunchArchPacket(const char *arch);
@@ -265,7 +266,7 @@ public:
bool GetDefaultThreadId(lldb::tid_t &tid);
- bool GetOSVersion(uint32_t &major, uint32_t &minor, uint32_t &update);
+ llvm::VersionTuple GetOSVersion();
bool GetOSBuildString(std::string &s);
@@ -354,6 +355,8 @@ public:
bool GetQXferFeaturesReadSupported();
+ bool GetQXferMemoryMapReadSupported();
+
LazyBool SupportsAllocDeallocMemory() // const
{
// Uncomment this to have lldb pretend the debug server doesn't respond to
@@ -401,8 +404,7 @@ public:
// the process to exit
std::string
*command_output, // Pass nullptr if you don't want the command output
- uint32_t timeout_sec); // Timeout in seconds to wait for shell program to
- // finish
+ const Timeout<std::micro> &timeout);
bool CalculateMD5(const FileSpec &file_spec, uint64_t &high, uint64_t &low);
@@ -544,6 +546,7 @@ protected:
LazyBool m_supports_qXfer_libraries_read;
LazyBool m_supports_qXfer_libraries_svr4_read;
LazyBool m_supports_qXfer_features_read;
+ LazyBool m_supports_qXfer_memory_map_read;
LazyBool m_supports_augmented_libraries_svr4_read;
LazyBool m_supports_jThreadExtendedInfo;
LazyBool m_supports_jLoadedDynamicLibrariesInfos;
@@ -570,9 +573,7 @@ protected:
ArchSpec m_host_arch;
ArchSpec m_process_arch;
- uint32_t m_os_version_major;
- uint32_t m_os_version_minor;
- uint32_t m_os_version_update;
+ llvm::VersionTuple m_os_version;
std::string m_os_build;
std::string m_os_kernel;
std::string m_hostname;
@@ -587,6 +588,9 @@ protected:
bool m_supported_async_json_packets_is_valid;
lldb_private::StructuredData::ObjectSP m_supported_async_json_packets_sp;
+ std::vector<MemoryRegionInfo> m_qXfer_memory_map;
+ bool m_qXfer_memory_map_loaded;
+
bool GetCurrentProcessInfo(bool allow_lazy_pid = true);
bool GetGDBServerVersion();
@@ -609,6 +613,11 @@ protected:
llvm::MutableArrayRef<uint8_t> &buffer,
size_t offset);
+ Status LoadQXferMemoryMap();
+
+ Status GetQXferMemoryMapRegionInfo(lldb::addr_t addr,
+ MemoryRegionInfo &region);
+
private:
DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationClient);
};
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index 4be92b79fd1a..4fc1fc7a1964 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -19,8 +19,8 @@
// Project includes
#include "ProcessGDBRemoteLog.h"
-#include "Utility/StringExtractorGDBRemote.h"
#include "lldb/Utility/StreamString.h"
+#include "lldb/Utility/StringExtractorGDBRemote.h"
using namespace lldb;
using namespace lldb_private;
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
index a35352480040..880caacd6414 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
@@ -57,8 +57,8 @@ protected:
bool m_exit_now; // use in asynchronous handling to indicate process should
// exit.
- bool m_send_error_strings; // If the client enables this then
- // we will send error strings as well.
+ bool m_send_error_strings = false; // If the client enables this then
+ // we will send error strings as well.
PacketResult Handle_QErrorStringEnable(StringExtractorGDBRemote &packet);
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
index 3cf6b8ac07b2..c5b478378faa 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -28,7 +28,7 @@
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/FileAction.h"
#include "lldb/Target/Platform.h"
@@ -36,13 +36,14 @@
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/JSON.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/SafeMachO.h"
#include "lldb/Utility/StreamGDBRemote.h"
#include "lldb/Utility/StreamString.h"
#include "llvm/ADT/Triple.h"
// Project includes
#include "ProcessGDBRemoteLog.h"
-#include "Utility/StringExtractorGDBRemote.h"
+#include "lldb/Utility/StringExtractorGDBRemote.h"
#ifdef __ANDROID__
#include "lldb/Host/android/HostInfoAndroid.h"
@@ -218,12 +219,15 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
if (sub != LLDB_INVALID_CPUTYPE)
response.Printf("cpusubtype:%u;", sub);
- if (cpu == ArchSpec::kCore_arm_any) {
+ if (cpu == llvm::MachO::CPU_TYPE_ARM
+ || cpu == llvm::MachO::CPU_TYPE_ARM64) {
// Indicate the OS type.
#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1
response.PutCString("ostype:tvos;");
#elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
response.PutCString("ostype:watchos;");
+#elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1
+ response.PutCString("ostype:bridgeos;");
#else
response.PutCString("ostype:ios;");
#endif
@@ -265,19 +269,10 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
break;
}
- uint32_t major = UINT32_MAX;
- uint32_t minor = UINT32_MAX;
- uint32_t update = UINT32_MAX;
- if (HostInfo::GetOSVersion(major, minor, update)) {
- if (major != UINT32_MAX) {
- response.Printf("os_version:%u", major);
- if (minor != UINT32_MAX) {
- response.Printf(".%u", minor);
- if (update != UINT32_MAX)
- response.Printf(".%u", update);
- }
- response.PutChar(';');
- }
+ llvm::VersionTuple version = HostInfo::GetOSVersion();
+ if (!version.empty()) {
+ response.Format("os_version:{0}", version.getAsString());
+ response.PutChar(';');
}
std::string s;
@@ -295,9 +290,9 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
#if defined(__APPLE__)
#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
- // For iOS devices, we are connected through a USB Mux so we never pretend
- // to actually have a hostname as far as the remote lldb that is connecting
- // to this lldb-platform is concerned
+ // For iOS devices, we are connected through a USB Mux so we never pretend to
+ // actually have a hostname as far as the remote lldb that is connecting to
+ // this lldb-platform is concerned
response.PutCString("hostname:");
response.PutCStringAsRawHex8("127.0.0.1");
response.PutChar(';');
@@ -357,7 +352,8 @@ GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo(
StringExtractor extractor(value);
std::string file;
extractor.GetHexByteString(file);
- match_info.GetProcessInfo().GetExecutableFile().SetFile(file, false);
+ match_info.GetProcessInfo().GetExecutableFile().SetFile(
+ file, false, FileSpec::Style::native);
} else if (key.equals("name_match")) {
NameMatch name_match = llvm::StringSwitch<NameMatch>(value)
.Case("equals", NameMatch::Equals)
@@ -401,7 +397,7 @@ GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo(
match_info.GetProcessInfo().SetEffectiveGroupID(gid);
} else if (key.equals("all_users")) {
match_info.SetMatchAllUsers(
- Args::StringToBoolean(value, false, &success));
+ OptionArgParser::ToBoolean(value, false, &success));
} else if (key.equals("triple")) {
match_info.GetProcessInfo().GetArchitecture() =
HostInfo::GetAugmentedArchSpec(value);
@@ -415,8 +411,8 @@ GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo(
}
if (Host::FindProcesses(match_info, m_proc_infos)) {
- // We found something, return the first item by calling the get
- // subsequent process info packet handler...
+ // We found something, return the first item by calling the get subsequent
+ // process info packet handler...
return Handle_qsProcessInfo(packet);
}
return SendErrorResponse(3);
@@ -731,14 +727,13 @@ GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell(
if (packet.GetChar() == ',') {
// FIXME: add timeout to qPlatform_shell packet
// uint32_t timeout = packet.GetHexMaxU32(false, 32);
- uint32_t timeout = 10;
if (packet.GetChar() == ',')
packet.GetHexByteString(working_dir);
int status, signo;
std::string output;
- Status err =
- Host::RunShellCommand(path.c_str(), FileSpec{working_dir, true},
- &status, &signo, &output, timeout);
+ Status err = Host::RunShellCommand(
+ path.c_str(), FileSpec{working_dir, true}, &status, &signo, &output,
+ std::chrono::seconds(10));
StreamGDBRemote response;
if (err.Fail()) {
response.PutCString("F,");
@@ -945,8 +940,7 @@ GDBRemoteCommunicationServerCommon::Handle_QEnvironment(
packet.SetFilePos(::strlen("QEnvironment:"));
const uint32_t bytes_left = packet.GetBytesLeft();
if (bytes_left > 0) {
- m_process_launch_info.GetEnvironmentEntries().AppendArgument(
- llvm::StringRef::withNullAsEmpty(packet.Peek()));
+ m_process_launch_info.GetEnvironment().insert(packet.Peek());
return SendOKResponse();
}
return SendErrorResponse(12);
@@ -960,7 +954,7 @@ GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded(
if (bytes_left > 0) {
std::string str;
packet.GetHexByteString(str);
- m_process_launch_info.GetEnvironmentEntries().AppendArgument(str);
+ m_process_launch_info.GetEnvironment().insert(str);
return SendOKResponse();
}
return SendErrorResponse(12);
@@ -981,11 +975,11 @@ GDBRemoteCommunicationServerCommon::Handle_QLaunchArch(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) {
- // The 'A' packet is the most over designed packet ever here with
- // redundant argument indexes, redundant argument lengths and needed hex
- // encoded argument string values. Really all that is needed is a comma
- // separated hex encoded argument value list, but we will stay true to the
- // documented version of the 'A' packet here...
+ // The 'A' packet is the most over designed packet ever here with redundant
+ // argument indexes, redundant argument lengths and needed hex encoded
+ // argument string values. Really all that is needed is a comma separated hex
+ // encoded argument value list, but we will stay true to the documented
+ // version of the 'A' packet here...
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
int actual_arg_index = 0;
@@ -993,8 +987,8 @@ GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) {
packet.SetFilePos(1); // Skip the 'A'
bool success = true;
while (success && packet.GetBytesLeft() > 0) {
- // Decode the decimal argument string length. This length is the
- // number of hex nibbles in the argument string value.
+ // Decode the decimal argument string length. This length is the number of
+ // hex nibbles in the argument string value.
const uint32_t arg_len = packet.GetU32(UINT32_MAX);
if (arg_len == UINT32_MAX)
success = false;
@@ -1003,8 +997,8 @@ GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) {
if (packet.GetChar() != ',')
success = false;
else {
- // Decode the argument index. We ignore this really because
- // who would really send down the arguments in a random order???
+ // Decode the argument index. We ignore this really because who would
+ // really send down the arguments in a random order???
const uint32_t arg_idx = packet.GetU32(UINT32_MAX);
if (arg_idx == UINT32_MAX)
success = false;
@@ -1013,9 +1007,9 @@ GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) {
if (packet.GetChar() != ',')
success = false;
else {
- // Decode the argument string value from hex bytes
- // back into a UTF8 string and make sure the length
- // matches the one supplied in the packet
+ // Decode the argument string value from hex bytes back into a UTF8
+ // string and make sure the length matches the one supplied in the
+ // packet
std::string arg;
if (packet.GetHexByteStringFixedLength(arg, arg_len) !=
(arg_len / 2))
@@ -1029,7 +1023,8 @@ GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) {
if (success) {
if (arg_idx == 0)
- m_process_launch_info.GetExecutableFile().SetFile(arg, false);
+ m_process_launch_info.GetExecutableFile().SetFile(
+ arg, false, FileSpec::Style::native);
m_process_launch_info.GetArguments().AppendArgument(arg);
if (log)
log->Printf("LLGSPacketHandler::%s added arg %d: \"%s\"",
@@ -1254,8 +1249,8 @@ void GDBRemoteCommunicationServerCommon::
// Nothing.
break;
}
- // In case of MIPS64, pointer size is depend on ELF ABI
- // For N32 the pointer size is 4 and for N64 it is 8
+ // In case of MIPS64, pointer size is depend on ELF ABI For N32 the pointer
+ // size is 4 and for N64 it is 8
std::string abi = proc_arch.GetTargetABI();
if (!abi.empty())
response.Printf("elf_abi:%s;", abi.c_str());
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 32741c2404e2..50392fa38956 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -33,9 +33,9 @@
#include "lldb/Host/common/NativeProcessProtocol.h"
#include "lldb/Host/common/NativeRegisterContext.h"
#include "lldb/Host/common/NativeThreadProtocol.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Target/FileAction.h"
#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/JSON.h"
@@ -49,7 +49,7 @@
// Project includes
#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
-#include "Utility/StringExtractorGDBRemote.h"
+#include "lldb/Utility/StringExtractorGDBRemote.h"
using namespace lldb;
using namespace lldb_private;
@@ -236,16 +236,15 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() {
m_debugged_process_up = std::move(*process_or);
}
- // Handle mirroring of inferior stdout/stderr over the gdb-remote protocol
- // as needed.
- // llgs local-process debugging may specify PTY paths, which will make these
- // file actions non-null
- // process launch -i/e/o will also make these file actions non-null
- // nullptr means that the traffic is expected to flow over gdb-remote protocol
+ // Handle mirroring of inferior stdout/stderr over the gdb-remote protocol as
+ // needed. llgs local-process debugging may specify PTY paths, which will
+ // make these file actions non-null process launch -i/e/o will also make
+ // these file actions non-null nullptr means that the traffic is expected to
+ // flow over gdb-remote protocol
if (should_forward_stdio) {
// nullptr means it's not redirected to file or pty (in case of LLGS local)
- // at least one of stdio will be transferred pty<->gdb-remote
- // we need to give the pty master handle to this object to read and/or write
+ // at least one of stdio will be transferred pty<->gdb-remote we need to
+ // give the pty master handle to this object to read and/or write
LLDB_LOG(log,
"pid = {0}: setting up stdout/stderr redirection via $O "
"gdb-remote commands",
@@ -291,7 +290,7 @@ Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) {
// else.
if (m_debugged_process_up &&
m_debugged_process_up->GetID() != LLDB_INVALID_PROCESS_ID)
- return Status("cannot attach to a process %" PRIu64
+ return Status("cannot attach to process %" PRIu64
" when another process with pid %" PRIu64
" is being debugged.",
pid, m_debugged_process_up->GetID());
@@ -410,8 +409,8 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) {
JSONObject::SP register_object_sp = std::make_shared<JSONObject>();
#ifdef LLDB_JTHREADSINFO_FULL_REGISTER_SET
- // Expedite all registers in the first register set (i.e. should be GPRs) that
- // are not contained in other registers.
+ // Expedite all registers in the first register set (i.e. should be GPRs)
+ // that are not contained in other registers.
const RegisterSet *reg_set_p = reg_ctx_sp->GetRegisterSet(0);
if (!reg_set_p)
return nullptr;
@@ -420,8 +419,7 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) {
uint32_t reg_num = *reg_num_p;
#else
// Expedite only a couple of registers until we figure out why sending
- // registers is
- // expensive.
+ // registers is expensive.
static const uint32_t k_expedited_registers[] = {
LLDB_REGNUM_GENERIC_PC, LLDB_REGNUM_GENERIC_SP, LLDB_REGNUM_GENERIC_FP,
LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM};
@@ -595,8 +593,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
return SendErrorResponse(52);
// FIXME implement register handling for exec'd inferiors.
- // if (tid_stop_info.reason == eStopReasonExec)
- // {
+ // if (tid_stop_info.reason == eStopReasonExec) {
// const bool force = true;
// InitializeRegisters(force);
// }
@@ -633,14 +630,14 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
response.PutChar(';');
}
- // If a 'QListThreadsInStopReply' was sent to enable this feature, we
- // will send all thread IDs back in the "threads" key whose value is
- // a list of hex thread IDs separated by commas:
+ // If a 'QListThreadsInStopReply' was sent to enable this feature, we will
+ // send all thread IDs back in the "threads" key whose value is a list of hex
+ // thread IDs separated by commas:
// "threads:10a,10b,10c;"
- // This will save the debugger from having to send a pair of qfThreadInfo
- // and qsThreadInfo packets, but it also might take a lot of room in the
- // stop reply packet, so it must be enabled only on systems where there
- // are no limits on packet lengths.
+ // This will save the debugger from having to send a pair of qfThreadInfo and
+ // qsThreadInfo packets, but it also might take a lot of room in the stop
+ // reply packet, so it must be enabled only on systems where there are no
+ // limits on packet lengths.
if (m_list_threads_in_stop_reply) {
response.PutCString("threads:");
@@ -655,12 +652,11 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
}
response.PutChar(';');
- // Include JSON info that describes the stop reason for any threads
- // that actually have stop reasons. We use the new "jstopinfo" key
- // whose values is hex ascii JSON that contains the thread IDs
- // thread stop info only for threads that have stop reasons. Only send
- // this if we have more than one thread otherwise this packet has all
- // the info it needs.
+ // Include JSON info that describes the stop reason for any threads that
+ // actually have stop reasons. We use the new "jstopinfo" key whose values
+ // is hex ascii JSON that contains the thread IDs thread stop info only for
+ // threads that have stop reasons. Only send this if we have more than one
+ // thread otherwise this packet has all the info it needs.
if (thread_index > 0) {
const bool threads_with_valid_stop_info_only = true;
JSONArray::SP threads_info_sp = GetJSONThreadsInfo(
@@ -806,8 +802,8 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited(
__FUNCTION__, process->GetID());
}
- // Close the pipe to the inferior terminal i/o if we launched it
- // and set one up.
+ // Close the pipe to the inferior terminal i/o if we launched it and set one
+ // up.
MaybeCloseInferiorTerminalConnection();
// We are ready to exit the debug monitor.
@@ -823,8 +819,7 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped(
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
- // Send the stop reason unless this is the stop after the
- // launch or attach.
+ // Send the stop reason unless this is the stop after the launch or attach.
switch (m_inferior_prev_state) {
case eStateLaunching:
case eStateAttaching:
@@ -859,13 +854,11 @@ void GDBRemoteCommunicationServerLLGS::ProcessStateChanged(
break;
case StateType::eStateStopped:
- // Make sure we get all of the pending stdout/stderr from the inferior
- // and send it to the lldb host before we send the state change
- // notification
+ // Make sure we get all of the pending stdout/stderr from the inferior and
+ // send it to the lldb host before we send the state change notification
SendProcessOutput();
// Then stop the forwarding, so that any late output (see llvm.org/pr25652)
- // does not
- // interfere with our protocol.
+ // does not interfere with our protocol.
StopSTDIOForwarding();
HandleInferiorState_Stopped(process);
break;
@@ -1287,8 +1280,8 @@ GDBRemoteCommunicationServerLLGS::Handle_qC(StringExtractorGDBRemote &packet) {
(m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
return SendErrorResponse(68);
- // Make sure we set the current thread so g and p packets return
- // the data the gdb will expect.
+ // Make sure we set the current thread so g and p packets return the data the
+ // gdb will expect.
lldb::tid_t tid = m_debugged_process_up->GetCurrentThreadID();
SetCurrentThreadID(tid);
@@ -1397,10 +1390,9 @@ GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) {
Status error;
// We have two branches: what to do if a continue thread is specified (in
- // which case we target
- // sending the signal to that thread), or when we don't have a continue thread
- // set (in which
- // case we send a signal to the process).
+ // which case we target sending the signal to that thread), or when we don't
+ // have a continue thread set (in which case we send a signal to the
+ // process).
// TODO discuss with Greg Clayton, make sure this makes sense.
@@ -1639,8 +1631,8 @@ GDBRemoteCommunicationServerLLGS::SendStopReasonForState(
case eStateStopped:
case eStateCrashed: {
lldb::tid_t tid = m_debugged_process_up->GetCurrentThreadID();
- // Make sure we set the current thread so g and p packets return
- // the data the gdb will expect.
+ // Make sure we set the current thread so g and p packets return the data
+ // the gdb will expect.
SetCurrentThreadID(tid);
return SendStopReplyPacketForThread(tid);
}
@@ -2043,9 +2035,8 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
return SendErrorResponse(0x47);
}
- // The dwarf expression are evaluate on host site
- // which may cause register size to change
- // Hence the reg_size may not be same as reg_info->bytes_size
+ // The dwarf expression are evaluate on host site which may cause register
+ // size to change Hence the reg_size may not be same as reg_info->bytes_size
if ((reg_size != reg_info->byte_size) &&
!(reg_info->dynamic_size_dwarf_expr_bytes)) {
return SendIllFormedResponse(packet, "P packet register size is incorrect");
@@ -2376,10 +2367,9 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported(
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
// Currently only the NativeProcessProtocol knows if it can handle a
- // qMemoryRegionInfoSupported
- // request, but we're not guaranteed to be attached to a process. For now
- // we'll assume the
- // client only asks this when a process is being debugged.
+ // qMemoryRegionInfoSupported request, but we're not guaranteed to be
+ // attached to a process. For now we'll assume the client only asks this
+ // when a process is being debugged.
// Ensure we have a process running; otherwise, we can't figure this out
// since we won't have a NativeProcessProtocol.
@@ -2670,8 +2660,7 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) {
}
// We first try to use a continue thread id. If any one or any all set, use
- // the current thread.
- // Bail out if we don't have a thread id.
+ // the current thread. Bail out if we don't have a thread id.
lldb::tid_t tid = GetContinueThreadID();
if (tid == 0 || tid == LLDB_INVALID_THREAD_ID)
tid = GetCurrentThreadID();
@@ -2935,7 +2924,7 @@ GDBRemoteCommunicationServerLLGS::Handle_vAttach(
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to attach to "
"pid %" PRIu64 ": %s\n",
__FUNCTION__, pid, error.AsCString());
- return SendErrorResponse(0x01);
+ return SendErrorResponse(error);
}
// Notify we attached by sending a stop packet.
@@ -3093,8 +3082,8 @@ GDBRemoteCommunicationServerLLGS::Handle_QPassSignals(
std::vector<int> signals;
packet.SetFilePos(strlen("QPassSignals:"));
- // Read sequence of hex signal numbers divided by a semicolon and
- // optionally spaces.
+ // Read sequence of hex signal numbers divided by a semicolon and optionally
+ // spaces.
while (packet.GetBytesLeft() > 0) {
int signal = packet.GetS32(-1, 16);
if (signal < 0)
@@ -3154,8 +3143,7 @@ NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
return nullptr;
// If the client hasn't asked for thread suffix support, there will not be a
- // thread suffix.
- // Use the current thread in that case.
+ // thread suffix. Use the current thread in that case.
if (!m_thread_suffix_supported) {
const lldb::tid_t current_tid = GetCurrentThreadID();
if (current_tid == LLDB_INVALID_THREAD_ID)
@@ -3201,9 +3189,9 @@ NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
lldb::tid_t GDBRemoteCommunicationServerLLGS::GetCurrentThreadID() const {
if (m_current_tid == 0 || m_current_tid == LLDB_INVALID_THREAD_ID) {
- // Use whatever the debug process says is the current thread id
- // since the protocol either didn't specify or specified we want
- // any/all threads marked as the current thread.
+ // Use whatever the debug process says is the current thread id since the
+ // protocol either didn't specify or specified we want any/all threads
+ // marked as the current thread.
if (!m_debugged_process_up)
return LLDB_INVALID_THREAD_ID;
return m_debugged_process_up->GetCurrentThreadID();
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
index 04ed9d704e13..26e28a900320 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
@@ -14,6 +14,7 @@
// C Includes
// C++ Includes
#include <chrono>
+#include <csignal>
#include <cstring>
#include <mutex>
#include <sstream>
@@ -38,7 +39,7 @@
#include "lldb/Utility/UriParser.h"
// Project includes
-#include "Utility/StringExtractorGDBRemote.h"
+#include "lldb/Utility/StringExtractorGDBRemote.h"
using namespace lldb;
using namespace lldb_private;
@@ -101,11 +102,11 @@ Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
if (port == UINT16_MAX)
port = GetNextAvailablePort();
- // Spawn a new thread to accept the port that gets bound after
- // binding to port 0 (zero).
+ // Spawn a new thread to accept the port that gets bound after binding to
+ // port 0 (zero).
- // ignore the hostname send from the remote end, just use the ip address
- // that we're currently communicating with as the hostname
+ // ignore the hostname send from the remote end, just use the ip address that
+ // we're currently communicating with as the hostname
// Spawn a debugserver and try to get the port it listens to.
ProcessLaunchInfo debugserver_launch_info;
@@ -116,8 +117,8 @@ Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
if (log)
log->Printf("Launching debugserver with: %s:%u...", hostname.c_str(), port);
- // Do not run in a new session so that it can not linger after the
- // platform closes.
+ // Do not run in a new session so that it can not linger after the platform
+ // closes.
debugserver_launch_info.SetLaunchInSeparateProcessGroup(false);
debugserver_launch_info.SetMonitorProcessCallback(
std::bind(&GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped,
@@ -170,8 +171,8 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
#ifdef _WIN32
return SendErrorResponse(9);
#else
- // Spawn a local debugserver as a platform so we can then attach or launch
- // a process...
+ // Spawn a local debugserver as a platform so we can then attach or launch a
+ // process...
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
if (log)
@@ -259,8 +260,7 @@ GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess(
lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID);
- // verify that we know anything about this pid.
- // Scope for locker
+ // verify that we know anything about this pid. Scope for locker
{
std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
@@ -306,8 +306,8 @@ bool GDBRemoteCommunicationServerPlatform::KillSpawnedProcess(lldb::pid_t pid) {
return true;
}
- // the launched process still lives. Now try killing it again,
- // this time with an unblockable signal.
+ // the launched process still lives. Now try killing it again, this time
+ // with an unblockable signal.
Host::Kill(pid, SIGKILL);
for (size_t i = 0; i < 10; ++i) {
@@ -321,8 +321,7 @@ bool GDBRemoteCommunicationServerPlatform::KillSpawnedProcess(lldb::pid_t pid) {
usleep(10000);
}
- // check one more time after the final usleep
- // Scope for locker
+ // check one more time after the final usleep Scope for locker
{
std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
if (m_spawned_pids.find(pid) == m_spawned_pids.end())
@@ -389,14 +388,13 @@ GDBRemoteCommunicationServerPlatform::Handle_qC(
StreamString response;
response.Printf("QC%" PRIx64, pid);
- // If we launch a process and this GDB server is acting as a platform,
- // then we need to clear the process launch state so we can start
- // launching another process. In order to launch a process a bunch or
- // packets need to be sent: environment packets, working directory,
- // disable ASLR, and many more settings. When we launch a process we
- // then need to know when to clear this information. Currently we are
- // selecting the 'qC' packet as that packet which seems to make the most
- // sense.
+ // If we launch a process and this GDB server is acting as a platform, then
+ // we need to clear the process launch state so we can start launching
+ // another process. In order to launch a process a bunch or packets need to
+ // be sent: environment packets, working directory, disable ASLR, and many
+ // more settings. When we launch a process we then need to know when to clear
+ // this information. Currently we are selecting the 'qC' packet as that
+ // packet which seems to make the most sense.
if (pid != LLDB_INVALID_PROCESS_ID) {
m_process_launch_info.Clear();
}
@@ -445,9 +443,8 @@ Status GDBRemoteCommunicationServerPlatform::LaunchProcess() {
return Status("%s: no process command line specified to launch",
__FUNCTION__);
- // specify the process monitor if not already set. This should
- // generally be what happens since we need to reap started
- // processes.
+ // specify the process monitor if not already set. This should generally be
+ // what happens since we need to reap started processes.
if (!m_process_launch_info.GetMonitorProcessCallback())
m_process_launch_info.SetMonitorProcessCallback(
std::bind(
@@ -466,8 +463,8 @@ Status GDBRemoteCommunicationServerPlatform::LaunchProcess() {
m_process_launch_info.GetArguments().GetArgumentAtIndex(0),
m_process_launch_info.GetProcessID());
- // add to list of spawned processes. On an lldb-gdbserver, we
- // would expect there to be only one.
+ // add to list of spawned processes. On an lldb-gdbserver, we would expect
+ // there to be only one.
const auto pid = m_process_launch_info.GetProcessID();
if (pid != LLDB_INVALID_PROCESS_ID) {
// add to spawned pids
@@ -537,7 +534,7 @@ const FileSpec &GDBRemoteCommunicationServerPlatform::GetDomainSocketDir() {
if (domainsocket_dir_env != nullptr)
g_domainsocket_dir = FileSpec(domainsocket_dir_env, false);
else
- HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, g_domainsocket_dir);
+ g_domainsocket_dir = HostInfo::GetProcessTempDir();
});
return g_domainsocket_dir;
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
index e418deee01f3..07dab751f4b9 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -25,7 +25,7 @@
#include "ThreadGDBRemote.h"
#include "Utility/ARM_DWARF_Registers.h"
#include "Utility/ARM_ehframe_Registers.h"
-#include "Utility/StringExtractorGDBRemote.h"
+#include "lldb/Utility/StringExtractorGDBRemote.h"
using namespace lldb;
using namespace lldb_private;
@@ -39,9 +39,9 @@ GDBRemoteRegisterContext::GDBRemoteRegisterContext(
GDBRemoteDynamicRegisterInfo &reg_info, bool read_all_at_once)
: RegisterContext(thread, concrete_frame_idx), m_reg_info(reg_info),
m_reg_valid(), m_reg_data(), m_read_all_at_once(read_all_at_once) {
- // Resize our vector of bools to contain one bool for every register.
- // We will use these boolean values to know when a register value
- // is valid in m_reg_data.
+ // Resize our vector of bools to contain one bool for every register. We will
+ // use these boolean values to know when a register value is valid in
+ // m_reg_data.
m_reg_valid.resize(reg_info.GetNumRegisters());
// Make a heap based buffer that is big enough to store all registers
@@ -119,8 +119,8 @@ bool GDBRemoteRegisterContext::PrivateSetRegisterValue(
if (success) {
SetRegisterIsValid(reg, true);
} else if (data.size() > 0) {
- // Only set register is valid to false if we copied some bytes, else
- // leave it as it was.
+ // Only set register is valid to false if we copied some bytes, else leave
+ // it as it was.
SetRegisterIsValid(reg, false);
}
return success;
@@ -133,11 +133,9 @@ bool GDBRemoteRegisterContext::PrivateSetRegisterValue(uint32_t reg,
return false;
// Early in process startup, we can get a thread that has an invalid byte
- // order
- // because the process hasn't been completely set up yet (see the ctor where
- // the
- // byte order is setfrom the process). If that's the case, we can't set the
- // value here.
+ // order because the process hasn't been completely set up yet (see the ctor
+ // where the byte order is setfrom the process). If that's the case, we
+ // can't set the value here.
if (m_reg_data.GetByteOrder() == eByteOrderInvalid) {
return false;
}
@@ -149,8 +147,7 @@ bool GDBRemoteRegisterContext::PrivateSetRegisterValue(uint32_t reg,
DataExtractor data(buffer_sp, endian::InlHostByteOrder(), sizeof(void *));
// If our register context and our register info disagree, which should never
- // happen, don't
- // overwrite past the end of the buffer.
+ // happen, don't overwrite past the end of the buffer.
if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
return false;
@@ -219,8 +216,7 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info,
}
if (reg_info->value_regs) {
// Process this composite register request by delegating to the
- // constituent
- // primordial registers.
+ // constituent primordial registers.
// Index of the primordial register.
bool success = true;
@@ -228,8 +224,8 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info,
const uint32_t prim_reg = reg_info->value_regs[idx];
if (prim_reg == LLDB_INVALID_REGNUM)
break;
- // We have a valid primordial register as our constituent.
- // Grab the corresponding register info.
+ // We have a valid primordial register as our constituent. Grab the
+ // corresponding register info.
const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg);
if (prim_reg_info == NULL)
success = false;
@@ -242,8 +238,7 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info,
if (success) {
// If we reach this point, all primordial register requests have
- // succeeded.
- // Validate this composite register.
+ // succeeded. Validate this composite register.
SetRegisterIsValid(reg_info, true);
}
} else {
@@ -262,16 +257,14 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info,
reg_info->byte_offset + reg_info->byte_size);
#endif
// If our register context and our register info disagree, which should
- // never happen, don't
- // read past the end of the buffer.
+ // never happen, don't read past the end of the buffer.
if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
return false;
- // If we aren't extracting into our own buffer (which
- // only happens when this function is called from
- // ReadRegisterValue(uint32_t, Scalar&)) then
- // we transfer bytes from our buffer into the data
- // buffer that was passed in
+ // If we aren't extracting into our own buffer (which only happens when
+ // this function is called from ReadRegisterValue(uint32_t, Scalar&)) then
+ // we transfer bytes from our buffer into the data buffer that was passed
+ // in
data.SetByteOrder(m_reg_data.GetByteOrder());
data.SetData(m_reg_data, reg_info->byte_offset, reg_info->byte_size);
@@ -321,8 +314,7 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
#endif
// If our register context and our register info disagree, which should never
- // happen, don't
- // overwrite past the end of the buffer.
+ // happen, don't overwrite past the end of the buffer.
if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
return false;
@@ -358,12 +350,10 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
bool success = true;
if (reg_info->value_regs) {
- // This register is part of another register. In this case we read the
- // actual
- // register data for any "value_regs", and once all that data is read,
- // we will
- // have enough data in our register context bytes for the value of
- // this register
+ // This register is part of another register. In this case we read
+ // the actual register data for any "value_regs", and once all that
+ // data is read, we will have enough data in our register context
+ // bytes for the value of this register
// Invalidate this composite register first.
@@ -371,8 +361,8 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
const uint32_t reg = reg_info->value_regs[idx];
if (reg == LLDB_INVALID_REGNUM)
break;
- // We have a valid primordial register as our constituent.
- // Grab the corresponding register info.
+ // We have a valid primordial register as our constituent. Grab the
+ // corresponding register info.
const RegisterInfo *value_reg_info = GetRegisterInfoAtIndex(reg);
if (value_reg_info == NULL)
success = false;
@@ -385,8 +375,7 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
}
// Check if writing this register will invalidate any other register
- // values?
- // If so, invalidate them
+ // values? If so, invalidate them
if (reg_info->invalidate_regs) {
for (uint32_t idx = 0, reg = reg_info->invalidate_regs[0];
reg != LLDB_INVALID_REGNUM;
@@ -548,26 +537,22 @@ bool GDBRemoteRegisterContext::WriteAllRegisterValues(
return true;
uint32_t num_restored = 0;
- // We need to manually go through all of the registers and
- // restore them manually
+ // We need to manually go through all of the registers and restore them
+ // manually
DataExtractor restore_data(data_sp, m_reg_data.GetByteOrder(),
m_reg_data.GetAddressByteSize());
const RegisterInfo *reg_info;
- // The g packet contents may either include the slice registers (registers
- // defined in
- // terms of other registers, e.g. eax is a subset of rax) or not. The
- // slice registers
- // should NOT be in the g packet, but some implementations may incorrectly
- // include them.
+ // The g packet contents may either include the slice registers
+ // (registers defined in terms of other registers, e.g. eax is a subset
+ // of rax) or not. The slice registers should NOT be in the g packet,
+ // but some implementations may incorrectly include them.
//
// If the slice registers are included in the packet, we must step over
- // the slice registers
- // when parsing the packet -- relying on the RegisterInfo byte_offset
- // field would be incorrect.
- // If the slice registers are not included, then using the byte_offset
- // values into the
+ // the slice registers when parsing the packet -- relying on the
+ // RegisterInfo byte_offset field would be incorrect. If the slice
+ // registers are not included, then using the byte_offset values into the
// data buffer is the best way to find individual register values.
uint64_t size_including_slice_registers = 0;
@@ -591,21 +576,17 @@ bool GDBRemoteRegisterContext::WriteAllRegisterValues(
} else if (size_not_including_slice_registers ==
restore_data.GetByteSize()) {
// The size of the packet is the same as concatenating all of the
- // registers sequentially,
- // skipping the slice registers
+ // registers sequentially, skipping the slice registers
use_byte_offset_into_buffer = true;
} else if (size_including_slice_registers == restore_data.GetByteSize()) {
// The slice registers are present in the packet (when they shouldn't
- // be).
- // Don't try to use the RegisterInfo byte_offset into the restore_data,
- // it will
- // point to the wrong place.
+ // be). Don't try to use the RegisterInfo byte_offset into the
+ // restore_data, it will point to the wrong place.
use_byte_offset_into_buffer = false;
} else {
// None of our expected sizes match the actual g packet data we're
- // looking at.
- // The most conservative approach here is to use the running total byte
- // offset.
+ // looking at. The most conservative approach here is to use the
+ // running total byte offset.
use_byte_offset_into_buffer = false;
}
@@ -664,11 +645,9 @@ bool GDBRemoteRegisterContext::WriteAllRegisterValues(
if (reg_info->value_regs) // skip registers that are slices of real
// registers
continue;
- // Skip the fpsr and fpcr floating point status/control register writing
- // to
- // work around a bug in an older version of debugserver that would lead
- // to
- // register context corruption when writing fpsr/fpcr.
+ // Skip the fpsr and fpcr floating point status/control register
+ // writing to work around a bug in an older version of debugserver that
+ // would lead to register context corruption when writing fpsr/fpcr.
if (arm64_debugserver && (strcmp(reg_info->name, "fpsr") == 0 ||
strcmp(reg_info->name, "fpcr") == 0)) {
continue;
@@ -752,8 +731,8 @@ void GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters(bool from_scratch) {
static uint32_t g_q14_regs[] = {71, 72, LLDB_INVALID_REGNUM}; // (d28, d29)
static uint32_t g_q15_regs[] = {73, 74, LLDB_INVALID_REGNUM}; // (d30, d31)
- // This is our array of composite registers, with each element coming from the
- // above register mappings.
+ // This is our array of composite registers, with each element coming from
+ // the above register mappings.
static uint32_t *g_composites[] = {
g_d0_regs, g_d1_regs, g_d2_regs, g_d3_regs, g_d4_regs, g_d5_regs,
g_d6_regs, g_d7_regs, g_d8_regs, g_d9_regs, g_d10_regs, g_d11_regs,
@@ -884,21 +863,17 @@ void GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters(bool from_scratch) {
if (from_scratch) {
// Calculate the offsets of the registers
// Note that the layout of the "composite" registers (d0-d15 and q0-q15)
- // which comes after the
- // "primordial" registers is important. This enables us to calculate the
- // offset of the composite
- // register by using the offset of its first primordial register. For
- // example, to calculate the
- // offset of q0, use s0's offset.
+ // which comes after the "primordial" registers is important. This enables
+ // us to calculate the offset of the composite register by using the offset
+ // of its first primordial register. For example, to calculate the offset
+ // of q0, use s0's offset.
if (g_register_infos[2].byte_offset == 0) {
uint32_t byte_offset = 0;
for (i = 0; i < num_registers; ++i) {
// For primordial registers, increment the byte_offset by the byte_size
- // to arrive at the
- // byte_offset for the next register. Otherwise, we have a composite
- // register whose
- // offset can be calculated by consulting the offset of its first
- // primordial register.
+ // to arrive at the byte_offset for the next register. Otherwise, we
+ // have a composite register whose offset can be calculated by
+ // consulting the offset of its first primordial register.
if (!g_register_infos[i].value_regs) {
g_register_infos[i].byte_offset = byte_offset;
byte_offset += g_register_infos[i].byte_size;
@@ -933,8 +908,8 @@ void GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters(bool from_scratch) {
RegisterInfo *g_comp_register_infos = g_register_infos + num_common_regs;
// First we need to validate that all registers that we already have match
- // the non composite regs.
- // If so, then we can add the registers, else we need to bail
+ // the non composite regs. If so, then we can add the registers, else we
+ // need to bail
bool match = true;
if (num_dynamic_regs == num_common_regs) {
for (i = 0; match && i < num_dynamic_regs; ++i) {
@@ -970,9 +945,8 @@ void GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters(bool from_scratch) {
// Find a matching primordial register info entry.
if (reg_info && reg_info->name &&
::strcasecmp(reg_info->name, reg_name) == 0) {
- // The name matches the existing primordial entry.
- // Find and assign the offset, and then add this composite
- // register entry.
+ // The name matches the existing primordial entry. Find and
+ // assign the offset, and then add this composite register entry.
g_comp_register_infos[i].byte_offset = reg_info->byte_offset;
name.SetCString(g_comp_register_infos[i].name);
AddRegister(g_comp_register_infos[i], name, alt_name,
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 35d02c15ab85..b3d33b19bd66 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -24,6 +24,7 @@
// C++ Includes
#include <algorithm>
+#include <csignal>
#include <map>
#include <mutex>
#include <sstream>
@@ -46,11 +47,11 @@
#include "lldb/Host/Symbols.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Host/XML.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionGroupBoolean.h"
#include "lldb/Interpreter/OptionGroupUInt64.h"
#include "lldb/Interpreter/OptionValueProperties.h"
@@ -59,10 +60,12 @@
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/DynamicLoader.h"
+#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/SystemRuntime.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/TargetList.h"
#include "lldb/Target/ThreadPlanCallFunction.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/StreamString.h"
@@ -77,8 +80,8 @@
#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
#include "ThreadGDBRemote.h"
-#include "Utility/StringExtractorGDBRemote.h"
#include "lldb/Host/Host.h"
+#include "lldb/Utility/StringExtractorGDBRemote.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/Threading.h"
@@ -91,11 +94,11 @@ using namespace lldb_private::process_gdb_remote;
namespace lldb {
// Provide a function that can easily dump the packet history if we know a
-// ProcessGDBRemote * value (which we can get from logs or from debugging).
-// We need the function in the lldb namespace so it makes it into the final
+// ProcessGDBRemote * value (which we can get from logs or from debugging). We
+// need the function in the lldb namespace so it makes it into the final
// executable since the LLDB shared library only exports stuff in the lldb
-// namespace. This allows you to attach with a debugger and call this
-// function and get the packet history dumped to a file.
+// namespace. This allows you to attach with a debugger and call this function
+// and get the packet history dumped to a file.
void DumpProcessGDBRemotePacketHistory(void *p, const char *path) {
StreamFile strm;
Status error(strm.GetFile().Open(path, File::eOpenOptionWrite |
@@ -158,8 +161,8 @@ static const ProcessKDPPropertiesSP &GetGlobalPluginProperties() {
} // anonymous namespace end
// TODO Randomly assigning a port is unsafe. We should get an unused
-// ephemeral port from the kernel and make sure we reserve it before passing
-// it to debugserver.
+// ephemeral port from the kernel and make sure we reserve it before passing it
+// to debugserver.
#if defined(__APPLE__)
#define LOW_PORT (IPPORT_RESERVED)
@@ -233,8 +236,8 @@ bool ProcessGDBRemote::CanDebug(lldb::TargetSP target_sp,
}
return exe_module->GetFileSpec().Exists();
}
- // However, if there is no executable module, we return true since we might be
- // preparing to attach.
+ // However, if there is no executable module, we return true since we might
+ // be preparing to attach.
return true;
}
@@ -256,7 +259,8 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
m_addr_to_mmap_size(), m_thread_create_bp_sp(),
m_waiting_for_attach(false), m_destroy_tried_resuming(false),
m_command_sp(), m_breakpoint_pc_offset(0),
- m_initial_tid(LLDB_INVALID_THREAD_ID) {
+ m_initial_tid(LLDB_INVALID_THREAD_ID), m_allow_flash_writes(false),
+ m_erased_flash_ranges() {
m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit,
"async thread should exit");
m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue,
@@ -299,17 +303,16 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
ProcessGDBRemote::~ProcessGDBRemote() {
// m_mach_process.UnregisterNotificationCallbacks (this);
Clear();
- // We need to call finalize on the process before destroying ourselves
- // to make sure all of the broadcaster cleanup goes as planned. If we
- // destruct this class, then Process::~Process() might have problems
- // trying to fully destroy the broadcaster.
+ // We need to call finalize on the process before destroying ourselves to
+ // make sure all of the broadcaster cleanup goes as planned. If we destruct
+ // this class, then Process::~Process() might have problems trying to fully
+ // destroy the broadcaster.
Finalize();
- // The general Finalize is going to try to destroy the process and that SHOULD
- // shut down the async thread. However, if we don't kill it it will get
- // stranded and
- // its connection will go away so when it wakes up it will crash. So kill it
- // for sure here.
+ // The general Finalize is going to try to destroy the process and that
+ // SHOULD shut down the async thread. However, if we don't kill it it will
+ // get stranded and its connection will go away so when it wakes up it will
+ // crash. So kill it for sure here.
StopAsyncThread();
KillDebugserverProcess();
}
@@ -368,8 +371,7 @@ bool ProcessGDBRemote::ParsePythonTargetDefinition(
}
// If the remote stub didn't give us eh_frame or DWARF register numbers for a
-// register,
-// see if the ABI can provide them.
+// register, see if the ABI can provide them.
// DWARF and eh_frame register numbers are defined as a part of the ABI.
static void AugmentRegisterInfoViaABI(RegisterInfo &reg_info,
ConstString reg_name, ABISP abi_sp) {
@@ -422,9 +424,9 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
m_register_info.Clear();
- // Check if qHostInfo specified a specific packet timeout for this connection.
- // If so then lets update our setting so the user knows what the timeout is
- // and can see it.
+ // Check if qHostInfo specified a specific packet timeout for this
+ // connection. If so then lets update our setting so the user knows what the
+ // timeout is and can see it.
const auto host_packet_timeout = m_gdb_comm.GetHostDefaultPacketTimeout();
if (host_packet_timeout > std::chrono::seconds(0)) {
GetGlobalPluginProperties()->SetPacketTimeout(host_packet_timeout.count());
@@ -531,7 +533,7 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
reg_info.encoding = encoding;
} else if (name.equals("format")) {
Format format = eFormatInvalid;
- if (Args::StringToFormat(value.str().c_str(), format, NULL)
+ if (OptionArgParser::ToFormat(value.str().c_str(), format, NULL)
.Success())
reg_info.format = format;
else {
@@ -596,10 +598,8 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
}
// We have to make a temporary ABI here, and not use the GetABI because
- // this code
- // gets called in DidAttach, when the target architecture (and
- // consequently the ABI we'll get from
- // the process) may be wrong.
+ // this code gets called in DidAttach, when the target architecture
+ // (and consequently the ABI we'll get from the process) may be wrong.
ABISP abi_to_use = ABI::FindPlugin(shared_from_this(), arch_to_use);
AugmentRegisterInfoViaABI(reg_info, reg_name, abi_to_use);
@@ -620,9 +620,9 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
// We didn't get anything if the accumulated reg_num is zero. See if we are
// debugging ARM and fill with a hard coded register set until we can get an
- // updated debugserver down on the devices.
- // On the other hand, if the accumulated reg_num is positive, see if we can
- // add composite registers to the existing primordial ones.
+ // updated debugserver down on the devices. On the other hand, if the
+ // accumulated reg_num is positive, see if we can add composite registers to
+ // the existing primordial ones.
bool from_scratch = (m_register_info.GetNumRegisters() == 0);
if (!target_arch.IsValid()) {
@@ -669,9 +669,8 @@ Status ProcessGDBRemote::DoConnectRemote(Stream *strm,
lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();
if (pid == LLDB_INVALID_PROCESS_ID) {
- // We don't have a valid process ID, so note that we are connected
- // and could now request to launch or attach, or get remote process
- // listings...
+ // We don't have a valid process ID, so note that we are connected and
+ // could now request to launch or attach, or get remote process listings...
SetPrivateState(eStateConnected);
} else {
// We have a valid process
@@ -721,7 +720,8 @@ Status ProcessGDBRemote::DoConnectRemote(Stream *strm,
if (error.Success() && !GetTarget().GetArchitecture().IsValid() &&
m_gdb_comm.GetHostArchitecture().IsValid()) {
- // Prefer the *process'* architecture over that of the *host*, if available.
+ // Prefer the *process'* architecture over that of the *host*, if
+ // available.
if (m_gdb_comm.GetProcessArchitecture().IsValid())
GetTarget().SetArchitecture(m_gdb_comm.GetProcessArchitecture());
else
@@ -800,8 +800,8 @@ Status ProcessGDBRemote::DoLaunch(Module *exe_module,
const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
if (stdin_file_spec || disable_stdio) {
- // the inferior will be reading stdin from the specified file
- // or stdio is completely disabled
+ // the inferior will be reading stdin from the specified file or stdio is
+ // completely disabled
m_stdin_forward = false;
} else {
m_stdin_forward = true;
@@ -824,11 +824,14 @@ Status ProcessGDBRemote::DoLaunch(Module *exe_module,
if (disable_stdio) {
// set to /dev/null unless redirected to a file above
if (!stdin_file_spec)
- stdin_file_spec.SetFile(FileSystem::DEV_NULL, false);
+ stdin_file_spec.SetFile(FileSystem::DEV_NULL, false,
+ FileSpec::Style::native);
if (!stdout_file_spec)
- stdout_file_spec.SetFile(FileSystem::DEV_NULL, false);
+ stdout_file_spec.SetFile(FileSystem::DEV_NULL, false,
+ FileSpec::Style::native);
if (!stderr_file_spec)
- stderr_file_spec.SetFile(FileSystem::DEV_NULL, false);
+ stderr_file_spec.SetFile(FileSystem::DEV_NULL, false,
+ FileSpec::Style::native);
} else if (platform_sp && platform_sp->IsHost()) {
// If the debugserver is local and we aren't disabling STDIO, lets use
// a pseudo terminal to instead of relying on the 'O' packets for stdio
@@ -888,16 +891,7 @@ Status ProcessGDBRemote::DoLaunch(Module *exe_module,
}
// Send the environment and the program + arguments after we connect
- const Args &environment = launch_info.GetEnvironmentEntries();
- if (environment.GetArgumentCount()) {
- size_t num_environment_entries = environment.GetArgumentCount();
- for (size_t i = 0; i < num_environment_entries; ++i) {
- const char *env_entry = environment.GetArgumentAtIndex(i);
- if (env_entry == NULL ||
- m_gdb_comm.SendEnvironmentPacket(env_entry) != 0)
- break;
- }
- }
+ m_gdb_comm.SendEnvironment(launch_info.GetEnvironment());
{
// Scope for the scoped timeout object
@@ -1004,16 +998,15 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) {
return error;
}
- // Start the communications read thread so all incoming data can be
- // parsed into packets and queued as they arrive.
+ // Start the communications read thread so all incoming data can be parsed
+ // into packets and queued as they arrive.
if (GetTarget().GetNonStopModeEnabled())
m_gdb_comm.StartReadThread();
- // We always seem to be able to open a connection to a local port
- // so we need to make sure we can then send data to it. If we can't
- // then we aren't actually connected to anything, so try and do the
- // handshake with the remote GDB server and make sure that goes
- // alright.
+ // We always seem to be able to open a connection to a local port so we need
+ // to make sure we can then send data to it. If we can't then we aren't
+ // actually connected to anything, so try and do the handshake with the
+ // remote GDB server and make sure that goes alright.
if (!m_gdb_comm.HandshakeWithServer(&error)) {
m_gdb_comm.Disconnect();
if (error.Success())
@@ -1055,9 +1048,9 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
// See if the GDB server supports the qHostInfo information
- // See if the GDB server supports the qProcessInfo packet, if so
- // prefer that over the Host information as it will be more specific
- // to our process.
+ // See if the GDB server supports the qProcessInfo packet, if so prefer
+ // that over the Host information as it will be more specific to our
+ // process.
const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();
if (remote_process_arch.IsValid()) {
@@ -1102,9 +1095,8 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
// architectures.
// You can have an armv6 executable, and if the host is armv7, then the
// system will load the best possible architecture for all shared
- // libraries
- // it has, so we really need to take the remote host architecture as our
- // defacto architecture in this case.
+ // libraries it has, so we really need to take the remote host
+ // architecture as our defacto architecture in this case.
if ((process_arch.GetMachine() == llvm::Triple::arm ||
process_arch.GetMachine() == llvm::Triple::thumb) &&
@@ -1150,14 +1142,14 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
? target_arch.GetTriple().getTriple().c_str()
: "<null>");
} else {
- // The target doesn't have a valid architecture yet, set it from
- // the architecture we got from the remote GDB server
+ // The target doesn't have a valid architecture yet, set it from the
+ // architecture we got from the remote GDB server
GetTarget().SetArchitecture(process_arch);
}
}
- // Find out which StructuredDataPlugins are supported by the
- // debug monitor. These plugins transmit data over async $J packets.
+ // Find out which StructuredDataPlugins are supported by the debug monitor.
+ // These plugins transmit data over async $J packets.
auto supported_packets_array =
m_gdb_comm.GetSupportedStructuredDataPlugins();
if (supported_packets_array)
@@ -1365,9 +1357,9 @@ Status ProcessGDBRemote::DoResume() {
continue_packet_error = true;
if (continue_packet_error) {
- // Either no vCont support, or we tried to use part of the vCont
- // packet that wasn't supported by the remote GDB server.
- // We need to try and make a simple packet that can do our continue
+ // Either no vCont support, or we tried to use part of the vCont packet
+ // that wasn't supported by the remote GDB server. We need to try and
+ // make a simple packet that can do our continue
const size_t num_continue_c_tids = m_continue_c_tids.size();
const size_t num_continue_C_tids = m_continue_C_tids.size();
const size_t num_continue_s_tids = m_continue_s_tids.size();
@@ -1394,11 +1386,10 @@ Status ProcessGDBRemote::DoResume() {
const int continue_signo = m_continue_C_tids.front().second;
// Only one thread is continuing
if (num_continue_C_tids > 1) {
- // More that one thread with a signal, yet we don't have
- // vCont support and we are being asked to resume each
- // thread with a signal, we need to make sure they are
- // all the same signal, or we can't issue the continue
- // accurately with the current support...
+ // More that one thread with a signal, yet we don't have vCont
+ // support and we are being asked to resume each thread with a
+ // signal, we need to make sure they are all the same signal, or we
+ // can't issue the continue accurately with the current support...
if (num_continue_C_tids > 1) {
continue_packet_error = false;
for (size_t i = 1; i < m_continue_C_tids.size(); ++i) {
@@ -1532,7 +1523,6 @@ void ProcessGDBRemote::ClearThreadIDList() {
size_t
ProcessGDBRemote::UpdateThreadIDsFromStopReplyThreadsValue(std::string &value) {
m_thread_ids.clear();
- m_thread_pcs.clear();
size_t comma_pos;
lldb::tid_t tid;
while ((comma_pos = value.find(',')) != std::string::npos) {
@@ -1675,9 +1665,8 @@ bool ProcessGDBRemote::UpdateThreadList(ThreadList &old_thread_list,
}
}
- // Whatever that is left in old_thread_list_copy are not
- // present in new_thread_list. Remove non-existent threads from internal id
- // table.
+ // Whatever that is left in old_thread_list_copy are not present in
+ // new_thread_list. Remove non-existent threads from internal id table.
size_t old_num_thread_ids = old_thread_list_copy.GetSize(false);
for (size_t i = 0; i < old_num_thread_ids; i++) {
ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex(i, false));
@@ -1738,12 +1727,11 @@ bool ProcessGDBRemote::CalculateThreadStopInfo(ThreadGDBRemote *thread) {
return true;
// See if we got thread stop info for any threads valid stop info reasons
- // threads
- // via the "jstopinfo" packet stop reply packet key/value pair?
+ // threads via the "jstopinfo" packet stop reply packet key/value pair?
if (m_jstopinfo_sp) {
// If we have "jstopinfo" then we have stop descriptions for all threads
- // that have stop reasons, and if there is no entry for a thread, then
- // it has no stop reason.
+ // that have stop reasons, and if there is no entry for a thread, then it
+ // has no stop reason.
thread->GetRegisterContext()->InvalidateIfNeeded(true);
if (!GetThreadStopInfoFromJSON(thread, m_jstopinfo_sp)) {
thread->SetStopInfo(StopInfoSP());
@@ -1771,9 +1759,8 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
if (tid != LLDB_INVALID_THREAD_ID) {
// Scope for "locker" below
{
- // m_thread_list_real does have its own mutex, but we need to
- // hold onto the mutex between the call to
- // m_thread_list_real.FindThreadByID(...)
+ // m_thread_list_real does have its own mutex, but we need to hold onto
+ // the mutex between the call to m_thread_list_real.FindThreadByID(...)
// and the m_thread_list_real.AddThread(...) so it doesn't change on us
std::lock_guard<std::recursive_mutex> guard(
m_thread_list_real.GetMutex());
@@ -1827,10 +1814,9 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
if (!thread_sp->StopInfoIsUpToDate()) {
thread_sp->SetStopInfo(StopInfoSP());
// If there's a memory thread backed by this thread, we need to use it
- // to calcualte StopInfo.
- ThreadSP memory_thread_sp =
- m_thread_list.FindThreadByProtocolID(thread_sp->GetProtocolID());
- if (memory_thread_sp)
+ // to calculate StopInfo.
+ if (ThreadSP memory_thread_sp =
+ m_thread_list.GetBackingThread(thread_sp))
thread_sp = memory_thread_sp;
if (exc_type != 0) {
@@ -1852,9 +1838,9 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
->GetBreakpointSiteList()
.FindByAddress(pc);
- // If the current pc is a breakpoint site then the StopInfo should
- // be set to Breakpoint
- // Otherwise, it will be set to Trace.
+ // If the current pc is a breakpoint site then the StopInfo
+ // should be set to Breakpoint Otherwise, it will be set to
+ // Trace.
if (bp_site_sp &&
bp_site_sp->ValidForThisThread(thread_sp.get())) {
thread_sp->SetStopInfo(
@@ -1871,11 +1857,10 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
.FindByAddress(pc);
if (bp_site_sp) {
// If the breakpoint is for this thread, then we'll report the
- // hit, but if it is for another thread,
- // we can just report no reason. We don't need to worry about
- // stepping over the breakpoint here, that
- // will be taken care of when the thread resumes and notices
- // that there's a breakpoint under the pc.
+ // hit, but if it is for another thread, we can just report no
+ // reason. We don't need to worry about stepping over the
+ // breakpoint here, that will be taken care of when the thread
+ // resumes and notices that there's a breakpoint under the pc.
handled = true;
if (bp_site_sp->ValidForThisThread(thread_sp.get())) {
thread_sp->SetStopInfo(
@@ -1937,13 +1922,10 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
pc);
// If the current pc is a breakpoint site then the StopInfo should
- // be set to Breakpoint
- // even though the remote stub did not set it as such. This can
- // happen when
- // the thread is involuntarily interrupted (e.g. due to stops on
- // other
- // threads) just as it is about to execute the breakpoint
- // instruction.
+ // be set to Breakpoint even though the remote stub did not set it
+ // as such. This can happen when the thread is involuntarily
+ // interrupted (e.g. due to stops on other threads) just as it is
+ // about to execute the breakpoint instruction.
if (bp_site_sp && bp_site_sp->ValidForThisThread(thread_sp.get())) {
thread_sp->SetStopInfo(
StopInfo::CreateStopReasonWithBreakpointSiteID(
@@ -1965,11 +1947,10 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
if (bp_site_sp) {
// If the breakpoint is for this thread, then we'll report the
- // hit, but if it is for another thread,
- // we can just report no reason. We don't need to worry about
- // stepping over the breakpoint here, that
- // will be taken care of when the thread resumes and notices
- // that there's a breakpoint under the pc.
+ // hit, but if it is for another thread, we can just report no
+ // reason. We don't need to worry about stepping over the
+ // breakpoint here, that will be taken care of when the thread
+ // resumes and notices that there's a breakpoint under the pc.
if (bp_site_sp->ValidForThisThread(thread_sp.get())) {
if (m_breakpoint_pc_offset != 0)
thread_sp->GetRegisterContext()->SetPC(pc);
@@ -1982,8 +1963,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
}
} else {
// If we were stepping then assume the stop was the result of
- // the trace. If we were
- // not stepping then report the SIGTRAP.
+ // the trace. If we were not stepping then report the SIGTRAP.
// FIXME: We are still missing the case where we single step
// over a trap instruction.
if (thread_sp->GetTemporaryResumeState() == eStateStepping)
@@ -2178,15 +2158,15 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
switch (stop_type) {
case 'T':
case 'S': {
- // This is a bit of a hack, but is is required. If we did exec, we
- // need to clear our thread lists and also know to rebuild our dynamic
- // register info before we lookup and threads and populate the expedited
- // register values so we need to know this right away so we can cleanup
- // and update our registers.
+ // This is a bit of a hack, but is is required. If we did exec, we need to
+ // clear our thread lists and also know to rebuild our dynamic register
+ // info before we lookup and threads and populate the expedited register
+ // values so we need to know this right away so we can cleanup and update
+ // our registers.
const uint32_t stop_id = GetStopID();
if (stop_id == 0) {
- // Our first stop, make sure we have a process ID, and also make
- // sure we know about our registers
+ // Our first stop, make sure we have a process ID, and also make sure we
+ // know about our registers
if (GetID() == LLDB_INVALID_PROCESS_ID) {
lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();
if (pid != LLDB_INVALID_PROCESS_ID)
@@ -2232,8 +2212,7 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
m_thread_ids.clear();
// A comma separated list of all threads in the current
- // process that includes the thread for this stop reply
- // packet
+ // process that includes the thread for this stop reply packet
lldb::tid_t tid;
while (!value.empty()) {
llvm::StringRef tid_str;
@@ -2245,8 +2224,7 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
} else if (key.compare("thread-pcs") == 0) {
m_thread_pcs.clear();
// A comma separated list of all threads in the current
- // process that includes the thread for this stop reply
- // packet
+ // process that includes the thread for this stop reply packet
lldb::addr_t pc;
while (!value.empty()) {
llvm::StringRef pc_str;
@@ -2298,13 +2276,10 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
desc_extractor.GetHexByteString(description);
} else if (key.compare("memory") == 0) {
// Expedited memory. GDB servers can choose to send back expedited
- // memory
- // that can populate the L1 memory cache in the process so that things
- // like
- // the frame pointer backchain can be expedited. This will help stack
- // backtracing be more efficient by not having to send as many memory
- // read
- // requests down the remote GDB server.
+ // memory that can populate the L1 memory cache in the process so that
+ // things like the frame pointer backchain can be expedited. This will
+ // help stack backtracing be more efficient by not having to send as
+ // many memory read requests down the remote GDB server.
// Key/value pair format: memory:<addr>=<bytes>;
// <addr> is a number whose base will be interpreted by the prefix:
@@ -2356,7 +2331,8 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
if (tid == LLDB_INVALID_THREAD_ID) {
// A thread id may be invalid if the response is old style 'S' packet
// which does not provide the
- // thread information. So update the thread list and choose the first one.
+ // thread information. So update the thread list and choose the first
+ // one.
UpdateThreadIDList();
if (!m_thread_ids.empty()) {
@@ -2389,9 +2365,9 @@ void ProcessGDBRemote::RefreshStateAfterStop() {
m_thread_ids.clear();
m_thread_pcs.clear();
- // Set the thread stop info. It might have a "threads" key whose value is
- // a list of all thread IDs in the current process, so m_thread_ids might
- // get set.
+ // Set the thread stop info. It might have a "threads" key whose value is a
+ // list of all thread IDs in the current process, so m_thread_ids might get
+ // set.
// Scope for the lock
{
@@ -2422,8 +2398,8 @@ void ProcessGDBRemote::RefreshStateAfterStop() {
m_initial_tid = LLDB_INVALID_THREAD_ID;
}
- // Let all threads recover from stopping and do any clean up based
- // on the previous thread state (if any).
+ // Let all threads recover from stopping and do any clean up based on the
+ // previous thread state (if any).
m_thread_list_real.RefreshStateAfterStop();
}
@@ -2431,8 +2407,8 @@ Status ProcessGDBRemote::DoHalt(bool &caused_stop) {
Status error;
if (m_public_state.GetValue() == eStateAttaching) {
- // We are being asked to halt during an attach. We need to just close
- // our file handle and debugserver will go away, and we can be done...
+ // We are being asked to halt during an attach. We need to just close our
+ // file handle and debugserver will go away, and we can be done...
m_gdb_comm.Disconnect();
} else
caused_stop = m_gdb_comm.Interrupt();
@@ -2475,31 +2451,24 @@ Status ProcessGDBRemote::DoDestroy() {
log->Printf("ProcessGDBRemote::DoDestroy()");
// There is a bug in older iOS debugservers where they don't shut down the
- // process
- // they are debugging properly. If the process is sitting at a breakpoint or
- // an exception,
- // this can cause problems with restarting. So we check to see if any of our
- // threads are stopped
- // at a breakpoint, and if so we remove all the breakpoints, resume the
- // process, and THEN
- // destroy it again.
+ // process they are debugging properly. If the process is sitting at a
+ // breakpoint or an exception, this can cause problems with restarting. So
+ // we check to see if any of our threads are stopped at a breakpoint, and if
+ // so we remove all the breakpoints, resume the process, and THEN destroy it
+ // again.
//
// Note, we don't have a good way to test the version of debugserver, but I
- // happen to know that
- // the set of all the iOS debugservers which don't support
- // GetThreadSuffixSupported() and that of
- // the debugservers with this bug are equal. There really should be a better
- // way to test this!
+ // happen to know that the set of all the iOS debugservers which don't
+ // support GetThreadSuffixSupported() and that of the debugservers with this
+ // bug are equal. There really should be a better way to test this!
//
// We also use m_destroy_tried_resuming to make sure we only do this once, if
- // we resume and then halt and
- // get called here to destroy again and we're still at a breakpoint or
- // exception, then we should
- // just do the straight-forward kill.
+ // we resume and then halt and get called here to destroy again and we're
+ // still at a breakpoint or exception, then we should just do the straight-
+ // forward kill.
//
// And of course, if we weren't able to stop the process by the time we get
- // here, it isn't
- // necessary (or helpful) to do any of this.
+ // here, it isn't necessary (or helpful) to do any of this.
if (!m_gdb_comm.GetThreadSuffixSupported() &&
m_public_state.GetValue() != eStateRunning) {
@@ -2514,9 +2483,8 @@ Status ProcessGDBRemote::DoDestroy() {
"destroy once already, not doing it again.");
} else {
// At present, the plans are discarded and the breakpoints disabled
- // Process::Destroy,
- // but we really need it to happen here and it doesn't matter if we do
- // it twice.
+ // Process::Destroy, but we really need it to happen here and it
+ // doesn't matter if we do it twice.
m_thread_list.DiscardThreadPlans();
DisableAllBreakpointSites();
@@ -2553,12 +2521,11 @@ Status ProcessGDBRemote::DoDestroy() {
m_destroy_tried_resuming = true;
// If we are going to run again before killing, it would be good to
- // suspend all the threads
- // before resuming so they won't get into more trouble. Sadly, for
- // the threads stopped with
- // the breakpoint or exception, the exception doesn't get cleared if
- // it is suspended, so we do
- // have to run the risk of letting those threads proceed a bit.
+ // suspend all the threads before resuming so they won't get into
+ // more trouble. Sadly, for the threads stopped with the breakpoint
+ // or exception, the exception doesn't get cleared if it is
+ // suspended, so we do have to run the risk of letting those threads
+ // proceed a bit.
{
std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
@@ -2605,17 +2572,14 @@ Status ProcessGDBRemote::DoDestroy() {
if (packet_cmd == 'W' || packet_cmd == 'X') {
#if defined(__APPLE__)
// For Native processes on Mac OS X, we launch through the Host
- // Platform, then hand the process off
- // to debugserver, which becomes the parent process through
- // "PT_ATTACH". Then when we go to kill
- // the process on Mac OS X we call ptrace(PT_KILL) to kill it, then we
- // call waitpid which returns
- // with no error and the correct status. But amusingly enough that
- // doesn't seem to actually reap
+ // Platform, then hand the process off to debugserver, which becomes
+ // the parent process through "PT_ATTACH". Then when we go to kill
+ // the process on Mac OS X we call ptrace(PT_KILL) to kill it, then
+ // we call waitpid which returns with no error and the correct
+ // status. But amusingly enough that doesn't seem to actually reap
// the process, but instead it is left around as a Zombie. Probably
- // the kernel is in the process of
- // switching ownership back to lldb which was the original parent, and
- // gets confused in the handoff.
+ // the kernel is in the process of switching ownership back to lldb
+ // which was the original parent, and gets confused in the handoff.
// Anyway, so call waitpid here to finally reap it.
PlatformSP platform_sp(GetTarget().GetPlatform());
if (platform_sp && platform_sp->IsHost()) {
@@ -2687,9 +2651,8 @@ void ProcessGDBRemote::SetLastStopPacket(
if (GetTarget().GetNonStopModeEnabled() == false)
m_stop_packet_stack.clear();
- // Add this stop packet to the stop packet stack
- // This stack will get popped and examined when we switch to the
- // Stopped state
+ // Add this stop packet to the stop packet stack This stack will get popped
+ // and examined when we switch to the Stopped state
m_stop_packet_stack.push_back(response);
}
}
@@ -2721,12 +2684,11 @@ addr_t ProcessGDBRemote::GetImageInfoAddress() {
}
void ProcessGDBRemote::WillPublicStop() {
- // See if the GDB remote client supports the JSON threads info.
- // If so, we gather stop info for all threads, expedited registers,
- // expedited memory, runtime queue information (iOS and MacOSX only),
- // and more. Expediting memory will help stack backtracing be much
- // faster. Expediting registers will make sure we don't have to read
- // the thread registers for GPRs.
+ // See if the GDB remote client supports the JSON threads info. If so, we
+ // gather stop info for all threads, expedited registers, expedited memory,
+ // runtime queue information (iOS and MacOSX only), and more. Expediting
+ // memory will help stack backtracing be much faster. Expediting registers
+ // will make sure we don't have to read the thread registers for GPRs.
m_jthreadsinfo_sp = m_gdb_comm.GetThreadsInfo();
if (m_jthreadsinfo_sp) {
@@ -2776,14 +2738,13 @@ size_t ProcessGDBRemote::DoReadMemory(addr_t addr, void *buf, size_t size,
error.Clear();
if (binary_memory_read) {
// The lower level GDBRemoteCommunication packet receive layer has
- // already de-quoted any
- // 0x7d character escaping that was present in the packet
+ // already de-quoted any 0x7d character escaping that was present in
+ // the packet
size_t data_received_size = response.GetBytesLeft();
if (data_received_size > size) {
// Don't write past the end of BUF if the remote debug server gave us
- // too
- // much data for some reason.
+ // too much data for some reason.
data_received_size = size;
}
memcpy(buf, response.GetStringRef().data(), data_received_size);
@@ -2807,6 +2768,145 @@ size_t ProcessGDBRemote::DoReadMemory(addr_t addr, void *buf, size_t size,
return 0;
}
+Status ProcessGDBRemote::WriteObjectFile(
+ std::vector<ObjectFile::LoadableData> entries) {
+ Status error;
+ // Sort the entries by address because some writes, like those to flash
+ // memory, must happen in order of increasing address.
+ std::stable_sort(
+ std::begin(entries), std::end(entries),
+ [](const ObjectFile::LoadableData a, const ObjectFile::LoadableData b) {
+ return a.Dest < b.Dest;
+ });
+ m_allow_flash_writes = true;
+ error = Process::WriteObjectFile(entries);
+ if (error.Success())
+ error = FlashDone();
+ else
+ // Even though some of the writing failed, try to send a flash done if some
+ // of the writing succeeded so the flash state is reset to normal, but
+ // don't stomp on the error status that was set in the write failure since
+ // that's the one we want to report back.
+ FlashDone();
+ m_allow_flash_writes = false;
+ return error;
+}
+
+bool ProcessGDBRemote::HasErased(FlashRange range) {
+ auto size = m_erased_flash_ranges.GetSize();
+ for (size_t i = 0; i < size; ++i)
+ if (m_erased_flash_ranges.GetEntryAtIndex(i)->Contains(range))
+ return true;
+ return false;
+}
+
+Status ProcessGDBRemote::FlashErase(lldb::addr_t addr, size_t size) {
+ Status status;
+
+ MemoryRegionInfo region;
+ status = GetMemoryRegionInfo(addr, region);
+ if (!status.Success())
+ return status;
+
+ // The gdb spec doesn't say if erasures are allowed across multiple regions,
+ // but we'll disallow it to be safe and to keep the logic simple by worring
+ // about only one region's block size. DoMemoryWrite is this function's
+ // primary user, and it can easily keep writes within a single memory region
+ if (addr + size > region.GetRange().GetRangeEnd()) {
+ status.SetErrorString("Unable to erase flash in multiple regions");
+ return status;
+ }
+
+ uint64_t blocksize = region.GetBlocksize();
+ if (blocksize == 0) {
+ status.SetErrorString("Unable to erase flash because blocksize is 0");
+ return status;
+ }
+
+ // Erasures can only be done on block boundary adresses, so round down addr
+ // and round up size
+ lldb::addr_t block_start_addr = addr - (addr % blocksize);
+ size += (addr - block_start_addr);
+ if ((size % blocksize) != 0)
+ size += (blocksize - size % blocksize);
+
+ FlashRange range(block_start_addr, size);
+
+ if (HasErased(range))
+ return status;
+
+ // We haven't erased the entire range, but we may have erased part of it.
+ // (e.g., block A is already erased and range starts in A and ends in B). So,
+ // adjust range if necessary to exclude already erased blocks.
+ if (!m_erased_flash_ranges.IsEmpty()) {
+ // Assuming that writes and erasures are done in increasing addr order,
+ // because that is a requirement of the vFlashWrite command. Therefore, we
+ // only need to look at the last range in the list for overlap.
+ const auto &last_range = *m_erased_flash_ranges.Back();
+ if (range.GetRangeBase() < last_range.GetRangeEnd()) {
+ auto overlap = last_range.GetRangeEnd() - range.GetRangeBase();
+ // overlap will be less than range.GetByteSize() or else HasErased()
+ // would have been true
+ range.SetByteSize(range.GetByteSize() - overlap);
+ range.SetRangeBase(range.GetRangeBase() + overlap);
+ }
+ }
+
+ StreamString packet;
+ packet.Printf("vFlashErase:%" PRIx64 ",%" PRIx64, range.GetRangeBase(),
+ (uint64_t)range.GetByteSize());
+
+ StringExtractorGDBRemote response;
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
+ true) ==
+ GDBRemoteCommunication::PacketResult::Success) {
+ if (response.IsOKResponse()) {
+ m_erased_flash_ranges.Insert(range, true);
+ } else {
+ if (response.IsErrorResponse())
+ status.SetErrorStringWithFormat("flash erase failed for 0x%" PRIx64,
+ addr);
+ else if (response.IsUnsupportedResponse())
+ status.SetErrorStringWithFormat("GDB server does not support flashing");
+ else
+ status.SetErrorStringWithFormat(
+ "unexpected response to GDB server flash erase packet '%s': '%s'",
+ packet.GetData(), response.GetStringRef().c_str());
+ }
+ } else {
+ status.SetErrorStringWithFormat("failed to send packet: '%s'",
+ packet.GetData());
+ }
+ return status;
+}
+
+Status ProcessGDBRemote::FlashDone() {
+ Status status;
+ // If we haven't erased any blocks, then we must not have written anything
+ // either, so there is no need to actually send a vFlashDone command
+ if (m_erased_flash_ranges.IsEmpty())
+ return status;
+ StringExtractorGDBRemote response;
+ if (m_gdb_comm.SendPacketAndWaitForResponse("vFlashDone", response, true) ==
+ GDBRemoteCommunication::PacketResult::Success) {
+ if (response.IsOKResponse()) {
+ m_erased_flash_ranges.Clear();
+ } else {
+ if (response.IsErrorResponse())
+ status.SetErrorStringWithFormat("flash done failed");
+ else if (response.IsUnsupportedResponse())
+ status.SetErrorStringWithFormat("GDB server does not support flashing");
+ else
+ status.SetErrorStringWithFormat(
+ "unexpected response to GDB server flash done packet: '%s'",
+ response.GetStringRef().c_str());
+ }
+ } else {
+ status.SetErrorStringWithFormat("failed to send flash done packet");
+ }
+ return status;
+}
+
size_t ProcessGDBRemote::DoWriteMemory(addr_t addr, const void *buf,
size_t size, Status &error) {
GetMaxMemorySize();
@@ -2819,10 +2919,33 @@ size_t ProcessGDBRemote::DoWriteMemory(addr_t addr, const void *buf,
size = max_memory_size;
}
- StreamString packet;
- packet.Printf("M%" PRIx64 ",%" PRIx64 ":", addr, (uint64_t)size);
- packet.PutBytesAsRawHex8(buf, size, endian::InlHostByteOrder(),
- endian::InlHostByteOrder());
+ StreamGDBRemote packet;
+
+ MemoryRegionInfo region;
+ Status region_status = GetMemoryRegionInfo(addr, region);
+
+ bool is_flash =
+ region_status.Success() && region.GetFlash() == MemoryRegionInfo::eYes;
+
+ if (is_flash) {
+ if (!m_allow_flash_writes) {
+ error.SetErrorString("Writing to flash memory is not allowed");
+ return 0;
+ }
+ // Keep the write within a flash memory region
+ if (addr + size > region.GetRange().GetRangeEnd())
+ size = region.GetRange().GetRangeEnd() - addr;
+ // Flash memory must be erased before it can be written
+ error = FlashErase(addr, size);
+ if (!error.Success())
+ return 0;
+ packet.Printf("vFlashWrite:%" PRIx64 ":", addr);
+ packet.PutEscapedBytes(buf, size);
+ } else {
+ packet.Printf("M%" PRIx64 ",%" PRIx64 ":", addr, (uint64_t)size);
+ packet.PutBytesAsRawHex8(buf, size, endian::InlHostByteOrder(),
+ endian::InlHostByteOrder());
+ }
StringExtractorGDBRemote response;
if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
true) ==
@@ -2918,8 +3041,8 @@ Status ProcessGDBRemote::DoDeallocateMemory(lldb::addr_t addr) {
switch (supported) {
case eLazyBoolCalculate:
- // We should never be deallocating memory without allocating memory
- // first so we should never get eLazyBoolCalculate
+ // We should never be deallocating memory without allocating memory first
+ // so we should never get eLazyBoolCalculate
error.SetErrorString(
"tried to deallocate memory without ever allocating memory");
break;
@@ -2991,18 +3114,14 @@ Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) {
const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode(bp_site);
// SupportsGDBStoppointPacket() simply checks a boolean, indicating if this
- // breakpoint type
- // is supported by the remote stub. These are set to true by default, and
- // later set to false
- // only after we receive an unimplemented response when sending a breakpoint
- // packet. This means
- // initially that unless we were specifically instructed to use a hardware
- // breakpoint, LLDB will
- // attempt to set a software breakpoint. HardwareRequired() also queries a
- // boolean variable which
- // indicates if the user specifically asked for hardware breakpoints. If true
- // then we will
- // skip over software breakpoints.
+ // breakpoint type is supported by the remote stub. These are set to true by
+ // default, and later set to false only after we receive an unimplemented
+ // response when sending a breakpoint packet. This means initially that
+ // unless we were specifically instructed to use a hardware breakpoint, LLDB
+ // will attempt to set a software breakpoint. HardwareRequired() also queries
+ // a boolean variable which indicates if the user specifically asked for
+ // hardware breakpoints. If true then we will skip over software
+ // breakpoints.
if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware) &&
(!bp_site->HardwareRequired())) {
// Try to send off a software breakpoint packet ($Z0)
@@ -3015,19 +3134,14 @@ Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) {
return error;
}
- // SendGDBStoppointTypePacket() will return an error if it was unable to set
- // this
- // breakpoint. We need to differentiate between a error specific to placing
- // this breakpoint
- // or if we have learned that this breakpoint type is unsupported. To do
- // this, we
- // must test the support boolean for this breakpoint type to see if it now
- // indicates that
- // this breakpoint type is unsupported. If they are still supported then we
- // should return
+ // SendGDBStoppointTypePacket() will return an error if it was unable to
+ // set this breakpoint. We need to differentiate between a error specific
+ // to placing this breakpoint or if we have learned that this breakpoint
+ // type is unsupported. To do this, we must test the support boolean for
+ // this breakpoint type to see if it now indicates that this breakpoint
+ // type is unsupported. If they are still supported then we should return
// with the error code. If they are now unsupported, then we would like to
- // fall through
- // and try another form of breakpoint.
+ // fall through and try another form of breakpoint.
if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware)) {
if (error_no != UINT8_MAX)
error.SetErrorStringWithFormat(
@@ -3038,21 +3152,18 @@ Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) {
}
// We reach here when software breakpoints have been found to be
- // unsupported. For future
- // calls to set a breakpoint, we will not attempt to set a breakpoint with a
- // type that is
- // known not to be supported.
+ // unsupported. For future calls to set a breakpoint, we will not attempt
+ // to set a breakpoint with a type that is known not to be supported.
if (log)
log->Printf("Software breakpoints are unsupported");
// So we will fall through and try a hardware breakpoint
}
- // The process of setting a hardware breakpoint is much the same as above. We
- // check the
- // supported boolean for this breakpoint type, and if it is thought to be
- // supported then we
- // will try to set this breakpoint with a hardware breakpoint.
+ // The process of setting a hardware breakpoint is much the same as above.
+ // We check the supported boolean for this breakpoint type, and if it is
+ // thought to be supported then we will try to set this breakpoint with a
+ // hardware breakpoint.
if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware)) {
// Try to send off a hardware breakpoint packet ($Z1)
uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(
@@ -3094,8 +3205,8 @@ Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) {
return error;
}
- // As a last resort we want to place a manual breakpoint. An instruction
- // is placed into the process memory using memory write packets.
+ // As a last resort we want to place a manual breakpoint. An instruction is
+ // placed into the process memory using memory write packets.
return EnableSoftwareBreakpoint(bp_site);
}
@@ -3225,10 +3336,9 @@ Status ProcessGDBRemote::DisableWatchpoint(Watchpoint *wp, bool notify) {
log->Printf("ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)",
watchID, (uint64_t)addr);
- // See also 'class WatchpointSentry' within StopInfo.cpp.
- // This disabling attempt might come from the user-supplied actions, we'll
- // route it in order for
- // the watchpoint object to intelligently process this action.
+ // See also 'class WatchpointSentry' within StopInfo.cpp. This disabling
+ // attempt might come from the user-supplied actions, we'll route it in
+ // order for the watchpoint object to intelligently process this action.
wp->SetEnabled(false, notify);
return error;
}
@@ -3313,8 +3423,8 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver(
static FileSpec g_debugserver_file_spec;
ProcessLaunchInfo debugserver_launch_info;
- // Make debugserver run in its own session so signals generated by
- // special terminal key sequences (^C) don't affect debugserver.
+ // Make debugserver run in its own session so signals generated by special
+ // terminal key sequences (^C) don't affect debugserver.
debugserver_launch_info.SetLaunchInSeparateProcessGroup(true);
const std::weak_ptr<ProcessGDBRemote> this_wp =
@@ -3325,27 +3435,22 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver(
int communication_fd = -1;
#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
- // Auto close the sockets we might open up unless everything goes OK. This
- // helps us not leak file descriptors when things go wrong.
- lldb_utility::CleanUp<int, int> our_socket(-1, -1, close);
- lldb_utility::CleanUp<int, int> gdb_socket(-1, -1, close);
-
// Use a socketpair on non-Windows systems for security and performance
// reasons.
- {
- int sockets[2]; /* the pair of socket descriptors */
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == -1) {
- error.SetErrorToErrno();
- return error;
- }
-
- our_socket.set(sockets[0]);
- gdb_socket.set(sockets[1]);
+ int sockets[2]; /* the pair of socket descriptors */
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == -1) {
+ error.SetErrorToErrno();
+ return error;
}
+ int our_socket = sockets[0];
+ int gdb_socket = sockets[1];
+ CleanUp cleanup_our(close, our_socket);
+ CleanUp cleanup_gdb(close, gdb_socket);
+
// Don't let any child processes inherit our communication socket
- SetCloexecFlag(our_socket.get());
- communication_fd = gdb_socket.get();
+ SetCloexecFlag(our_socket);
+ communication_fd = gdb_socket;
#endif
error = m_gdb_comm.StartDebugserverProcess(
@@ -3359,10 +3464,10 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver(
if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID) {
#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
- // Our process spawned correctly, we can now set our connection to use our
- // end of the socket pair
- m_gdb_comm.SetConnection(
- new ConnectionFileDescriptor(our_socket.release(), true));
+ // Our process spawned correctly, we can now set our connection to use
+ // our end of the socket pair
+ cleanup_our.disable();
+ m_gdb_comm.SetConnection(new ConnectionFileDescriptor(our_socket, true));
#endif
StartAsyncThread();
}
@@ -3377,9 +3482,9 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver(
}
if (m_gdb_comm.IsConnected()) {
- // Finish the connection process by doing the handshake without connecting
- // (send NULL URL)
- ConnectToDebugserver("");
+ // Finish the connection process by doing the handshake without
+ // connecting (send NULL URL)
+ error = ConnectToDebugserver("");
} else {
error.SetErrorString("connection failed");
}
@@ -3393,8 +3498,8 @@ bool ProcessGDBRemote::MonitorDebugserverProcess(
int signo, // Zero for no signal
int exit_status // Exit value of process if signal is zero
) {
- // "debugserver_pid" argument passed in is the process ID for
- // debugserver that we are tracking...
+ // "debugserver_pid" argument passed in is the process ID for debugserver
+ // that we are tracking...
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
const bool handled = true;
@@ -3410,12 +3515,12 @@ bool ProcessGDBRemote::MonitorDebugserverProcess(
if (!process_sp || process_sp->m_debugserver_pid != debugserver_pid)
return handled;
- // Sleep for a half a second to make sure our inferior process has
- // time to set its exit status before we set it incorrectly when
- // both the debugserver and the inferior process shut down.
+ // Sleep for a half a second to make sure our inferior process has time to
+ // set its exit status before we set it incorrectly when both the debugserver
+ // and the inferior process shut down.
usleep(500000);
- // If our process hasn't yet exited, debugserver might have died.
- // If the process did exit, then we are reaping it.
+ // If our process hasn't yet exited, debugserver might have died. If the
+ // process did exit, then we are reaping it.
const StateType state = process_sp->GetState();
if (state != eStateInvalid && state != eStateUnloaded &&
@@ -3438,8 +3543,8 @@ bool ProcessGDBRemote::MonitorDebugserverProcess(
process_sp->SetExitStatus(-1, error_str);
}
- // Debugserver has exited we need to let our ProcessGDBRemote
- // know that it no longer has a debugserver instance
+ // Debugserver has exited we need to let our ProcessGDBRemote know that it no
+ // longer has a debugserver instance
process_sp->m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
return handled;
}
@@ -3529,10 +3634,9 @@ bool ProcessGDBRemote::HandleNotifyPacket(StringExtractorGDBRemote &packet) {
// check for more stop reasons
HandleStopReplySequence();
- // if the process is stopped then we need to fake a resume
- // so that we can stop properly with the new break. This
- // is possible due to SetPrivateState() broadcasting the
- // state change as a side effect.
+ // if the process is stopped then we need to fake a resume so that we can
+ // stop properly with the new break. This is possible due to
+ // SetPrivateState() broadcasting the state change as a side effect.
if (GetPrivateState() == lldb::StateType::eStateStopped) {
SetPrivateState(lldb::StateType::eStateRunning);
}
@@ -3605,12 +3709,11 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
response);
// We need to immediately clear the thread ID list so we are sure
- // to get a valid list of threads.
- // The thread ID list might be contained within the "response", or
- // the stop reply packet that
+ // to get a valid list of threads. The thread ID list might be
+ // contained within the "response", or the stop reply packet that
// caused the stop. So clear it now before we give the stop reply
- // packet to the process
- // using the process->SetLastStopPacket()...
+ // packet to the process using the
+ // process->SetLastStopPacket()...
process->ClearThreadIDList();
switch (stop_state) {
@@ -3647,17 +3750,14 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
// Check to see if we were trying to attach and if we got back
// the "E87" error code from debugserver -- this indicates that
// the process is not debuggable. Return a slightly more
- // helpful
- // error message about why the attach failed.
+ // helpful error message about why the attach failed.
if (::strstr(continue_cstr, "vAttach") != NULL &&
response.GetError() == 0x87) {
process->SetExitStatus(-1, "cannot attach to process due to "
"System Integrity Protection");
- }
- // E01 code from vAttach means that the attach failed
- if (::strstr(continue_cstr, "vAttach") != NULL &&
- response.GetError() == 0x1) {
- process->SetExitStatus(-1, "unable to attach");
+ } else if (::strstr(continue_cstr, "vAttach") != NULL &&
+ response.GetStatus().Fail()) {
+ process->SetExitStatus(-1, response.GetStatus().AsCString());
} else {
process->SetExitStatus(-1, "lost connection");
}
@@ -3769,8 +3869,8 @@ Status ProcessGDBRemote::UpdateAutomaticSignalFiltering() {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
LLDB_LOG(log, "Check if need to update ignored signals");
- // QPassSignals package is not supported by the server,
- // there is no way we can ignore any signals on server side.
+ // QPassSignals package is not supported by the server, there is no way we
+ // can ignore any signals on server side.
if (!m_gdb_comm.GetQPassSignalsSupported())
return Status();
@@ -3894,9 +3994,9 @@ ProcessGDBRemote::GetExtendedInfoForThread(lldb::tid_t tid) {
// FIXME the final character of a JSON dictionary, '}', is the escape
// character in gdb-remote binary mode. lldb currently doesn't escape
- // these characters in its packet output -- so we add the quoted version
- // of the } character here manually in case we talk to a debugserver which
- // un-escapes the characters at packet read time.
+ // these characters in its packet output -- so we add the quoted version of
+ // the } character here manually in case we talk to a debugserver which un-
+ // escapes the characters at packet read time.
packet << (char)(0x7d ^ 0x20);
StringExtractorGDBRemote response;
@@ -3966,9 +4066,9 @@ ProcessGDBRemote::GetLoadedDynamicLibrariesInfos_sender(
// FIXME the final character of a JSON dictionary, '}', is the escape
// character in gdb-remote binary mode. lldb currently doesn't escape
- // these characters in its packet output -- so we add the quoted version
- // of the } character here manually in case we talk to a debugserver which
- // un-escapes the characters at packet read time.
+ // these characters in its packet output -- so we add the quoted version of
+ // the } character here manually in case we talk to a debugserver which un-
+ // escapes the characters at packet read time.
packet << (char)(0x7d ^ 0x20);
StringExtractorGDBRemote response;
@@ -3999,9 +4099,9 @@ StructuredData::ObjectSP ProcessGDBRemote::GetSharedCacheInfo() {
// FIXME the final character of a JSON dictionary, '}', is the escape
// character in gdb-remote binary mode. lldb currently doesn't escape
- // these characters in its packet output -- so we add the quoted version
- // of the } character here manually in case we talk to a debugserver which
- // un-escapes the characters at packet read time.
+ // these characters in its packet output -- so we add the quoted version of
+ // the } character here manually in case we talk to a debugserver which un-
+ // escapes the characters at packet read time.
packet << (char)(0x7d ^ 0x20);
StringExtractorGDBRemote response;
@@ -4026,14 +4126,14 @@ Status ProcessGDBRemote::ConfigureStructuredData(
return m_gdb_comm.ConfigureRemoteStructuredData(type_name, config_sp);
}
-// Establish the largest memory read/write payloads we should use.
-// If the remote stub has a max packet size, stay under that size.
+// Establish the largest memory read/write payloads we should use. If the
+// remote stub has a max packet size, stay under that size.
//
-// If the remote stub's max packet size is crazy large, use a
-// reasonable largeish default.
+// If the remote stub's max packet size is crazy large, use a reasonable
+// largeish default.
//
-// If the remote stub doesn't advertise a max packet size, use a
-// conservative default.
+// If the remote stub doesn't advertise a max packet size, use a conservative
+// default.
void ProcessGDBRemote::GetMaxMemorySize() {
const uint64_t reasonable_largeish_default = 128 * 1024;
@@ -4045,15 +4145,15 @@ void ProcessGDBRemote::GetMaxMemorySize() {
// Save the stub's claimed maximum packet size
m_remote_stub_max_memory_size = stub_max_size;
- // Even if the stub says it can support ginormous packets,
- // don't exceed our reasonable largeish default packet size.
+ // Even if the stub says it can support ginormous packets, don't exceed
+ // our reasonable largeish default packet size.
if (stub_max_size > reasonable_largeish_default) {
stub_max_size = reasonable_largeish_default;
}
- // Memory packet have other overheads too like Maddr,size:#NN
- // Instead of calculating the bytes taken by size and addr every
- // time, we take a maximum guess here.
+ // Memory packet have other overheads too like Maddr,size:#NN Instead of
+ // calculating the bytes taken by size and addr every time, we take a
+ // maximum guess here.
if (stub_max_size > 70)
stub_max_size -= 32 + 32 + 6;
else {
@@ -4140,13 +4240,8 @@ void ProcessGDBRemote::PrefetchModuleSpecs(
}
}
-bool ProcessGDBRemote::GetHostOSVersion(uint32_t &major, uint32_t &minor,
- uint32_t &update) {
- if (m_gdb_comm.GetOSVersion(major, minor, update))
- return true;
- // We failed to get the host OS version, defer to the base
- // implementation to correctly invalidate the arguments.
- return Process::GetHostOSVersion(major, minor, update);
+llvm::VersionTuple ProcessGDBRemote::GetHostOSVersion() {
+ return m_gdb_comm.GetOSVersion();
}
namespace {
@@ -4237,7 +4332,7 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
} else if (name == "format") {
format_set = true;
Format format = eFormatInvalid;
- if (Args::StringToFormat(value.data(), format, NULL).Success())
+ if (OptionArgParser::ToFormat(value.data(), format, NULL).Success())
reg_info.format = format;
else if (value == "vector-sint8")
reg_info.format = eFormatVectorOfSInt8;
@@ -4311,8 +4406,8 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
}
// Only update the register set name if we didn't get a "reg_set"
+ // attribute. "set_name" will be empty if we didn't have a "reg_set"
// attribute.
- // "set_name" will be empty if we didn't have a "reg_set" attribute.
if (!set_name && !gdb_group.empty())
set_name.SetCString(gdb_group.c_str());
@@ -4339,8 +4434,8 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
} // namespace {}
-// query the target of gdb-remote for extended target information
-// return: 'true' on success
+// query the target of gdb-remote for extended target information return:
+// 'true' on success
// 'false' on failure
bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {
// Make sure LLDB has an XML parser it can use first
@@ -4409,15 +4504,27 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {
return true; // Keep iterating through all children of the target_node
});
+ // If the target.xml includes an architecture entry like
+ // <architecture>i386:x86-64</architecture> (seen from VMWare ESXi)
+ // <architecture>arm</architecture> (seen from Segger JLink on unspecified arm board)
+ // use that if we don't have anything better.
+ if (!arch_to_use.IsValid() && !target_info.arch.empty()) {
+ if (target_info.arch == "i386:x86-64")
+ {
+ // We don't have any information about vendor or OS.
+ arch_to_use.SetTriple("x86_64--");
+ GetTarget().MergeArchitecture(arch_to_use);
+ }
+ }
+
// Initialize these outside of ParseRegisters, since they should not be
// reset inside each include feature
uint32_t cur_reg_num = 0;
uint32_t reg_offset = 0;
- // Don't use Process::GetABI, this code gets called from DidAttach, and in
- // that context we haven't
- // set the Target's architecture yet, so the ABI is also potentially
- // incorrect.
+ // Don't use Process::GetABI, this code gets called from DidAttach, and
+ // in that context we haven't set the Target's architecture yet, so the
+ // ABI is also potentially incorrect.
ABISP abi_to_use_sp = ABI::FindPlugin(shared_from_this(), arch_to_use);
for (auto &feature_node : feature_nodes) {
ParseRegisters(feature_node, target_info, this->m_register_info,
@@ -4758,8 +4865,8 @@ void ProcessGDBRemote::ModulesDidLoad(ModuleList &module_list) {
// do anything
Process::ModulesDidLoad(module_list);
- // After loading shared libraries, we can ask our remote GDB server if
- // it needs any symbols.
+ // After loading shared libraries, we can ask our remote GDB server if it
+ // needs any symbols.
m_gdb_comm.ServeSymbolLookups(this);
}
@@ -4817,8 +4924,8 @@ std::string ProcessGDBRemote::HarmonizeThreadIdsForProfileData(
has_used_usec = true;
usec_value.getAsInteger(0, curr_used_usec);
} else {
- // We didn't find what we want, it is probably
- // an older version. Bail out.
+ // We didn't find what we want, it is probably an older version. Bail
+ // out.
profileDataExtractor.SetFilePos(input_file_pos);
}
}
@@ -4840,8 +4947,8 @@ std::string ProcessGDBRemote::HarmonizeThreadIdsForProfileData(
((real_used_usec > 0) || (HasAssignedIndexIDToThread(thread_id)));
if (good_first_time || good_subsequent_time) {
- // We try to avoid doing too many index id reservation,
- // resulting in fast increase of index ids.
+ // We try to avoid doing too many index id reservation, resulting in
+ // fast increase of index ids.
output_stream << name << ":";
int32_t index_id = AssignIndexIDToThread(thread_id);
@@ -4892,7 +4999,7 @@ ParseStructuredDataPacket(llvm::StringRef packet) {
if (!packet.consume_front(s_async_json_packet_prefix)) {
if (log) {
log->Printf(
- "GDBRemoteCommmunicationClientBase::%s() received $J packet "
+ "GDBRemoteCommunicationClientBase::%s() received $J packet "
"but was not a StructuredData packet: packet starts with "
"%s",
__FUNCTION__,
@@ -4901,8 +5008,7 @@ ParseStructuredDataPacket(llvm::StringRef packet) {
return StructuredData::ObjectSP();
}
- // This is an asynchronous JSON packet, destined for a
- // StructuredDataPlugin.
+ // This is an asynchronous JSON packet, destined for a StructuredDataPlugin.
StructuredData::ObjectSP json_sp = StructuredData::ParseJSON(packet);
if (log) {
if (json_sp) {
@@ -5137,8 +5243,9 @@ public:
~CommandObjectProcessGDBRemotePacketMonitor() {}
- bool DoExecute(const char *command, CommandReturnObject &result) override {
- if (command == NULL || command[0] == '\0') {
+ bool DoExecute(llvm::StringRef command,
+ CommandReturnObject &result) override {
+ if (command.empty()) {
result.AppendErrorWithFormat("'%s' takes a command string argument",
m_cmd_name.c_str());
result.SetStatus(eReturnStatusFailed);
@@ -5150,14 +5257,15 @@ public:
if (process) {
StreamString packet;
packet.PutCString("qRcmd,");
- packet.PutBytesAsRawHex8(command, strlen(command));
+ packet.PutBytesAsRawHex8(command.data(), command.size());
bool send_async = true;
StringExtractorGDBRemote response;
- process->GetGDBRemote().SendPacketAndWaitForResponse(
- packet.GetString(), response, send_async);
- result.SetStatus(eReturnStatusSuccessFinishResult);
Stream &output_strm = result.GetOutputStream();
+ process->GetGDBRemote().SendPacketAndReceiveResponseWithOutputSupport(
+ packet.GetString(), response, send_async,
+ [&output_strm](llvm::StringRef output) { output_strm << output; });
+ result.SetStatus(eReturnStatusSuccessFinishResult);
output_strm.Printf(" packet: %s\n", packet.GetData());
const std::string &response_str = response.GetStringRef();
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 42d1c4ecd666..45bb2d4c28e7 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -144,6 +144,9 @@ public:
size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
Status &error) override;
+ Status
+ WriteObjectFile(std::vector<ObjectFile::LoadableData> entries) override;
+
size_t DoWriteMemory(lldb::addr_t addr, const void *buf, size_t size,
Status &error) override;
@@ -214,8 +217,7 @@ public:
void PrefetchModuleSpecs(llvm::ArrayRef<FileSpec> module_file_specs,
const llvm::Triple &triple) override;
- bool GetHostOSVersion(uint32_t &major, uint32_t &minor,
- uint32_t &update) override;
+ llvm::VersionTuple GetHostOSVersion() override;
size_t LoadModules(LoadedModuleInfoList &module_list) override;
@@ -302,6 +304,11 @@ protected:
int64_t m_breakpoint_pc_offset;
lldb::tid_t m_initial_tid; // The initial thread ID, given by stub on attach
+ bool m_allow_flash_writes;
+ using FlashRangeVector = lldb_private::RangeVector<lldb::addr_t, size_t>;
+ using FlashRange = FlashRangeVector::Entry;
+ FlashRangeVector m_erased_flash_ranges;
+
//----------------------------------------------------------------------
// Accessors
//----------------------------------------------------------------------
@@ -408,6 +415,12 @@ protected:
Status UpdateAutomaticSignalFiltering() override;
+ Status FlashErase(lldb::addr_t addr, size_t size);
+
+ Status FlashDone();
+
+ bool HasErased(FlashRange range);
+
private:
//------------------------------------------------------------------
// For ProcessGDBRemote only
diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index 27dd03bfc7bc..a525c16b9f13 100644
--- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -24,7 +24,7 @@
#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
-#include "Utility/StringExtractorGDBRemote.h"
+#include "lldb/Utility/StringExtractorGDBRemote.h"
using namespace lldb;
using namespace lldb_private;
@@ -55,7 +55,7 @@ ThreadGDBRemote::~ThreadGDBRemote() {
const char *ThreadGDBRemote::GetName() {
if (m_thread_name.empty())
- return NULL;
+ return nullptr;
return m_thread_name.c_str();
}
@@ -80,10 +80,9 @@ void ThreadGDBRemote::SetQueueInfo(std::string &&queue_name,
const char *ThreadGDBRemote::GetQueueName() {
// If our cached queue info is valid, then someone called
- // ThreadGDBRemote::SetQueueInfo(...)
- // with valid information that was gleaned from the stop reply packet. In this
- // case we trust
- // that the info is valid in m_dispatch_queue_name without refetching it
+ // ThreadGDBRemote::SetQueueInfo(...) with valid information that was gleaned
+ // from the stop reply packet. In this case we trust that the info is valid
+ // in m_dispatch_queue_name without refetching it
if (CachedQueueInfoIsValid()) {
if (m_dispatch_queue_name.empty())
return nullptr;
@@ -110,15 +109,14 @@ const char *ThreadGDBRemote::GetQueueName() {
return m_dispatch_queue_name.c_str();
}
}
- return NULL;
+ return nullptr;
}
QueueKind ThreadGDBRemote::GetQueueKind() {
// If our cached queue info is valid, then someone called
- // ThreadGDBRemote::SetQueueInfo(...)
- // with valid information that was gleaned from the stop reply packet. In this
- // case we trust
- // that the info is valid in m_dispatch_queue_name without refetching it
+ // ThreadGDBRemote::SetQueueInfo(...) with valid information that was gleaned
+ // from the stop reply packet. In this case we trust that the info is valid
+ // in m_dispatch_queue_name without refetching it
if (CachedQueueInfoIsValid()) {
return m_queue_kind;
}
@@ -141,10 +139,9 @@ QueueKind ThreadGDBRemote::GetQueueKind() {
queue_id_t ThreadGDBRemote::GetQueueID() {
// If our cached queue info is valid, then someone called
- // ThreadGDBRemote::SetQueueInfo(...)
- // with valid information that was gleaned from the stop reply packet. In this
- // case we trust
- // that the info is valid in m_dispatch_queue_name without refetching it
+ // ThreadGDBRemote::SetQueueInfo(...) with valid information that was gleaned
+ // from the stop reply packet. In this case we trust that the info is valid
+ // in m_dispatch_queue_name without refetching it
if (CachedQueueInfoIsValid())
return m_queue_serial_number;
@@ -275,11 +272,11 @@ void ThreadGDBRemote::RefreshStateAfterStop() {
// Invalidate all registers in our register context. We don't set "force" to
// true because the stop reply packet might have had some register values
// that were expedited and these will already be copied into the register
- // context by the time this function gets called. The GDBRemoteRegisterContext
- // class has been made smart enough to detect when it needs to invalidate
- // which registers are valid by putting hooks in the register read and
- // register supply functions where they check the process stop ID and do
- // the right thing.
+ // context by the time this function gets called. The
+ // GDBRemoteRegisterContext class has been made smart enough to detect when
+ // it needs to invalidate which registers are valid by putting hooks in the
+ // register read and register supply functions where they check the process
+ // stop ID and do the right thing.
const bool force = false;
GetRegisterContext()->InvalidateIfNeeded(force);
}
@@ -292,8 +289,8 @@ void ThreadGDBRemote::Dump(Log *log, uint32_t index) {}
bool ThreadGDBRemote::ShouldStop(bool &step_more) { return true; }
lldb::RegisterContextSP ThreadGDBRemote::GetRegisterContext() {
- if (m_reg_context_sp.get() == NULL)
- m_reg_context_sp = CreateRegisterContextForFrame(NULL);
+ if (!m_reg_context_sp)
+ m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
return m_reg_context_sp;
}
@@ -310,7 +307,8 @@ ThreadGDBRemote::CreateRegisterContextForFrame(StackFrame *frame) {
if (process_sp) {
ProcessGDBRemote *gdb_process =
static_cast<ProcessGDBRemote *>(process_sp.get());
- // read_all_registers_at_once will be true if 'p' packet is not supported.
+ // read_all_registers_at_once will be true if 'p' packet is not
+ // supported.
bool read_all_registers_at_once =
!gdb_process->GetGDBRemote().GetpPacketSupported(GetID());
reg_ctx_sp.reset(new GDBRemoteRegisterContext(
@@ -319,7 +317,7 @@ ThreadGDBRemote::CreateRegisterContextForFrame(StackFrame *frame) {
}
} else {
Unwind *unwinder = GetUnwinder();
- if (unwinder)
+ if (unwinder != nullptr)
reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
}
return reg_ctx_sp;
diff --git a/source/Plugins/Process/mach-core/CMakeLists.txt b/source/Plugins/Process/mach-core/CMakeLists.txt
index 18f6ff581ea3..e79cd82c92a6 100644
--- a/source/Plugins/Process/mach-core/CMakeLists.txt
+++ b/source/Plugins/Process/mach-core/CMakeLists.txt
@@ -1,5 +1,3 @@
-include_directories(../Utility)
-
add_lldb_library(lldbPluginProcessMachCore PLUGIN
ProcessMachCore.cpp
ThreadMachCore.cpp
diff --git a/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/source/Plugins/Process/mach-core/ProcessMachCore.cpp
index d21651b77ee0..bfa35ed506a9 100644
--- a/source/Plugins/Process/mach-core/ProcessMachCore.cpp
+++ b/source/Plugins/Process/mach-core/ProcessMachCore.cpp
@@ -35,7 +35,7 @@
// Project includes
#include "ProcessMachCore.h"
-#include "StopInfoMachException.h"
+#include "Plugins/Process/Utility/StopInfoMachException.h"
#include "ThreadMachCore.h"
// Needed for the plug-in names for the dynamic loaders.
@@ -91,11 +91,10 @@ bool ProcessMachCore::CanDebug(lldb::TargetSP target_sp,
// For now we are just making sure the file exists for a given module
if (!m_core_module_sp && m_core_file.Exists()) {
- // Don't add the Target's architecture to the ModuleSpec - we may be working
- // with a core file that doesn't have the correct cpusubtype in the header
- // but we should still try to use it -
- // ModuleSpecList::FindMatchingModuleSpec
- // enforces a strict arch mach.
+ // Don't add the Target's architecture to the ModuleSpec - we may be
+ // working with a core file that doesn't have the correct cpusubtype in the
+ // header but we should still try to use it -
+ // ModuleSpecList::FindMatchingModuleSpec enforces a strict arch mach.
ModuleSpec core_module_spec(m_core_file);
Status error(ModuleList::GetSharedModule(core_module_spec, m_core_module_sp,
NULL, NULL, NULL));
@@ -125,10 +124,10 @@ ProcessMachCore::ProcessMachCore(lldb::TargetSP target_sp,
//----------------------------------------------------------------------
ProcessMachCore::~ProcessMachCore() {
Clear();
- // We need to call finalize on the process before destroying ourselves
- // to make sure all of the broadcaster cleanup goes as planned. If we
- // destruct this class, then Process::~Process() might have problems
- // trying to fully destroy the broadcaster.
+ // We need to call finalize on the process before destroying ourselves to
+ // make sure all of the broadcaster cleanup goes as planned. If we destruct
+ // this class, then Process::~Process() might have problems trying to fully
+ // destroy the broadcaster.
Finalize();
}
@@ -162,11 +161,10 @@ bool ProcessMachCore::GetDynamicLoaderAddress(lldb::addr_t addr) {
// header.magic, header.filetype);
if (header.magic == llvm::MachO::MH_MAGIC ||
header.magic == llvm::MachO::MH_MAGIC_64) {
- // Check MH_EXECUTABLE to see if we can find the mach image
- // that contains the shared library list. The dynamic loader
- // (dyld) is what contains the list for user applications,
- // and the mach kernel contains a global that has the list
- // of kexts to load
+ // Check MH_EXECUTABLE to see if we can find the mach image that contains
+ // the shared library list. The dynamic loader (dyld) is what contains the
+ // list for user applications, and the mach kernel contains a global that
+ // has the list of kexts to load
switch (header.filetype) {
case llvm::MachO::MH_DYLINKER:
// printf("0x%16.16" PRIx64 ": file_type = MH_DYLINKER\n", vaddr);
@@ -272,13 +270,10 @@ Status ProcessMachCore::DoLoadCore() {
} else {
m_core_aranges.Append(range_entry);
}
- // Some core files don't fill in the permissions correctly. If that is the
- // case
- // assume read + execute so clients don't think the memory is not
- // readable,
- // or executable. The memory isn't writable since this plug-in doesn't
- // implement
- // DoWriteMemory.
+ // Some core files don't fill in the permissions correctly. If that is
+ // the case assume read + execute so clients don't think the memory is
+ // not readable, or executable. The memory isn't writable since this
+ // plug-in doesn't implement DoWriteMemory.
uint32_t permissions = section->GetPermissions();
if (permissions == 0)
permissions = lldb::ePermissionsReadable | lldb::ePermissionsExecutable;
@@ -309,8 +304,8 @@ Status ProcessMachCore::DoLoadCore() {
}
// This checks for the presence of an LC_IDENT string in a core file;
- // LC_IDENT is very obsolete and should not be used in new code, but
- // if the load command is present, let's use the contents.
+ // LC_IDENT is very obsolete and should not be used in new code, but if the
+ // load command is present, let's use the contents.
std::string corefile_identifier = core_objfile->GetIdentifierString();
if (found_main_binary_definitively == false
&& corefile_identifier.find("Darwin Kernel") != std::string::npos) {
@@ -319,7 +314,7 @@ Status ProcessMachCore::DoLoadCore() {
if (corefile_identifier.find("UUID=") != std::string::npos) {
size_t p = corefile_identifier.find("UUID=") + strlen("UUID=");
std::string uuid_str = corefile_identifier.substr(p, 36);
- uuid.SetFromCString(uuid_str.c_str());
+ uuid.SetFromStringRef(uuid_str);
}
if (corefile_identifier.find("stext=") != std::string::npos) {
size_t p = corefile_identifier.find("stext=") + strlen("stext=");
@@ -342,16 +337,12 @@ Status ProcessMachCore::DoLoadCore() {
if (found_main_binary_definitively == false
&& (m_dyld_addr == LLDB_INVALID_ADDRESS
|| m_mach_kernel_addr == LLDB_INVALID_ADDRESS)) {
- // We need to locate the main executable in the memory ranges
- // we have in the core file. We need to search for both a user-process dyld
- // binary
+ // We need to locate the main executable in the memory ranges we have in
+ // the core file. We need to search for both a user-process dyld binary
// and a kernel binary in memory; we must look at all the pages in the
- // binary so
- // we don't miss one or the other. Step through all memory segments
- // searching for
- // a kernel binary and for a user process dyld -- we'll decide which to
- // prefer
- // later if both are present.
+ // binary so we don't miss one or the other. Step through all memory
+ // segments searching for a kernel binary and for a user process dyld --
+ // we'll decide which to prefer later if both are present.
const size_t num_core_aranges = m_core_aranges.GetSize();
for (size_t i = 0; i < num_core_aranges; ++i) {
@@ -369,13 +360,10 @@ Status ProcessMachCore::DoLoadCore() {
if (found_main_binary_definitively == false
&& m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
// In the case of multiple kernel images found in the core file via
- // exhaustive
- // search, we may not pick the correct one. See if the
- // DynamicLoaderDarwinKernel's
- // search heuristics might identify the correct one.
- // Most of the time, I expect the address from SearchForDarwinKernel() will
- // be the
- // same as the address we found via exhaustive search.
+ // exhaustive search, we may not pick the correct one. See if the
+ // DynamicLoaderDarwinKernel's search heuristics might identify the correct
+ // one. Most of the time, I expect the address from SearchForDarwinKernel()
+ // will be the same as the address we found via exhaustive search.
if (GetTarget().GetArchitecture().IsValid() == false &&
m_core_module_sp.get()) {
@@ -383,13 +371,11 @@ Status ProcessMachCore::DoLoadCore() {
}
// SearchForDarwinKernel will end up calling back into this this class in
- // the GetImageInfoAddress
- // method which will give it the m_mach_kernel_addr/m_dyld_addr it already
- // has. Save that aside
- // and set m_mach_kernel_addr/m_dyld_addr to an invalid address temporarily
- // so
- // DynamicLoaderDarwinKernel does a real search for the kernel using its own
- // heuristics.
+ // the GetImageInfoAddress method which will give it the
+ // m_mach_kernel_addr/m_dyld_addr it already has. Save that aside and set
+ // m_mach_kernel_addr/m_dyld_addr to an invalid address temporarily so
+ // DynamicLoaderDarwinKernel does a real search for the kernel using its
+ // own heuristics.
addr_t saved_mach_kernel_addr = m_mach_kernel_addr;
addr_t saved_user_dyld_addr = m_dyld_addr;
@@ -410,8 +396,8 @@ Status ProcessMachCore::DoLoadCore() {
}
}
- // If we found both a user-process dyld and a kernel binary, we need to decide
- // which to prefer.
+ // If we found both a user-process dyld and a kernel binary, we need to
+ // decide which to prefer.
if (GetCorefilePreference() == eKernelCorefile) {
if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
if (log)
@@ -444,18 +430,13 @@ Status ProcessMachCore::DoLoadCore() {
if (m_dyld_plugin_name != DynamicLoaderMacOSXDYLD::GetPluginNameStatic()) {
// For non-user process core files, the permissions on the core file
- // segments are usually
- // meaningless, they may be just "read", because we're dealing with kernel
- // coredumps or
- // early startup coredumps and the dumper is grabbing pages of memory
- // without knowing
- // what they are. If they aren't marked as "exeuctable", that can break the
- // unwinder
- // which will check a pc value to see if it is in an executable segment and
- // stop the
+ // segments are usually meaningless, they may be just "read", because we're
+ // dealing with kernel coredumps or early startup coredumps and the dumper
+ // is grabbing pages of memory without knowing what they are. If they
+ // aren't marked as "exeuctable", that can break the unwinder which will
+ // check a pc value to see if it is in an executable segment and stop the
// backtrace early if it is not ("executable" and "unknown" would both be
- // fine, but
- // "not executable" will break the unwinder).
+ // fine, but "not executable" will break the unwinder).
size_t core_range_infos_size = m_core_range_infos.GetSize();
for (size_t i = 0; i < core_range_infos_size; i++) {
VMRangeToPermissions::Entry *ent =
@@ -464,8 +445,8 @@ Status ProcessMachCore::DoLoadCore() {
}
}
- // Even if the architecture is set in the target, we need to override
- // it to match the core file which is always single arch.
+ // Even if the architecture is set in the target, we need to override it to
+ // match the core file which is always single arch.
ArchSpec arch(m_core_module_sp->GetArchitecture());
if (arch.GetCore() == ArchSpec::eCore_x86_32_i486) {
arch = Platform::GetAugmentedArchSpec(GetTarget().GetPlatform().get(), "i386");
@@ -488,8 +469,7 @@ bool ProcessMachCore::UpdateThreadList(ThreadList &old_thread_list,
ThreadList &new_thread_list) {
if (old_thread_list.GetSize(false) == 0) {
// Make up the thread the first time this is called so we can setup our one
- // and only
- // core thread state.
+ // and only core thread state.
ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
if (core_objfile) {
@@ -508,8 +488,8 @@ bool ProcessMachCore::UpdateThreadList(ThreadList &old_thread_list,
}
void ProcessMachCore::RefreshStateAfterStop() {
- // Let all threads recover from stopping and do any clean up based
- // on the previous thread state (if any).
+ // Let all threads recover from stopping and do any clean up based on the
+ // previous thread state (if any).
m_thread_list.RefreshStateAfterStop();
// SetThreadStopInfo (m_last_stop_packet);
}
@@ -529,8 +509,8 @@ bool ProcessMachCore::WarnBeforeDetach() const { return false; }
//------------------------------------------------------------------
size_t ProcessMachCore::ReadMemory(addr_t addr, void *buf, size_t size,
Status &error) {
- // Don't allow the caching that lldb_private::Process::ReadMemory does
- // since in core files we have it all cached our our core file anyway.
+ // Don't allow the caching that lldb_private::Process::ReadMemory does since
+ // in core files we have it all cached our our core file anyway.
return DoReadMemory(addr, buf, size, error);
}
@@ -546,19 +526,17 @@ size_t ProcessMachCore::DoReadMemory(addr_t addr, void *buf, size_t size,
// Address Size File off File size
// ---------- ---------- ---------- ----------
// LC_SEGMENT 0x000f6000 0x00001000 0x1d509ee8 0x00001000 --- --- 0
- // 0x00000000 __TEXT
- // LC_SEGMENT 0x0f600000 0x00100000 0x1d50aee8 0x00100000 --- --- 0
- // 0x00000000 __TEXT
- // LC_SEGMENT 0x000f7000 0x00001000 0x1d60aee8 0x00001000 --- --- 0
- // 0x00000000 __TEXT
+ // 0x00000000 __TEXT LC_SEGMENT 0x0f600000 0x00100000 0x1d50aee8 0x00100000
+ // --- --- 0 0x00000000 __TEXT LC_SEGMENT 0x000f7000 0x00001000
+ // 0x1d60aee8 0x00001000 --- --- 0 0x00000000 __TEXT
//
// Any if the user executes the following command:
//
// (lldb) mem read 0xf6ff0
//
- // We would attempt to read 32 bytes from 0xf6ff0 but would only
- // get 16 unless we loop through consecutive memory ranges that are
- // contiguous in the address space, but not in the file data.
+ // We would attempt to read 32 bytes from 0xf6ff0 but would only get 16
+ // unless we loop through consecutive memory ranges that are contiguous in
+ // the address space, but not in the file data.
//----------------------------------------------------------------------
while (bytes_read < size) {
const addr_t curr_addr = addr + bytes_read;
@@ -641,8 +619,8 @@ void ProcessMachCore::Initialize() {
}
addr_t ProcessMachCore::GetImageInfoAddress() {
- // If we found both a user-process dyld and a kernel binary, we need to decide
- // which to prefer.
+ // If we found both a user-process dyld and a kernel binary, we need to
+ // decide which to prefer.
if (GetCorefilePreference() == eKernelCorefile) {
if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
return m_mach_kernel_addr;
diff --git a/source/Plugins/Process/mach-core/ThreadMachCore.cpp b/source/Plugins/Process/mach-core/ThreadMachCore.cpp
index 2b44105c13b1..c262dd47f978 100644
--- a/source/Plugins/Process/mach-core/ThreadMachCore.cpp
+++ b/source/Plugins/Process/mach-core/ThreadMachCore.cpp
@@ -43,7 +43,7 @@ ThreadMachCore::~ThreadMachCore() { DestroyThread(); }
const char *ThreadMachCore::GetName() {
if (m_thread_name.empty())
- return NULL;
+ return nullptr;
return m_thread_name.c_str();
}
@@ -54,8 +54,8 @@ void ThreadMachCore::RefreshStateAfterStop() {
// context by the time this function gets called. The KDPRegisterContext
// class has been made smart enough to detect when it needs to invalidate
// which registers are valid by putting hooks in the register read and
- // register supply functions where they check the process stop ID and do
- // the right thing.
+ // register supply functions where they check the process stop ID and do the
+ // right thing.
const bool force = false;
GetRegisterContext()->InvalidateIfNeeded(force);
}
@@ -63,8 +63,8 @@ void ThreadMachCore::RefreshStateAfterStop() {
bool ThreadMachCore::ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; }
lldb::RegisterContextSP ThreadMachCore::GetRegisterContext() {
- if (m_reg_context_sp.get() == NULL)
- m_reg_context_sp = CreateRegisterContextForFrame(NULL);
+ if (!m_reg_context_sp)
+ m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
return m_reg_context_sp;
}
@@ -89,7 +89,7 @@ ThreadMachCore::CreateRegisterContextForFrame(StackFrame *frame) {
reg_ctx_sp = m_thread_reg_ctx_sp;
} else {
Unwind *unwinder = GetUnwinder();
- if (unwinder)
+ if (unwinder != nullptr)
reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
}
return reg_ctx_sp;
diff --git a/source/Plugins/Process/minidump/CMakeLists.txt b/source/Plugins/Process/minidump/CMakeLists.txt
index 61ce16830c9b..b898ee1aa144 100644
--- a/source/Plugins/Process/minidump/CMakeLists.txt
+++ b/source/Plugins/Process/minidump/CMakeLists.txt
@@ -1,5 +1,3 @@
-include_directories(../Utility)
-
add_lldb_library(lldbPluginProcessMinidump PLUGIN
MinidumpTypes.cpp
MinidumpParser.cpp
diff --git a/source/Plugins/Process/minidump/MinidumpParser.cpp b/source/Plugins/Process/minidump/MinidumpParser.cpp
index 36350fdb6398..9a979335e99e 100644
--- a/source/Plugins/Process/minidump/MinidumpParser.cpp
+++ b/source/Plugins/Process/minidump/MinidumpParser.cpp
@@ -14,10 +14,13 @@
// Other libraries and framework includes
#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Utility/LLDBAssert.h"
// C includes
// C++ includes
+#include <algorithm>
#include <map>
+#include <vector>
using namespace lldb_private;
using namespace minidump;
@@ -27,47 +30,11 @@ MinidumpParser::Create(const lldb::DataBufferSP &data_buf_sp) {
if (data_buf_sp->GetByteSize() < sizeof(MinidumpHeader)) {
return llvm::None;
}
-
- llvm::ArrayRef<uint8_t> header_data(data_buf_sp->GetBytes(),
- sizeof(MinidumpHeader));
- const MinidumpHeader *header = MinidumpHeader::Parse(header_data);
-
- if (header == nullptr) {
- return llvm::None;
- }
-
- lldb::offset_t directory_list_offset = header->stream_directory_rva;
- // check if there is enough data for the parsing of the directory list
- if ((directory_list_offset +
- sizeof(MinidumpDirectory) * header->streams_count) >
- data_buf_sp->GetByteSize()) {
- return llvm::None;
- }
-
- const MinidumpDirectory *directory = nullptr;
- Status error;
- llvm::ArrayRef<uint8_t> directory_data(
- data_buf_sp->GetBytes() + directory_list_offset,
- sizeof(MinidumpDirectory) * header->streams_count);
- llvm::DenseMap<uint32_t, MinidumpLocationDescriptor> directory_map;
-
- for (uint32_t i = 0; i < header->streams_count; ++i) {
- error = consumeObject(directory_data, directory);
- if (error.Fail()) {
- return llvm::None;
- }
- directory_map[static_cast<const uint32_t>(directory->stream_type)] =
- directory->location;
- }
-
- return MinidumpParser(data_buf_sp, header, std::move(directory_map));
+ return MinidumpParser(data_buf_sp);
}
-MinidumpParser::MinidumpParser(
- const lldb::DataBufferSP &data_buf_sp, const MinidumpHeader *header,
- llvm::DenseMap<uint32_t, MinidumpLocationDescriptor> &&directory_map)
- : m_data_sp(data_buf_sp), m_header(header), m_directory_map(directory_map) {
-}
+MinidumpParser::MinidumpParser(const lldb::DataBufferSP &data_buf_sp)
+ : m_data_sp(data_buf_sp) {}
llvm::ArrayRef<uint8_t> MinidumpParser::GetData() {
return llvm::ArrayRef<uint8_t>(m_data_sp->GetBytes(),
@@ -96,6 +63,31 @@ llvm::Optional<std::string> MinidumpParser::GetMinidumpString(uint32_t rva) {
return parseMinidumpString(arr_ref);
}
+UUID MinidumpParser::GetModuleUUID(const MinidumpModule *module) {
+ auto cv_record =
+ GetData().slice(module->CV_record.rva, module->CV_record.data_size);
+
+ // Read the CV record signature
+ const llvm::support::ulittle32_t *signature = nullptr;
+ Status error = consumeObject(cv_record, signature);
+ if (error.Fail())
+ return UUID();
+
+ const CvSignature cv_signature =
+ static_cast<CvSignature>(static_cast<const uint32_t>(*signature));
+
+ if (cv_signature == CvSignature::Pdb70) {
+ // PDB70 record
+ const CvRecordPdb70 *pdb70_uuid = nullptr;
+ Status error = consumeObject(cv_record, pdb70_uuid);
+ if (!error.Fail())
+ return UUID::fromData(pdb70_uuid, sizeof(*pdb70_uuid));
+ } else if (cv_signature == CvSignature::ElfBuildId)
+ return UUID::fromData(cv_record);
+
+ return UUID();
+}
+
llvm::ArrayRef<MinidumpThread> MinidumpParser::GetThreads() {
llvm::ArrayRef<uint8_t> data = GetStream(MinidumpStreamType::ThreadList);
@@ -115,12 +107,12 @@ MinidumpParser::GetThreadContext(const MinidumpThread &td) {
llvm::ArrayRef<uint8_t>
MinidumpParser::GetThreadContextWow64(const MinidumpThread &td) {
- // On Windows, a 32-bit process can run on a 64-bit machine under
- // WOW64. If the minidump was captured with a 64-bit debugger, then
- // the CONTEXT we just grabbed from the mini_dump_thread is the one
- // for the 64-bit "native" process rather than the 32-bit "guest"
- // process we care about. In this case, we can get the 32-bit CONTEXT
- // from the TEB (Thread Environment Block) of the 64-bit process.
+ // On Windows, a 32-bit process can run on a 64-bit machine under WOW64. If
+ // the minidump was captured with a 64-bit debugger, then the CONTEXT we just
+ // grabbed from the mini_dump_thread is the one for the 64-bit "native"
+ // process rather than the 32-bit "guest" process we care about. In this
+ // case, we can get the 32-bit CONTEXT from the TEB (Thread Environment
+ // Block) of the 64-bit process.
auto teb_mem = GetMemory(td.teb, sizeof(TEB64));
if (teb_mem.empty())
return {};
@@ -130,9 +122,9 @@ MinidumpParser::GetThreadContextWow64(const MinidumpThread &td) {
if (error.Fail())
return {};
- // Slot 1 of the thread-local storage in the 64-bit TEB points to a
- // structure that includes the 32-bit CONTEXT (after a ULONG).
- // See: https://msdn.microsoft.com/en-us/library/ms681670.aspx
+ // Slot 1 of the thread-local storage in the 64-bit TEB points to a structure
+ // that includes the 32-bit CONTEXT (after a ULONG). See:
+ // https://msdn.microsoft.com/en-us/library/ms681670.aspx
auto context =
GetMemory(wow64teb->tls_slots[1] + 4, sizeof(MinidumpContext_x86_32));
if (context.size() < sizeof(MinidumpContext_x86_32))
@@ -334,10 +326,10 @@ MinidumpParser::FindMemoryRange(lldb::addr_t addr) {
}
}
- // Some Minidumps have a Memory64ListStream that captures all the heap
- // memory (full-memory Minidumps). We can't exactly use the same loop as
- // above, because the Minidump uses slightly different data structures to
- // describe those
+ // Some Minidumps have a Memory64ListStream that captures all the heap memory
+ // (full-memory Minidumps). We can't exactly use the same loop as above,
+ // because the Minidump uses slightly different data structures to describe
+ // those
if (!data64.empty()) {
llvm::ArrayRef<MinidumpMemoryDescriptor64> memory64_list;
@@ -377,8 +369,8 @@ llvm::ArrayRef<uint8_t> MinidumpParser::GetMemory(lldb::addr_t addr,
return {};
// There's at least some overlap between the beginning of the desired range
- // (addr) and the current range. Figure out where the overlap begins and
- // how much overlap there is.
+ // (addr) and the current range. Figure out where the overlap begins and how
+ // much overlap there is.
const size_t offset = addr - range->start;
@@ -456,3 +448,109 @@ MinidumpParser::GetMemoryRegionInfo(lldb::addr_t load_addr) {
// appear truncated.
return info;
}
+
+Status MinidumpParser::Initialize() {
+ Status error;
+
+ lldbassert(m_directory_map.empty());
+
+ llvm::ArrayRef<uint8_t> header_data(m_data_sp->GetBytes(),
+ sizeof(MinidumpHeader));
+ const MinidumpHeader *header = MinidumpHeader::Parse(header_data);
+ if (header == nullptr) {
+ error.SetErrorString("invalid minidump: can't parse the header");
+ return error;
+ }
+
+ // A minidump without at least one stream is clearly ill-formed
+ if (header->streams_count == 0) {
+ error.SetErrorString("invalid minidump: no streams present");
+ return error;
+ }
+
+ struct FileRange {
+ uint32_t offset = 0;
+ uint32_t size = 0;
+
+ FileRange(uint32_t offset, uint32_t size) : offset(offset), size(size) {}
+ uint32_t end() const { return offset + size; }
+ };
+
+ const uint32_t file_size = m_data_sp->GetByteSize();
+
+ // Build a global minidump file map, checking for:
+ // - overlapping streams/data structures
+ // - truncation (streams pointing past the end of file)
+ std::vector<FileRange> minidump_map;
+
+ // Add the minidump header to the file map
+ if (sizeof(MinidumpHeader) > file_size) {
+ error.SetErrorString("invalid minidump: truncated header");
+ return error;
+ }
+ minidump_map.emplace_back( 0, sizeof(MinidumpHeader) );
+
+ // Add the directory entries to the file map
+ FileRange directory_range(header->stream_directory_rva,
+ header->streams_count *
+ sizeof(MinidumpDirectory));
+ if (directory_range.end() > file_size) {
+ error.SetErrorString("invalid minidump: truncated streams directory");
+ return error;
+ }
+ minidump_map.push_back(directory_range);
+
+ // Parse stream directory entries
+ llvm::ArrayRef<uint8_t> directory_data(
+ m_data_sp->GetBytes() + directory_range.offset, directory_range.size);
+ for (uint32_t i = 0; i < header->streams_count; ++i) {
+ const MinidumpDirectory *directory_entry = nullptr;
+ error = consumeObject(directory_data, directory_entry);
+ if (error.Fail())
+ return error;
+ if (directory_entry->stream_type == 0) {
+ // Ignore dummy streams (technically ill-formed, but a number of
+ // existing minidumps seem to contain such streams)
+ if (directory_entry->location.data_size == 0)
+ continue;
+ error.SetErrorString("invalid minidump: bad stream type");
+ return error;
+ }
+ // Update the streams map, checking for duplicate stream types
+ if (!m_directory_map
+ .insert({directory_entry->stream_type, directory_entry->location})
+ .second) {
+ error.SetErrorString("invalid minidump: duplicate stream type");
+ return error;
+ }
+ // Ignore the zero-length streams for layout checks
+ if (directory_entry->location.data_size != 0) {
+ minidump_map.emplace_back(directory_entry->location.rva,
+ directory_entry->location.data_size);
+ }
+ }
+
+ // Sort the file map ranges by start offset
+ std::sort(minidump_map.begin(), minidump_map.end(),
+ [](const FileRange &a, const FileRange &b) {
+ return a.offset < b.offset;
+ });
+
+ // Check for overlapping streams/data structures
+ for (size_t i = 1; i < minidump_map.size(); ++i) {
+ const auto &prev_range = minidump_map[i - 1];
+ if (prev_range.end() > minidump_map[i].offset) {
+ error.SetErrorString("invalid minidump: overlapping streams");
+ return error;
+ }
+ }
+
+ // Check for streams past the end of file
+ const auto &last_range = minidump_map.back();
+ if (last_range.end() > file_size) {
+ error.SetErrorString("invalid minidump: truncated stream");
+ return error;
+ }
+
+ return error;
+}
diff --git a/source/Plugins/Process/minidump/MinidumpParser.h b/source/Plugins/Process/minidump/MinidumpParser.h
index b7329ffc0028..49b1eef14de5 100644
--- a/source/Plugins/Process/minidump/MinidumpParser.h
+++ b/source/Plugins/Process/minidump/MinidumpParser.h
@@ -17,6 +17,7 @@
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/Status.h"
+#include "lldb/Utility/UUID.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
@@ -54,6 +55,8 @@ public:
llvm::Optional<std::string> GetMinidumpString(uint32_t rva);
+ UUID GetModuleUUID(const MinidumpModule* module);
+
llvm::ArrayRef<MinidumpThread> GetThreads();
llvm::ArrayRef<uint8_t> GetThreadContext(const MinidumpThread &td);
@@ -86,14 +89,15 @@ public:
llvm::Optional<MemoryRegionInfo> GetMemoryRegionInfo(lldb::addr_t);
+ // Perform consistency checks and initialize internal data structures
+ Status Initialize();
+
+private:
+ MinidumpParser(const lldb::DataBufferSP &data_buf_sp);
+
private:
lldb::DataBufferSP m_data_sp;
- const MinidumpHeader *m_header;
llvm::DenseMap<uint32_t, MinidumpLocationDescriptor> m_directory_map;
-
- MinidumpParser(
- const lldb::DataBufferSP &data_buf_sp, const MinidumpHeader *header,
- llvm::DenseMap<uint32_t, MinidumpLocationDescriptor> &&directory_map);
};
} // end namespace minidump
diff --git a/source/Plugins/Process/minidump/MinidumpTypes.cpp b/source/Plugins/Process/minidump/MinidumpTypes.cpp
index 24ce3f94c094..049704ba80ca 100644
--- a/source/Plugins/Process/minidump/MinidumpTypes.cpp
+++ b/source/Plugins/Process/minidump/MinidumpTypes.cpp
@@ -33,9 +33,6 @@ const MinidumpHeader *MinidumpHeader::Parse(llvm::ArrayRef<uint8_t> &data) {
version != MinidumpHeaderConstants::Version)
return nullptr;
- // TODO check for max number of streams ?
- // TODO more sanity checks ?
-
return header;
}
@@ -44,19 +41,23 @@ llvm::Optional<std::string>
lldb_private::minidump::parseMinidumpString(llvm::ArrayRef<uint8_t> &data) {
std::string result;
- const uint32_t *source_length;
- Status error = consumeObject(data, source_length);
- if (error.Fail() || *source_length > data.size() || *source_length % 2 != 0)
+ const uint32_t *source_length_ptr;
+ Status error = consumeObject(data, source_length_ptr);
+
+ // Copy non-aligned source_length data into aligned memory.
+ uint32_t source_length;
+ std::memcpy(&source_length, source_length_ptr, sizeof(source_length));
+
+ if (error.Fail() || source_length > data.size() || source_length % 2 != 0)
return llvm::None;
auto source_start = reinterpret_cast<const llvm::UTF16 *>(data.data());
- // source_length is the length of the string in bytes
- // we need the length of the string in UTF-16 characters/code points (16 bits
- // per char)
- // that's why it's divided by 2
- const auto source_end = source_start + (*source_length) / 2;
+ // source_length is the length of the string in bytes we need the length of
+ // the string in UTF-16 characters/code points (16 bits per char) that's why
+ // it's divided by 2
+ const auto source_end = source_start + source_length / 2;
// resize to worst case length
- result.resize(UNI_MAX_UTF8_BYTES_PER_CODE_POINT * (*source_length) / 2);
+ result.resize(UNI_MAX_UTF8_BYTES_PER_CODE_POINT * source_length / 2);
auto result_start = reinterpret_cast<llvm::UTF8 *>(&result[0]);
const auto result_end = result_start + result.size();
llvm::ConvertUTF16toUTF8(&source_start, source_end, &result_start, result_end,
@@ -80,11 +81,17 @@ const MinidumpThread *MinidumpThread::Parse(llvm::ArrayRef<uint8_t> &data) {
llvm::ArrayRef<MinidumpThread>
MinidumpThread::ParseThreadList(llvm::ArrayRef<uint8_t> &data) {
+ const auto orig_size = data.size();
const llvm::support::ulittle32_t *thread_count;
Status error = consumeObject(data, thread_count);
if (error.Fail() || *thread_count * sizeof(MinidumpThread) > data.size())
return {};
+ // Compilers might end up padding an extra 4 bytes depending on how the
+ // structure is padded by the compiler and the #pragma pack settings.
+ if (4 + *thread_count * sizeof(MinidumpThread) < orig_size)
+ data = data.drop_front(4);
+
return llvm::ArrayRef<MinidumpThread>(
reinterpret_cast<const MinidumpThread *>(data.data()), *thread_count);
}
@@ -156,12 +163,17 @@ const MinidumpModule *MinidumpModule::Parse(llvm::ArrayRef<uint8_t> &data) {
llvm::ArrayRef<MinidumpModule>
MinidumpModule::ParseModuleList(llvm::ArrayRef<uint8_t> &data) {
-
+ const auto orig_size = data.size();
const llvm::support::ulittle32_t *modules_count;
Status error = consumeObject(data, modules_count);
if (error.Fail() || *modules_count * sizeof(MinidumpModule) > data.size())
return {};
-
+
+ // Compilers might end up padding an extra 4 bytes depending on how the
+ // structure is padded by the compiler and the #pragma pack settings.
+ if (4 + *modules_count * sizeof(MinidumpModule) < orig_size)
+ data = data.drop_front(4);
+
return llvm::ArrayRef<MinidumpModule>(
reinterpret_cast<const MinidumpModule *>(data.data()), *modules_count);
}
@@ -179,11 +191,17 @@ MinidumpExceptionStream::Parse(llvm::ArrayRef<uint8_t> &data) {
llvm::ArrayRef<MinidumpMemoryDescriptor>
MinidumpMemoryDescriptor::ParseMemoryList(llvm::ArrayRef<uint8_t> &data) {
+ const auto orig_size = data.size();
const llvm::support::ulittle32_t *mem_ranges_count;
Status error = consumeObject(data, mem_ranges_count);
if (error.Fail() ||
*mem_ranges_count * sizeof(MinidumpMemoryDescriptor) > data.size())
return {};
+
+ // Compilers might end up padding an extra 4 bytes depending on how the
+ // structure is padded by the compiler and the #pragma pack settings.
+ if (4 + *mem_ranges_count * sizeof(MinidumpMemoryDescriptor) < orig_size)
+ data = data.drop_front(4);
return llvm::makeArrayRef(
reinterpret_cast<const MinidumpMemoryDescriptor *>(data.data()),
diff --git a/source/Plugins/Process/minidump/MinidumpTypes.h b/source/Plugins/Process/minidump/MinidumpTypes.h
index 6de4f55a769d..e83089865b9e 100644
--- a/source/Plugins/Process/minidump/MinidumpTypes.h
+++ b/source/Plugins/Process/minidump/MinidumpTypes.h
@@ -43,6 +43,21 @@ enum class MinidumpHeaderConstants : uint32_t {
};
+enum class CvSignature : uint32_t {
+ Pdb70 = 0x53445352, // RSDS
+ ElfBuildId = 0x4270454c, // BpEL (Breakpad/Crashpad minidumps)
+};
+
+// Reference:
+// https://crashpad.chromium.org/doxygen/structcrashpad_1_1CodeViewRecordPDB70.html
+struct CvRecordPdb70 {
+ uint8_t Uuid[16];
+ llvm::support::ulittle32_t Age;
+ // char PDBFileName[];
+};
+static_assert(sizeof(CvRecordPdb70) == 20,
+ "sizeof CvRecordPdb70 is not correct!");
+
// Reference:
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680394.aspx
enum class MinidumpStreamType : uint32_t {
diff --git a/source/Plugins/Process/minidump/ProcessMinidump.cpp b/source/Plugins/Process/minidump/ProcessMinidump.cpp
index d4d65c044eab..b43f22382eac 100644
--- a/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -19,6 +19,7 @@
#include "lldb/Core/State.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/DataBufferLLVM.h"
@@ -31,9 +32,56 @@
// C includes
// C++ includes
+using namespace lldb;
using namespace lldb_private;
using namespace minidump;
+//------------------------------------------------------------------
+/// A placeholder module used for minidumps, where the original
+/// object files may not be available (so we can't parse the object
+/// files to extract the set of sections/segments)
+///
+/// This placeholder module has a single synthetic section (.module_image)
+/// which represents the module memory range covering the whole module.
+//------------------------------------------------------------------
+class PlaceholderModule : public Module {
+public:
+ PlaceholderModule(const ModuleSpec &module_spec) :
+ Module(module_spec.GetFileSpec(), module_spec.GetArchitecture()) {
+ if (module_spec.GetUUID().IsValid())
+ SetUUID(module_spec.GetUUID());
+ }
+
+ // Creates a synthetic module section covering the whole module image (and
+ // sets the section load address as well)
+ void CreateImageSection(const MinidumpModule *module, Target& target) {
+ const ConstString section_name(".module_image");
+ lldb::SectionSP section_sp(new Section(
+ shared_from_this(), // Module to which this section belongs.
+ nullptr, // ObjectFile
+ 0, // Section ID.
+ section_name, // Section name.
+ eSectionTypeContainer, // Section type.
+ module->base_of_image, // VM address.
+ module->size_of_image, // VM size in bytes of this section.
+ 0, // Offset of this section in the file.
+ module->size_of_image, // Size of the section as found in the file.
+ 12, // Alignment of the section (log2)
+ 0, // Flags for this section.
+ 1)); // Number of host bytes per target byte
+ section_sp->SetPermissions(ePermissionsExecutable | ePermissionsReadable);
+ GetSectionList()->AddSection(section_sp);
+ target.GetSectionLoadList().SetSectionLoadAddress(
+ section_sp, module->base_of_image);
+ }
+
+ ObjectFile *GetObjectFile() override { return nullptr; }
+
+ SectionList *GetSectionList() override {
+ return Module::GetUnifiedSectionList();
+ }
+};
+
ConstString ProcessMinidump::GetPluginNameStatic() {
static ConstString g_name("minidump");
return g_name;
@@ -57,7 +105,7 @@ lldb::ProcessSP ProcessMinidump::CreateInstance(lldb::TargetSP target_sp,
if (!DataPtr)
return nullptr;
- assert(DataPtr->GetByteSize() == header_size);
+ lldbassert(DataPtr->GetByteSize() == header_size);
// first, only try to parse the header, beacuse we need to be fast
llvm::ArrayRef<uint8_t> HeaderBytes = DataPtr->GetData();
@@ -92,10 +140,10 @@ ProcessMinidump::ProcessMinidump(lldb::TargetSP target_sp,
ProcessMinidump::~ProcessMinidump() {
Clear();
- // We need to call finalize on the process before destroying ourselves
- // to make sure all of the broadcaster cleanup goes as planned. If we
- // destruct this class, then Process::~Process() might have problems
- // trying to fully destroy the broadcaster.
+ // We need to call finalize on the process before destroying ourselves to
+ // make sure all of the broadcaster cleanup goes as planned. If we destruct
+ // this class, then Process::~Process() might have problems trying to fully
+ // destroy the broadcaster.
Finalize();
}
@@ -116,10 +164,29 @@ void ProcessMinidump::Terminate() {
Status ProcessMinidump::DoLoadCore() {
Status error;
+ // Minidump parser initialization & consistency checks
+ error = m_minidump_parser.Initialize();
+ if (error.Fail())
+ return error;
+
+ // Do we support the minidump's architecture?
+ ArchSpec arch = GetArchitecture();
+ switch (arch.GetMachine()) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ // supported
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("unsupported minidump architecture: %s",
+ arch.GetArchitectureName());
+ return error;
+ }
+
m_thread_list = m_minidump_parser.GetThreads();
m_active_exception = m_minidump_parser.GetExceptionStream();
ReadModuleList();
- GetTarget().SetArchitecture(GetArchitecture());
+ GetTarget().SetArchitecture(arch);
llvm::Optional<lldb::pid_t> pid = m_minidump_parser.GetPid();
if (!pid) {
@@ -185,8 +252,8 @@ bool ProcessMinidump::WarnBeforeDetach() const { return false; }
size_t ProcessMinidump::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
Status &error) {
- // Don't allow the caching that lldb_private::Process::ReadMemory does
- // since we have it all cached in our dump file anyway.
+ // Don't allow the caching that lldb_private::Process::ReadMemory does since
+ // we have it all cached in our dump file anyway.
return DoReadMemory(addr, buf, size, error);
}
@@ -276,12 +343,25 @@ void ProcessMinidump::ReadModuleList() {
m_is_wow64 = true;
}
- const auto file_spec = FileSpec(name.getValue(), true);
- ModuleSpec module_spec = file_spec;
+ const auto uuid = m_minidump_parser.GetModuleUUID(module);
+ const auto file_spec =
+ FileSpec(name.getValue(), true, GetArchitecture().GetTriple());
+ ModuleSpec module_spec(file_spec, uuid);
Status error;
lldb::ModuleSP module_sp = GetTarget().GetSharedModule(module_spec, &error);
if (!module_sp || error.Fail()) {
- continue;
+ // We failed to locate a matching local object file. Fortunately, the
+ // minidump format encodes enough information about each module's memory
+ // range to allow us to create placeholder modules.
+ //
+ // This enables most LLDB functionality involving address-to-module
+ // translations (ex. identifing the module for a stack frame PC) and
+ // modules/sections commands (ex. target modules list, ...)
+ auto placeholder_module =
+ std::make_shared<PlaceholderModule>(module_spec);
+ placeholder_module->CreateImageSection(module, GetTarget());
+ module_sp = placeholder_module;
+ GetTarget().GetImages().Append(module_sp);
}
if (log) {
diff --git a/source/Plugins/Process/minidump/ProcessMinidump.h b/source/Plugins/Process/minidump/ProcessMinidump.h
index 4b91d1ba396a..d65ada9009a7 100644
--- a/source/Plugins/Process/minidump/ProcessMinidump.h
+++ b/source/Plugins/Process/minidump/ProcessMinidump.h
@@ -61,6 +61,8 @@ public:
uint32_t GetPluginVersion() override;
+ SystemRuntime *GetSystemRuntime() override { return nullptr; }
+
Status DoDestroy() override;
void RefreshStateAfterStop() override;
diff --git a/source/Plugins/ScriptInterpreter/CMakeLists.txt b/source/Plugins/ScriptInterpreter/CMakeLists.txt
index dc2a27d95a31..5d8642eb07e6 100644
--- a/source/Plugins/ScriptInterpreter/CMakeLists.txt
+++ b/source/Plugins/ScriptInterpreter/CMakeLists.txt
@@ -1,2 +1,4 @@
add_subdirectory(None)
-add_subdirectory(Python)
+if (NOT LLDB_DISABLE_PYTHON)
+ add_subdirectory(Python)
+endif()
diff --git a/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp b/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
index 9ec9f4344613..4bd4c6a029a0 100644
--- a/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
+++ b/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
@@ -27,7 +27,7 @@ ScriptInterpreterNone::ScriptInterpreterNone(CommandInterpreter &interpreter)
ScriptInterpreterNone::~ScriptInterpreterNone() {}
-bool ScriptInterpreterNone::ExecuteOneLine(const char *command,
+bool ScriptInterpreterNone::ExecuteOneLine(llvm::StringRef command,
CommandReturnObject *,
const ExecuteScriptOptions &) {
m_interpreter.GetDebugger().GetErrorFile()->PutCString(
diff --git a/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h b/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h
index d66b2f07310c..824579472b5e 100644
--- a/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h
+++ b/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h
@@ -25,7 +25,7 @@ public:
~ScriptInterpreterNone() override;
bool ExecuteOneLine(
- const char *command, CommandReturnObject *result,
+ llvm::StringRef command, CommandReturnObject *result,
const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
void ExecuteInterpreterLoop() override;
diff --git a/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt b/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt
index c337fc7b5874..56eacc941d64 100644
--- a/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt
+++ b/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt
@@ -1,3 +1,16 @@
+if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows")
+ # Call a python script to gather the arch-specific libdir for
+ # modules like the lldb module.
+ execute_process(
+ COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../../../../scripts/get_relative_lib_dir.py
+ RESULT_VARIABLE get_libdir_status
+ OUTPUT_VARIABLE relative_libdir
+ )
+ if (get_libdir_status EQUAL 0)
+ add_definitions(-DLLDB_PYTHON_RELATIVE_LIBDIR="${relative_libdir}")
+ endif()
+endif()
+
add_lldb_library(lldbPluginScriptInterpreterPython PLUGIN
PythonDataObjects.cpp
PythonExceptionState.cpp
diff --git a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
index 966bdff3ad95..90d8ab97fb73 100644
--- a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -1,5 +1,4 @@
-//===-- PythonDataObjects.cpp ------------------------------------*- C++
-//-*-===//
+//===-- PythonDataObjects.cpp -----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -123,21 +122,20 @@ PythonObject::ResolveNameWithDictionary(llvm::StringRef name,
}
PythonObject PythonObject::ResolveName(llvm::StringRef name) const {
- // Resolve the name in the context of the specified object. If,
- // for example, `this` refers to a PyModule, then this will look for
- // `name` in this module. If `this` refers to a PyType, then it will
- // resolve `name` as an attribute of that type. If `this` refers to
- // an instance of an object, then it will resolve `name` as the value
- // of the specified field.
+ // Resolve the name in the context of the specified object. If, for example,
+ // `this` refers to a PyModule, then this will look for `name` in this
+ // module. If `this` refers to a PyType, then it will resolve `name` as an
+ // attribute of that type. If `this` refers to an instance of an object,
+ // then it will resolve `name` as the value of the specified field.
//
// This function handles dotted names so that, for example, if `m_py_obj`
- // refers to the `sys` module, and `name` == "path.append", then it
- // will find the function `sys.path.append`.
+ // refers to the `sys` module, and `name` == "path.append", then it will find
+ // the function `sys.path.append`.
size_t dot_pos = name.find_first_of('.');
if (dot_pos == llvm::StringRef::npos) {
- // No dots in the name, we should be able to find the value immediately
- // as an attribute of `m_py_obj`.
+ // No dots in the name, we should be able to find the value immediately as
+ // an attribute of `m_py_obj`.
return GetAttributeValue(name);
}
@@ -230,8 +228,8 @@ bool PythonBytes::Check(PyObject *py_obj) {
}
void PythonBytes::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting
- // `py_obj` it still gets decremented if necessary.
+ // Grab the desired reference type so that if we end up rejecting `py_obj` it
+ // still gets decremented if necessary.
PythonObject result(type, py_obj);
if (!PythonBytes::Check(py_obj)) {
@@ -240,8 +238,7 @@ void PythonBytes::Reset(PyRefType type, PyObject *py_obj) {
}
// Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls
- // back into the virtual implementation.
+ // overflow since it calls back into the virtual implementation.
PythonObject::Reset(PyRefType::Borrowed, result.get());
}
@@ -303,8 +300,8 @@ bool PythonByteArray::Check(PyObject *py_obj) {
}
void PythonByteArray::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting
- // `py_obj` it still gets decremented if necessary.
+ // Grab the desired reference type so that if we end up rejecting `py_obj` it
+ // still gets decremented if necessary.
PythonObject result(type, py_obj);
if (!PythonByteArray::Check(py_obj)) {
@@ -313,8 +310,7 @@ void PythonByteArray::Reset(PyRefType type, PyObject *py_obj) {
}
// Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls
- // back into the virtual implementation.
+ // overflow since it calls back into the virtual implementation.
PythonObject::Reset(PyRefType::Borrowed, result.get());
}
@@ -378,8 +374,8 @@ bool PythonString::Check(PyObject *py_obj) {
}
void PythonString::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting
- // `py_obj` it still gets decremented if necessary.
+ // Grab the desired reference type so that if we end up rejecting `py_obj` it
+ // still gets decremented if necessary.
PythonObject result(type, py_obj);
if (!PythonString::Check(py_obj)) {
@@ -394,8 +390,7 @@ void PythonString::Reset(PyRefType type, PyObject *py_obj) {
result.Reset(PyRefType::Owned, PyUnicode_AsUTF8String(result.get()));
#endif
// Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls
- // back into the virtual implementation.
+ // overflow since it calls back into the virtual implementation.
PythonObject::Reset(PyRefType::Borrowed, result.get());
}
@@ -404,14 +399,16 @@ llvm::StringRef PythonString::GetString() const {
return llvm::StringRef();
Py_ssize_t size;
- char *c;
+ const char *data;
#if PY_MAJOR_VERSION >= 3
- c = PyUnicode_AsUTF8AndSize(m_py_obj, &size);
+ data = PyUnicode_AsUTF8AndSize(m_py_obj, &size);
#else
+ char *c;
PyString_AsStringAndSize(m_py_obj, &c, &size);
+ data = c;
#endif
- return llvm::StringRef(c, size);
+ return llvm::StringRef(data, size);
}
size_t PythonString::GetSize() const {
@@ -466,8 +463,8 @@ bool PythonInteger::Check(PyObject *py_obj) {
return false;
#if PY_MAJOR_VERSION >= 3
- // Python 3 does not have PyInt_Check. There is only one type of
- // integral value, long.
+ // Python 3 does not have PyInt_Check. There is only one type of integral
+ // value, long.
return PyLong_Check(py_obj);
#else
return PyLong_Check(py_obj) || PyInt_Check(py_obj);
@@ -475,8 +472,8 @@ bool PythonInteger::Check(PyObject *py_obj) {
}
void PythonInteger::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting
- // `py_obj` it still gets decremented if necessary.
+ // Grab the desired reference type so that if we end up rejecting `py_obj` it
+ // still gets decremented if necessary.
PythonObject result(type, py_obj);
if (!PythonInteger::Check(py_obj)) {
@@ -485,13 +482,13 @@ void PythonInteger::Reset(PyRefType type, PyObject *py_obj) {
}
#if PY_MAJOR_VERSION < 3
- // Always store this as a PyLong, which makes interoperability between
- // Python 2.x and Python 3.x easier. This is only necessary in 2.x,
- // since 3.x doesn't even have a PyInt.
+ // Always store this as a PyLong, which makes interoperability between Python
+ // 2.x and Python 3.x easier. This is only necessary in 2.x, since 3.x
+ // doesn't even have a PyInt.
if (PyInt_Check(py_obj)) {
// Since we converted the original object to a different type, the new
- // object is an owned object regardless of the ownership semantics requested
- // by the user.
+ // object is an owned object regardless of the ownership semantics
+ // requested by the user.
result.Reset(PyRefType::Owned, PyLong_FromLongLong(PyInt_AsLong(py_obj)));
}
#endif
@@ -500,8 +497,7 @@ void PythonInteger::Reset(PyRefType type, PyObject *py_obj) {
"Couldn't get a PyLong from this PyObject");
// Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls
- // back into the virtual implementation.
+ // overflow since it calls back into the virtual implementation.
PythonObject::Reset(PyRefType::Borrowed, result.get());
}
@@ -513,10 +509,9 @@ int64_t PythonInteger::GetInteger() const {
int overflow = 0;
int64_t result = PyLong_AsLongLongAndOverflow(m_py_obj, &overflow);
if (overflow != 0) {
- // We got an integer that overflows, like 18446744072853913392L
- // we can't use PyLong_AsLongLong() as it will return
- // 0xffffffffffffffff. If we use the unsigned long long
- // it will work as expected.
+ // We got an integer that overflows, like 18446744072853913392L we can't
+ // use PyLong_AsLongLong() as it will return 0xffffffffffffffff. If we
+ // use the unsigned long long it will work as expected.
const uint64_t uval = PyLong_AsUnsignedLongLong(m_py_obj);
result = static_cast<int64_t>(uval);
}
@@ -563,8 +558,8 @@ bool PythonList::Check(PyObject *py_obj) {
}
void PythonList::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting
- // `py_obj` it still gets decremented if necessary.
+ // Grab the desired reference type so that if we end up rejecting `py_obj` it
+ // still gets decremented if necessary.
PythonObject result(type, py_obj);
if (!PythonList::Check(py_obj)) {
@@ -573,8 +568,7 @@ void PythonList::Reset(PyRefType type, PyObject *py_obj) {
}
// Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls
- // back into the virtual implementation.
+ // overflow since it calls back into the virtual implementation.
PythonObject::Reset(PyRefType::Borrowed, result.get());
}
@@ -668,8 +662,8 @@ bool PythonTuple::Check(PyObject *py_obj) {
}
void PythonTuple::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting
- // `py_obj` it still gets decremented if necessary.
+ // Grab the desired reference type so that if we end up rejecting `py_obj` it
+ // still gets decremented if necessary.
PythonObject result(type, py_obj);
if (!PythonTuple::Check(py_obj)) {
@@ -678,8 +672,7 @@ void PythonTuple::Reset(PyRefType type, PyObject *py_obj) {
}
// Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls
- // back into the virtual implementation.
+ // overflow since it calls back into the virtual implementation.
PythonObject::Reset(PyRefType::Borrowed, result.get());
}
@@ -741,8 +734,8 @@ bool PythonDictionary::Check(PyObject *py_obj) {
}
void PythonDictionary::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting
- // `py_obj` it still gets decremented if necessary.
+ // Grab the desired reference type so that if we end up rejecting `py_obj` it
+ // still gets decremented if necessary.
PythonObject result(type, py_obj);
if (!PythonDictionary::Check(py_obj)) {
@@ -751,8 +744,7 @@ void PythonDictionary::Reset(PyRefType type, PyObject *py_obj) {
}
// Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls
- // back into the virtual implementation.
+ // overflow since it calls back into the virtual implementation.
PythonObject::Reset(PyRefType::Borrowed, result.get());
}
@@ -833,8 +825,8 @@ bool PythonModule::Check(PyObject *py_obj) {
}
void PythonModule::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting
- // `py_obj` it still gets decremented if necessary.
+ // Grab the desired reference type so that if we end up rejecting `py_obj` it
+ // still gets decremented if necessary.
PythonObject result(type, py_obj);
if (!PythonModule::Check(py_obj)) {
@@ -843,8 +835,7 @@ void PythonModule::Reset(PyRefType type, PyObject *py_obj) {
}
// Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls
- // back into the virtual implementation.
+ // overflow since it calls back into the virtual implementation.
PythonObject::Reset(PyRefType::Borrowed, result.get());
}
@@ -871,8 +862,8 @@ bool PythonCallable::Check(PyObject *py_obj) {
}
void PythonCallable::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting
- // `py_obj` it still gets decremented if necessary.
+ // Grab the desired reference type so that if we end up rejecting `py_obj` it
+ // still gets decremented if necessary.
PythonObject result(type, py_obj);
if (!PythonCallable::Check(py_obj)) {
@@ -881,8 +872,7 @@ void PythonCallable::Reset(PyRefType type, PyObject *py_obj) {
}
// Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls
- // back into the virtual implementation.
+ // overflow since it calls back into the virtual implementation.
PythonObject::Reset(PyRefType::Borrowed, result.get());
}
@@ -963,9 +953,9 @@ bool PythonFile::Check(PyObject *py_obj) {
#else
// In Python 3, there is no `PyFile_Check`, and in fact PyFile is not even a
// first-class object type anymore. `PyFile_FromFd` is just a thin wrapper
- // over `io.open()`, which returns some object derived from `io.IOBase`.
- // As a result, the only way to detect a file in Python 3 is to check whether
- // it inherits from `io.IOBase`. Since it is possible for non-files to also
+ // over `io.open()`, which returns some object derived from `io.IOBase`. As a
+ // result, the only way to detect a file in Python 3 is to check whether it
+ // inherits from `io.IOBase`. Since it is possible for non-files to also
// inherit from `io.IOBase`, we additionally verify that it has the `fileno`
// attribute, which should guarantee that it is backed by the file system.
PythonObject io_module(PyRefType::Owned, PyImport_ImportModule("io"));
@@ -985,8 +975,8 @@ bool PythonFile::Check(PyObject *py_obj) {
}
void PythonFile::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting
- // `py_obj` it still gets decremented if necessary.
+ // Grab the desired reference type so that if we end up rejecting `py_obj` it
+ // still gets decremented if necessary.
PythonObject result(type, py_obj);
if (!PythonFile::Check(py_obj)) {
diff --git a/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp b/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp
index 4d956d5dbe14..d28a8033820a 100644
--- a/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp
+++ b/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp
@@ -30,9 +30,9 @@ PythonExceptionState::~PythonExceptionState() {
}
void PythonExceptionState::Acquire(bool restore_on_exit) {
- // If a state is already acquired, the user needs to decide whether they
- // want to discard or restore it. Don't allow the potential silent
- // loss of a valid state.
+ // If a state is already acquired, the user needs to decide whether they want
+ // to discard or restore it. Don't allow the potential silent loss of a
+ // valid state.
assert(!IsError());
if (!HasErrorOccurred())
@@ -45,8 +45,7 @@ void PythonExceptionState::Acquire(bool restore_on_exit) {
// PyErr_Fetch clears the error flag.
assert(!HasErrorOccurred());
- // Ownership of the objects returned by `PyErr_Fetch` is transferred
- // to us.
+ // Ownership of the objects returned by `PyErr_Fetch` is transferred to us.
m_type.Reset(PyRefType::Owned, py_type);
m_value.Reset(PyRefType::Owned, py_value);
m_traceback.Reset(PyRefType::Owned, py_traceback);
@@ -56,14 +55,14 @@ void PythonExceptionState::Acquire(bool restore_on_exit) {
void PythonExceptionState::Restore() {
if (m_type.IsValid()) {
// The documentation for PyErr_Restore says "Do not pass a null type and
- // non-null value or traceback. So only restore if type was non-null
- // to begin with. In this case we're passing ownership back to Python
- // so release them all.
+ // non-null value or traceback. So only restore if type was non-null to
+ // begin with. In this case we're passing ownership back to Python so
+ // release them all.
PyErr_Restore(m_type.release(), m_value.release(), m_traceback.release());
}
- // After we restore, we should not hold onto the exception state. Demand that
- // it be re-acquired.
+ // After we restore, we should not hold onto the exception state. Demand
+ // that it be re-acquired.
Discard();
}
@@ -100,10 +99,10 @@ std::string PythonExceptionState::Format() const {
if (!IsError())
return std::string();
- // It's possible that ReadPythonBacktrace generated another exception.
- // If this happens we have to clear the exception, because otherwise
- // PyObject_Str() will assert below. That's why we needed to do the
- // save / restore at the beginning of this function.
+ // It's possible that ReadPythonBacktrace generated another exception. If
+ // this happens we have to clear the exception, because otherwise
+ // PyObject_Str() will assert below. That's why we needed to do the save /
+ // restore at the beginning of this function.
PythonExceptionState bt_error_state(false);
std::string error_string;
@@ -114,8 +113,8 @@ std::string PythonExceptionState::Format() const {
// If we were able to read the backtrace, just append it.
error_stream << backtrace << "\n";
} else {
- // Otherwise, append some information about why we were unable to
- // obtain the backtrace.
+ // Otherwise, append some information about why we were unable to obtain
+ // the backtrace.
PythonString bt_error = bt_error_state.GetValue().Str();
error_stream << "An error occurred while retrieving the backtrace: "
<< bt_error.GetString() << "\n";
diff --git a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 6c39690268c6..b8eb36a2baf6 100644
--- a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -112,13 +112,12 @@ static bool g_initialized = false;
namespace {
-// Initializing Python is not a straightforward process. We cannot control what
-// external code may have done before getting to this point in LLDB, including
-// potentially having already initialized Python, so we need to do a lot of work
-// to ensure that the existing state of the system is maintained across our
-// initialization. We do this by using an RAII pattern where we save off
-// initial
-// state at the beginning, and restore it at the end
+// Initializing Python is not a straightforward process. We cannot control
+// what external code may have done before getting to this point in LLDB,
+// including potentially having already initialized Python, so we need to do a
+// lot of work to ensure that the existing state of the system is maintained
+// across our initialization. We do this by using an RAII pattern where we
+// save off initial state at the beginning, and restore it at the end
struct InitializePythonRAII {
public:
InitializePythonRAII()
@@ -210,12 +209,11 @@ bool ScriptInterpreterPython::Locker::DoAcquireLock() {
LLDB_LOGV(log, "Ensured PyGILState. Previous state = {0}locked",
m_GILState == PyGILState_UNLOCKED ? "un" : "");
- // we need to save the thread state when we first start the command
- // because we might decide to interrupt it while some action is taking
- // place outside of Python (e.g. printing to screen, waiting for the network,
- // ...)
- // in that case, _PyThreadState_Current will be NULL - and we would be unable
- // to set the asynchronous exception - not a desirable situation
+ // we need to save the thread state when we first start the command because
+ // we might decide to interrupt it while some action is taking place outside
+ // of Python (e.g. printing to screen, waiting for the network, ...) in that
+ // case, _PyThreadState_Current will be NULL - and we would be unable to set
+ // the asynchronous exception - not a desirable situation
m_python_interpreter->SetThreadState(PyThreadState_Get());
m_python_interpreter->IncrementLockCount();
return true;
@@ -281,17 +279,16 @@ ScriptInterpreterPython::ScriptInterpreterPython(
PyRun_SimpleString(run_string.GetData());
// Reloading modules requires a different syntax in Python 2 and Python 3.
- // This provides
- // a consistent syntax no matter what version of Python.
+ // This provides a consistent syntax no matter what version of Python.
run_string.Clear();
run_string.Printf("run_one_line (%s, 'from six.moves import reload_module')",
m_dictionary_name.c_str());
PyRun_SimpleString(run_string.GetData());
// WARNING: temporary code that loads Cocoa formatters - this should be done
- // on a per-platform basis rather than loading the whole set
- // and letting the individual formatter classes exploit APIs to check whether
- // they can/cannot do their task
+ // on a per-platform basis rather than loading the whole set and letting the
+ // individual formatter classes exploit APIs to check whether they can/cannot
+ // do their task
run_string.Clear();
run_string.Printf(
"run_one_line (%s, 'import lldb.formatters, lldb.formatters.cpp, pydoc')",
@@ -314,13 +311,11 @@ ScriptInterpreterPython::ScriptInterpreterPython(
}
ScriptInterpreterPython::~ScriptInterpreterPython() {
- // the session dictionary may hold objects with complex state
- // which means that they may need to be torn down with some level of smarts
- // and that, in turn, requires a valid thread state
- // force Python to procure itself such a thread state, nuke the session
- // dictionary
- // and then release it for others to use and proceed with the rest of the
- // shutdown
+ // the session dictionary may hold objects with complex state which means
+ // that they may need to be torn down with some level of smarts and that, in
+ // turn, requires a valid thread state force Python to procure itself such a
+ // thread state, nuke the session dictionary and then release it for others
+ // to use and proceed with the rest of the shutdown
auto gil_state = PyGILState_Ensure();
m_session_dict.Reset();
PyGILState_Release(gil_state);
@@ -352,6 +347,71 @@ const char *ScriptInterpreterPython::GetPluginDescriptionStatic() {
return "Embedded Python interpreter";
}
+void ScriptInterpreterPython::ComputePythonDirForApple(
+ llvm::SmallVectorImpl<char> &path) {
+ auto style = llvm::sys::path::Style::posix;
+
+ llvm::StringRef path_ref(path.begin(), path.size());
+ auto rbegin = llvm::sys::path::rbegin(path_ref, style);
+ auto rend = llvm::sys::path::rend(path_ref);
+ auto framework = std::find(rbegin, rend, "LLDB.framework");
+ if (framework == rend) {
+ ComputePythonDirForPosix(path);
+ return;
+ }
+ path.resize(framework - rend);
+ llvm::sys::path::append(path, style, "LLDB.framework", "Resources", "Python");
+}
+
+void ScriptInterpreterPython::ComputePythonDirForPosix(
+ llvm::SmallVectorImpl<char> &path) {
+ auto style = llvm::sys::path::Style::posix;
+#if defined(LLDB_PYTHON_RELATIVE_LIBDIR)
+ // Build the path by backing out of the lib dir, then building with whatever
+ // the real python interpreter uses. (e.g. lib for most, lib64 on RHEL
+ // x86_64).
+ llvm::sys::path::remove_filename(path, style);
+ llvm::sys::path::append(path, style, LLDB_PYTHON_RELATIVE_LIBDIR);
+#else
+ llvm::sys::path::append(path, style,
+ "python" + llvm::Twine(PY_MAJOR_VERSION) + "." +
+ llvm::Twine(PY_MINOR_VERSION),
+ "site-packages");
+#endif
+}
+
+void ScriptInterpreterPython::ComputePythonDirForWindows(
+ llvm::SmallVectorImpl<char> &path) {
+ auto style = llvm::sys::path::Style::windows;
+ llvm::sys::path::remove_filename(path, style);
+ llvm::sys::path::append(path, style, "lib", "site-packages");
+
+ // This will be injected directly through FileSpec.GetDirectory().SetString(),
+ // so we need to normalize manually.
+ std::replace(path.begin(), path.end(), '\\', '/');
+}
+
+FileSpec ScriptInterpreterPython::GetPythonDir() {
+ static FileSpec g_spec = []() {
+ FileSpec spec = HostInfo::GetShlibDir();
+ if (!spec)
+ return FileSpec();
+ llvm::SmallString<64> path;
+ spec.GetPath(path);
+
+#if defined(__APPLE__)
+ ComputePythonDirForApple(path);
+#elif defined(_WIN32)
+ ComputePythonDirForWindows(path);
+#else
+ ComputePythonDirForPosix(path);
+#endif
+ spec.GetDirectory().SetString(path);
+ return spec;
+ }();
+ return g_spec;
+}
+
lldb_private::ConstString ScriptInterpreterPython::GetPluginName() {
return GetPluginNameStatic();
}
@@ -452,16 +512,16 @@ void ScriptInterpreterPython::ResetOutputFileHandle(FILE *fh) {}
void ScriptInterpreterPython::SaveTerminalState(int fd) {
// Python mucks with the terminal state of STDIN. If we can possibly avoid
// this by setting the file handles up correctly prior to entering the
- // interpreter we should. For now we save and restore the terminal state
- // on the input file handle.
+ // interpreter we should. For now we save and restore the terminal state on
+ // the input file handle.
m_terminal_state.Save(fd, false);
}
void ScriptInterpreterPython::RestoreTerminalState() {
// Python mucks with the terminal state of STDIN. If we can possibly avoid
// this by setting the file handles up correctly prior to entering the
- // interpreter we should. For now we save and restore the terminal state
- // on the input file handle.
+ // interpreter we should. For now we save and restore the terminal state on
+ // the input file handle.
m_terminal_state.Restore();
}
@@ -470,14 +530,11 @@ void ScriptInterpreterPython::LeaveSession() {
if (log)
log->PutCString("ScriptInterpreterPython::LeaveSession()");
- // checking that we have a valid thread state - since we use our own threading
- // and locking
- // in some (rare) cases during cleanup Python may end up believing we have no
- // thread state
- // and PyImport_AddModule will crash if that is the case - since that seems to
- // only happen
- // when destroying the SBDebugger, we can make do without clearing up stdout
- // and stderr
+ // checking that we have a valid thread state - since we use our own
+ // threading and locking in some (rare) cases during cleanup Python may end
+ // up believing we have no thread state and PyImport_AddModule will crash if
+ // that is the case - since that seems to only happen when destroying the
+ // SBDebugger, we can make do without clearing up stdout and stderr
// rdar://problem/11292882
// When the current thread state is NULL, PyThreadState_Get() issues a fatal
@@ -526,8 +583,7 @@ bool ScriptInterpreterPython::SetStdHandle(File &file, const char *py_name,
bool ScriptInterpreterPython::EnterSession(uint16_t on_entry_flags, FILE *in,
FILE *out, FILE *err) {
// If we have already entered the session, without having officially 'left'
- // it, then there is no need to
- // 'enter' it again.
+ // it, then there is no need to 'enter' it again.
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT));
if (m_session_is_active) {
if (log)
@@ -560,8 +616,8 @@ bool ScriptInterpreterPython::EnterSession(uint16_t on_entry_flags, FILE *in,
run_string.PutCString("; lldb.frame = lldb.thread.GetSelectedFrame ()");
run_string.PutCString("')");
} else {
- // If we aren't initing the globals, we should still always set the debugger
- // (since that is always unique.)
+ // If we aren't initing the globals, we should still always set the
+ // debugger (since that is always unique.)
run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64,
m_dictionary_name.c_str(),
GetCommandInterpreter().GetDebugger().GetID());
@@ -695,19 +751,20 @@ static void ReadThreadBytesReceived(void *baton, const void *src,
}
bool ScriptInterpreterPython::ExecuteOneLine(
- const char *command, CommandReturnObject *result,
+ llvm::StringRef command, CommandReturnObject *result,
const ExecuteScriptOptions &options) {
+ std::string command_str = command.str();
+
if (!m_valid_session)
return false;
- if (command && command[0]) {
+ if (!command.empty()) {
// We want to call run_one_line, passing in the dictionary and the command
- // string. We cannot do this through
- // PyRun_SimpleString here because the command string may contain escaped
- // characters, and putting it inside
+ // string. We cannot do this through PyRun_SimpleString here because the
+ // command string may contain escaped characters, and putting it inside
// another string to pass to PyRun_SimpleString messes up the escaping. So
- // we use the following more complicated
- // method to pass the command string directly down to Python.
+ // we use the following more complicated method to pass the command string
+ // directly down to Python.
Debugger &debugger = m_interpreter.GetDebugger();
StreamFileSP input_file_sp;
@@ -773,17 +830,14 @@ bool ScriptInterpreterPython::ExecuteOneLine(
FILE *err_file = error_file_sp->GetFile().GetStream();
bool success = false;
{
- // WARNING! It's imperative that this RAII scope be as tight as possible.
- // In particular, the
- // scope must end *before* we try to join the read thread. The reason for
- // this is that a
- // pre-requisite for joining the read thread is that we close the write
- // handle (to break the
- // pipe and cause it to wake up and exit). But acquiring the GIL as below
- // will redirect Python's
- // stdio to use this same handle. If we close the handle while Python is
- // still using it, bad
- // things will happen.
+ // WARNING! It's imperative that this RAII scope be as tight as
+ // possible. In particular, the scope must end *before* we try to join
+ // the read thread. The reason for this is that a pre-requisite for
+ // joining the read thread is that we close the write handle (to break
+ // the pipe and cause it to wake up and exit). But acquiring the GIL as
+ // below will redirect Python's stdio to use this same handle. If we
+ // close the handle while Python is still using it, bad things will
+ // happen.
Locker locker(
this,
ScriptInterpreterPython::Locker::AcquireLock |
@@ -803,7 +857,7 @@ bool ScriptInterpreterPython::ExecuteOneLine(
if (PyCallable_Check(m_run_one_line_function.get())) {
PythonObject pargs(
PyRefType::Owned,
- Py_BuildValue("(Os)", session_dict.get(), command));
+ Py_BuildValue("(Os)", session_dict.get(), command_str.c_str()));
if (pargs.IsValid()) {
PythonObject return_value(
PyRefType::Owned,
@@ -827,12 +881,12 @@ bool ScriptInterpreterPython::ExecuteOneLine(
}
if (join_read_thread) {
- // Close the write end of the pipe since we are done with our
- // one line script. This should cause the read thread that
- // output_comm is using to exit
+ // Close the write end of the pipe since we are done with our one line
+ // script. This should cause the read thread that output_comm is using to
+ // exit
output_file_sp->GetFile().Close();
- // The close above should cause this thread to exit when it gets
- // to the end of file, so let it get all its data
+ // The close above should cause this thread to exit when it gets to the
+ // end of file, so let it get all its data
output_comm.JoinReadThread();
// Now we can close the read end of the pipe
output_comm.Disconnect();
@@ -842,9 +896,10 @@ bool ScriptInterpreterPython::ExecuteOneLine(
return true;
// The one-liner failed. Append the error message.
- if (result)
+ if (result) {
result->AppendErrorWithFormat(
- "python failed attempting to evaluate '%s'\n", command);
+ "python failed attempting to evaluate '%s'\n", command_str.c_str());
+ }
return false;
}
@@ -889,21 +944,18 @@ public:
ScriptInterpreterPython::Locker::FreeAcquiredLock |
ScriptInterpreterPython::Locker::TearDownSession);
- // The following call drops into the embedded interpreter loop and stays
- // there until the
- // user chooses to exit from the Python interpreter.
- // This embedded interpreter will, as any Python code that performs I/O,
- // unlock the GIL before
- // a system call that can hang, and lock it when the syscall has
- // returned.
+ // The following call drops into the embedded interpreter loop and
+ // stays there until the user chooses to exit from the Python
+ // interpreter. This embedded interpreter will, as any Python code that
+ // performs I/O, unlock the GIL before a system call that can hang, and
+ // lock it when the syscall has returned.
// We need to surround the call to the embedded interpreter with calls
- // to PyGILState_Ensure and
- // PyGILState_Release (using the Locker above). This is because Python
- // has a global lock which must be held whenever we want
- // to touch any Python objects. Otherwise, if the user calls Python
- // code, the interpreter state will be off,
- // and things could hang (it's happened before).
+ // to PyGILState_Ensure and PyGILState_Release (using the Locker
+ // above). This is because Python has a global lock which must be held
+ // whenever we want to touch any Python objects. Otherwise, if the user
+ // calls Python code, the interpreter state will be off, and things
+ // could hang (it's happened before).
StreamString run_string;
run_string.Printf("run_python_interpreter (%s)",
@@ -934,12 +986,10 @@ void ScriptInterpreterPython::ExecuteInterpreterLoop() {
Debugger &debugger = GetCommandInterpreter().GetDebugger();
// At the moment, the only time the debugger does not have an input file
- // handle is when this is called
- // directly from Python, in which case it is both dangerous and unnecessary
- // (not to mention confusing) to
- // try to embed a running interpreter loop inside the already running Python
- // interpreter loop, so we won't
- // do it.
+ // handle is when this is called directly from Python, in which case it is
+ // both dangerous and unnecessary (not to mention confusing) to try to embed
+ // a running interpreter loop inside the already running Python interpreter
+ // loop, so we won't do it.
if (!debugger.GetInputFile()->GetFile().IsValid())
return;
@@ -974,7 +1024,7 @@ bool ScriptInterpreterPython::Interrupt() {
return false;
}
bool ScriptInterpreterPython::ExecuteOneLineWithReturn(
- const char *in_string, ScriptInterpreter::ScriptReturnType return_type,
+ llvm::StringRef in_string, ScriptInterpreter::ScriptReturnType return_type,
void *ret_value, const ExecuteScriptOptions &options) {
Locker locker(this, ScriptInterpreterPython::Locker::AcquireLock |
@@ -1009,116 +1059,111 @@ bool ScriptInterpreterPython::ExecuteOneLineWithReturn(
if (py_error.IsValid())
PyErr_Clear();
- if (in_string != nullptr) {
- { // scope for PythonInputReaderManager
- // PythonInputReaderManager py_input(options.GetEnableIO() ? this : NULL);
- py_return.Reset(
- PyRefType::Owned,
- PyRun_String(in_string, Py_eval_input, globals.get(), locals.get()));
- if (!py_return.IsValid()) {
- py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
- if (py_error.IsValid())
- PyErr_Clear();
+ std::string as_string = in_string.str();
+ { // scope for PythonInputReaderManager
+ // PythonInputReaderManager py_input(options.GetEnableIO() ? this : NULL);
+ py_return.Reset(PyRefType::Owned,
+ PyRun_String(as_string.c_str(), Py_eval_input,
+ globals.get(), locals.get()));
+ if (!py_return.IsValid()) {
+ py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
+ if (py_error.IsValid())
+ PyErr_Clear();
- py_return.Reset(PyRefType::Owned,
- PyRun_String(in_string, Py_single_input, globals.get(),
- locals.get()));
- }
+ py_return.Reset(PyRefType::Owned,
+ PyRun_String(as_string.c_str(), Py_single_input,
+ globals.get(), locals.get()));
}
+ }
- if (py_return.IsValid()) {
- switch (return_type) {
- case eScriptReturnTypeCharPtr: // "char *"
- {
- const char format[3] = "s#";
- success = PyArg_Parse(py_return.get(), format, (char **)ret_value);
- break;
- }
- case eScriptReturnTypeCharStrOrNone: // char* or NULL if py_return ==
- // Py_None
- {
- const char format[3] = "z";
- success = PyArg_Parse(py_return.get(), format, (char **)ret_value);
- break;
- }
- case eScriptReturnTypeBool: {
- const char format[2] = "b";
- success = PyArg_Parse(py_return.get(), format, (bool *)ret_value);
- break;
- }
- case eScriptReturnTypeShortInt: {
- const char format[2] = "h";
- success = PyArg_Parse(py_return.get(), format, (short *)ret_value);
- break;
- }
- case eScriptReturnTypeShortIntUnsigned: {
- const char format[2] = "H";
- success =
- PyArg_Parse(py_return.get(), format, (unsigned short *)ret_value);
- break;
- }
- case eScriptReturnTypeInt: {
- const char format[2] = "i";
- success = PyArg_Parse(py_return.get(), format, (int *)ret_value);
- break;
- }
- case eScriptReturnTypeIntUnsigned: {
- const char format[2] = "I";
- success =
- PyArg_Parse(py_return.get(), format, (unsigned int *)ret_value);
- break;
- }
- case eScriptReturnTypeLongInt: {
- const char format[2] = "l";
- success = PyArg_Parse(py_return.get(), format, (long *)ret_value);
- break;
- }
- case eScriptReturnTypeLongIntUnsigned: {
- const char format[2] = "k";
- success =
- PyArg_Parse(py_return.get(), format, (unsigned long *)ret_value);
- break;
- }
- case eScriptReturnTypeLongLong: {
- const char format[2] = "L";
- success = PyArg_Parse(py_return.get(), format, (long long *)ret_value);
- break;
- }
- case eScriptReturnTypeLongLongUnsigned: {
- const char format[2] = "K";
- success = PyArg_Parse(py_return.get(), format,
- (unsigned long long *)ret_value);
- break;
- }
- case eScriptReturnTypeFloat: {
- const char format[2] = "f";
- success = PyArg_Parse(py_return.get(), format, (float *)ret_value);
- break;
- }
- case eScriptReturnTypeDouble: {
- const char format[2] = "d";
- success = PyArg_Parse(py_return.get(), format, (double *)ret_value);
- break;
- }
- case eScriptReturnTypeChar: {
- const char format[2] = "c";
- success = PyArg_Parse(py_return.get(), format, (char *)ret_value);
- break;
- }
- case eScriptReturnTypeOpaqueObject: {
- success = true;
- PyObject *saved_value = py_return.get();
- Py_XINCREF(saved_value);
- *((PyObject **)ret_value) = saved_value;
- break;
- }
- }
-
- if (success)
- ret_success = true;
- else
- ret_success = false;
+ if (py_return.IsValid()) {
+ switch (return_type) {
+ case eScriptReturnTypeCharPtr: // "char *"
+ {
+ const char format[3] = "s#";
+ success = PyArg_Parse(py_return.get(), format, (char **)ret_value);
+ break;
}
+ case eScriptReturnTypeCharStrOrNone: // char* or NULL if py_return ==
+ // Py_None
+ {
+ const char format[3] = "z";
+ success = PyArg_Parse(py_return.get(), format, (char **)ret_value);
+ break;
+ }
+ case eScriptReturnTypeBool: {
+ const char format[2] = "b";
+ success = PyArg_Parse(py_return.get(), format, (bool *)ret_value);
+ break;
+ }
+ case eScriptReturnTypeShortInt: {
+ const char format[2] = "h";
+ success = PyArg_Parse(py_return.get(), format, (short *)ret_value);
+ break;
+ }
+ case eScriptReturnTypeShortIntUnsigned: {
+ const char format[2] = "H";
+ success =
+ PyArg_Parse(py_return.get(), format, (unsigned short *)ret_value);
+ break;
+ }
+ case eScriptReturnTypeInt: {
+ const char format[2] = "i";
+ success = PyArg_Parse(py_return.get(), format, (int *)ret_value);
+ break;
+ }
+ case eScriptReturnTypeIntUnsigned: {
+ const char format[2] = "I";
+ success = PyArg_Parse(py_return.get(), format, (unsigned int *)ret_value);
+ break;
+ }
+ case eScriptReturnTypeLongInt: {
+ const char format[2] = "l";
+ success = PyArg_Parse(py_return.get(), format, (long *)ret_value);
+ break;
+ }
+ case eScriptReturnTypeLongIntUnsigned: {
+ const char format[2] = "k";
+ success =
+ PyArg_Parse(py_return.get(), format, (unsigned long *)ret_value);
+ break;
+ }
+ case eScriptReturnTypeLongLong: {
+ const char format[2] = "L";
+ success = PyArg_Parse(py_return.get(), format, (long long *)ret_value);
+ break;
+ }
+ case eScriptReturnTypeLongLongUnsigned: {
+ const char format[2] = "K";
+ success =
+ PyArg_Parse(py_return.get(), format, (unsigned long long *)ret_value);
+ break;
+ }
+ case eScriptReturnTypeFloat: {
+ const char format[2] = "f";
+ success = PyArg_Parse(py_return.get(), format, (float *)ret_value);
+ break;
+ }
+ case eScriptReturnTypeDouble: {
+ const char format[2] = "d";
+ success = PyArg_Parse(py_return.get(), format, (double *)ret_value);
+ break;
+ }
+ case eScriptReturnTypeChar: {
+ const char format[2] = "c";
+ success = PyArg_Parse(py_return.get(), format, (char *)ret_value);
+ break;
+ }
+ case eScriptReturnTypeOpaqueObject: {
+ success = true;
+ PyObject *saved_value = py_return.get();
+ Py_XINCREF(saved_value);
+ *((PyObject **)ret_value) = saved_value;
+ break;
+ }
+ }
+
+ ret_success = success;
}
py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
@@ -1174,10 +1219,8 @@ Status ScriptInterpreterPython::ExecuteMultipleLines(
if (code_object.IsValid()) {
// In Python 2.x, PyEval_EvalCode takes a PyCodeObject, but in Python 3.x, it
-// takes
-// a PyObject. They are convertible (hence the function
-// PyCode_Check(PyObject*), so
-// we have to do the cast for Python 2.x
+// takes a PyObject. They are convertible (hence the function
+// PyCode_Check(PyObject*), so we have to do the cast for Python 2.x
#if PY_MAJOR_VERSION >= 3
PyObject *py_code_obj = code_object.get();
#else
@@ -1243,10 +1286,9 @@ Status ScriptInterpreterPython::SetBreakpointCommandCallback(
auto data_ap = llvm::make_unique<CommandDataPython>();
// Split the command_body_text into lines, and pass that to
- // GenerateBreakpointCommandCallbackData. That will
- // wrap the body in an auto-generated function, and return the function name
- // in script_source. That is what
- // the callback will actually invoke.
+ // GenerateBreakpointCommandCallbackData. That will wrap the body in an
+ // auto-generated function, and return the function name in script_source.
+ // That is what the callback will actually invoke.
data_ap->user_source.SplitIntoLines(command_body_text);
Status error = GenerateBreakpointCommandCallbackData(data_ap->user_source,
@@ -1268,9 +1310,8 @@ void ScriptInterpreterPython::SetWatchpointCommandCallback(
// It's necessary to set both user_source and script_source to the oneliner.
// The former is used to generate callback description (as in watchpoint
- // command list)
- // while the latter is used for Python to interpret during the actual
- // callback.
+ // 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);
@@ -1365,8 +1406,7 @@ bool ScriptInterpreterPython::GenerateTypeScriptFunction(
return false;
// Take what the user wrote, wrap it all up inside one big auto-generated
- // Python function, passing in the
- // ValueObject as parameter to the function.
+ // Python function, passing in the ValueObject as parameter to the function.
std::string auto_generated_function_name(
GenerateUniqueName("lldb_autogen_python_type_print_func",
@@ -1430,8 +1470,8 @@ bool ScriptInterpreterPython::GenerateTypeSynthClass(StringList &user_input,
sstr.Printf("class %s:", auto_generated_class_name.c_str());
auto_generated_class.AppendString(sstr.GetString());
- // Wrap everything up inside the class, increasing the indentation.
- // we don't need to play any fancy indentation tricks here because there is no
+ // Wrap everything up inside the class, increasing the indentation. we don't
+ // need to play any fancy indentation tricks here because there is no
// surrounding code whose indentation we need to honor
for (int i = 0; i < num_lines; ++i) {
sstr.Clear();
@@ -1439,9 +1479,8 @@ bool ScriptInterpreterPython::GenerateTypeSynthClass(StringList &user_input,
auto_generated_class.AppendString(sstr.GetString());
}
- // Verify that the results are valid Python.
- // (even though the method is ExportFunctionDefinitionToInterpreter, a class
- // will actually be exported)
+ // Verify that the results are valid Python. (even though the method is
+ // ExportFunctionDefinitionToInterpreter, a class will actually be exported)
// (TODO: rename that method to ExportDefinitionToInterpreter)
if (!ExportFunctionDefinitionToInterpreter(auto_generated_class).Success())
return false;
@@ -1585,8 +1624,8 @@ StructuredData::ArraySP ScriptInterpreterPython::OSPlugin_ThreadsInfo(
// GetPythonValueFormatString provides a system independent type safe way to
// convert a variable's type into a python value format. Python value formats
-// are defined in terms of builtin C types and could change from system to
-// as the underlying typedef for uint* types, size_t, off_t and other values
+// are defined in terms of builtin C types and could change from system to as
+// the underlying typedef for uint* types, size_t, off_t and other values
// change.
template <typename T> const char *GetPythonValueFormatString(T t);
@@ -2044,8 +2083,7 @@ void ScriptInterpreterPython::Clear() {
ScriptInterpreterPython::Locker::FreeAcquiredLock);
// This may be called as part of Py_Finalize. In that case the modules are
- // destroyed in random
- // order and we can't guarantee that we can access these.
+ // destroyed in random order and we can't guarantee that we can access these.
if (Py_IsInitialized())
PyRun_SimpleString("lldb.debugger = None; lldb.target = None; lldb.process "
"= None; lldb.thread = None; lldb.frame = None");
@@ -2615,9 +2653,9 @@ bool ScriptInterpreterPython::LoadScriptingModule(
// strip .py or .pyc extension
ConstString extension = target_file.GetFileNameExtension();
if (extension) {
- if (::strcmp(extension.GetCString(), "py") == 0)
+ if (llvm::StringRef(extension.GetCString()) == ".py")
basename.resize(basename.length() - 3);
- else if (::strcmp(extension.GetCString(), "pyc") == 0)
+ else if (llvm::StringRef(extension.GetCString()) == ".pyc")
basename.resize(basename.length() - 4);
}
} else {
@@ -2629,9 +2667,8 @@ bool ScriptInterpreterPython::LoadScriptingModule(
command_stream.Clear();
command_stream.Printf("sys.modules.__contains__('%s')", basename.c_str());
bool does_contain = false;
- // this call will succeed if the module was ever imported in any Debugger in
- // the lifetime of the process
- // in which this LLDB framework is living
+ // this call will succeed if the module was ever imported in any Debugger
+ // in the lifetime of the process in which this LLDB framework is living
bool was_imported_globally =
(ExecuteOneLineWithReturn(
command_stream.GetData(),
@@ -2705,8 +2742,8 @@ bool ScriptInterpreterPython::IsReservedWord(const char *word) {
llvm::StringRef word_sr(word);
- // filter out a few characters that would just confuse us
- // and that are clearly not keyword material anyway
+ // filter out a few characters that would just confuse us and that are
+ // clearly not keyword material anyway
if (word_sr.find_first_of("'\"") != llvm::StringRef::npos)
return false;
@@ -2740,7 +2777,7 @@ ScriptInterpreterPython::SynchronicityHandler::~SynchronicityHandler() {
}
bool ScriptInterpreterPython::RunScriptBasedCommand(
- const char *impl_function, const char *args,
+ const char *impl_function, llvm::StringRef args,
ScriptedCommandSynchronicity synchronicity,
lldb_private::CommandReturnObject &cmd_retobj, Status &error,
const lldb_private::ExecutionContext &exe_ctx) {
@@ -2774,9 +2811,10 @@ bool ScriptInterpreterPython::RunScriptBasedCommand(
SynchronicityHandler synch_handler(debugger_sp, synchronicity);
- ret_val =
- g_swig_call_command(impl_function, m_dictionary_name.c_str(),
- debugger_sp, args, cmd_retobj, exe_ctx_ref_sp);
+ std::string args_str = args.str();
+ ret_val = g_swig_call_command(impl_function, m_dictionary_name.c_str(),
+ debugger_sp, args_str.c_str(), cmd_retobj,
+ exe_ctx_ref_sp);
}
if (!ret_val)
@@ -2788,7 +2826,7 @@ bool ScriptInterpreterPython::RunScriptBasedCommand(
}
bool ScriptInterpreterPython::RunScriptBasedCommand(
- StructuredData::GenericSP impl_obj_sp, const char *args,
+ StructuredData::GenericSP impl_obj_sp, llvm::StringRef args,
ScriptedCommandSynchronicity synchronicity,
lldb_private::CommandReturnObject &cmd_retobj, Status &error,
const lldb_private::ExecutionContext &exe_ctx) {
@@ -2822,8 +2860,10 @@ bool ScriptInterpreterPython::RunScriptBasedCommand(
SynchronicityHandler synch_handler(debugger_sp, synchronicity);
+ std::string args_str = args.str();
ret_val = g_swig_call_command_object(impl_obj_sp->GetValue(), debugger_sp,
- args, cmd_retobj, exe_ctx_ref_sp);
+ args_str.c_str(), cmd_retobj,
+ exe_ctx_ref_sp);
}
if (!ret_val)
@@ -2834,9 +2874,9 @@ bool ScriptInterpreterPython::RunScriptBasedCommand(
return ret_val;
}
-// in Python, a special attribute __doc__ contains the docstring
-// for an object (function, method, class, ...) if any is defined
-// Otherwise, the attribute's value is None
+// in Python, a special attribute __doc__ contains the docstring for an object
+// (function, method, class, ...) if any is defined Otherwise, the attribute's
+// value is None
bool ScriptInterpreterPython::GetDocumentationForItem(const char *item,
std::string &dest) {
dest.clear();
@@ -3106,10 +3146,9 @@ void ScriptInterpreterPython::InitializePrivate() {
Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
// RAII-based initialization which correctly handles multiple-initialization,
- // version-
- // specific differences among Python 2 and Python 3, and saving and restoring
- // various
- // other pieces of state that can get mucked with during initialization.
+ // version- specific differences among Python 2 and Python 3, and saving and
+ // restoring various other pieces of state that can get mucked with during
+ // initialization.
InitializePythonRAII initialize_guard;
if (g_swig_init_callback)
@@ -3121,17 +3160,13 @@ void ScriptInterpreterPython::InitializePrivate() {
PyRun_SimpleString("import sys");
AddToSysPath(AddLocation::End, ".");
- FileSpec file_spec;
// Don't denormalize paths when calling file_spec.GetPath(). On platforms
- // that use
- // a backslash as the path separator, this will result in executing python
- // code containing
- // paths with unescaped backslashes. But Python also accepts forward slashes,
- // so to make
- // life easier we just use that.
- if (HostInfo::GetLLDBPath(ePathTypePythonDir, file_spec))
+ // that use a backslash as the path separator, this will result in executing
+ // python code containing paths with unescaped backslashes. But Python also
+ // accepts forward slashes, so to make life easier we just use that.
+ if (FileSpec file_spec = GetPythonDir())
AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false));
- if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, file_spec))
+ if (FileSpec file_spec = HostInfo::GetShlibDir())
AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false));
PyRun_SimpleString("sys.dont_write_bytecode = 1; import "
@@ -3157,30 +3192,20 @@ void ScriptInterpreterPython::AddToSysPath(AddLocation location,
PyRun_SimpleString(statement.c_str());
}
-// void
-// ScriptInterpreterPython::Terminate ()
-//{
-// // We are intentionally NOT calling Py_Finalize here (this would be the
-// logical place to call it). Calling
-// // Py_Finalize here causes test suite runs to seg fault: The test suite
-// runs in Python. It registers
-// // SBDebugger::Terminate to be called 'at_exit'. When the test suite
-// Python harness finishes up, it calls
-// // Py_Finalize, which calls all the 'at_exit' registered functions.
-// SBDebugger::Terminate calls Debugger::Terminate,
-// // which calls lldb::Terminate, which calls ScriptInterpreter::Terminate,
-// which calls
-// // ScriptInterpreterPython::Terminate. So if we call Py_Finalize here, we
-// end up with Py_Finalize being called from
-// // within Py_Finalize, which results in a seg fault.
-// //
-// // Since this function only gets called when lldb is shutting down and
-// going away anyway, the fact that we don't
-// // actually call Py_Finalize should not cause any problems (everything
-// should shut down/go away anyway when the
-// // process exits).
-// //
-//// Py_Finalize ();
-//}
+// We are intentionally NOT calling Py_Finalize here (this would be the logical
+// place to call it). Calling Py_Finalize here causes test suite runs to seg
+// fault: The test suite runs in Python. It registers SBDebugger::Terminate to
+// be called 'at_exit'. When the test suite Python harness finishes up, it
+// calls Py_Finalize, which calls all the 'at_exit' registered functions.
+// SBDebugger::Terminate calls Debugger::Terminate, which calls lldb::Terminate,
+// which calls ScriptInterpreter::Terminate, which calls
+// ScriptInterpreterPython::Terminate. So if we call Py_Finalize here, we end
+// up with Py_Finalize being called from within Py_Finalize, which results in a
+// seg fault. Since this function only gets called when lldb is shutting down
+// and going away anyway, the fact that we don't actually call Py_Finalize
+// should not cause any problems (everything should shut down/go away anyway
+// when the process exits).
+//
+// void ScriptInterpreterPython::Terminate() { Py_Finalize (); }
-#endif // #ifdef LLDB_DISABLE_PYTHON
+#endif // LLDB_DISABLE_PYTHON
diff --git a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
index a71fcea7519c..b13979dc069b 100644
--- a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
+++ b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
@@ -151,14 +151,14 @@ public:
bool Interrupt() override;
bool ExecuteOneLine(
- const char *command, CommandReturnObject *result,
+ llvm::StringRef command, CommandReturnObject *result,
const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
void ExecuteInterpreterLoop() override;
bool ExecuteOneLineWithReturn(
- const char *in_string, ScriptInterpreter::ScriptReturnType return_type,
- void *ret_value,
+ llvm::StringRef in_string,
+ ScriptInterpreter::ScriptReturnType return_type, void *ret_value,
const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
lldb_private::Status ExecuteMultipleLines(
@@ -259,18 +259,17 @@ public:
GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) override;
bool
- RunScriptBasedCommand(const char *impl_function, const char *args,
+ RunScriptBasedCommand(const char *impl_function, llvm::StringRef args,
ScriptedCommandSynchronicity synchronicity,
lldb_private::CommandReturnObject &cmd_retobj,
Status &error,
const lldb_private::ExecutionContext &exe_ctx) override;
- bool
- RunScriptBasedCommand(StructuredData::GenericSP impl_obj_sp, const char *args,
- ScriptedCommandSynchronicity synchronicity,
- lldb_private::CommandReturnObject &cmd_retobj,
- Status &error,
- const lldb_private::ExecutionContext &exe_ctx) override;
+ bool RunScriptBasedCommand(
+ StructuredData::GenericSP impl_obj_sp, llvm::StringRef args,
+ ScriptedCommandSynchronicity synchronicity,
+ lldb_private::CommandReturnObject &cmd_retobj, Status &error,
+ const lldb_private::ExecutionContext &exe_ctx) override;
Status GenerateFunction(const char *signature,
const StringList &input) override;
@@ -445,6 +444,8 @@ public:
static const char *GetPluginDescriptionStatic();
+ static FileSpec GetPythonDir();
+
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
@@ -509,6 +510,10 @@ protected:
static void AddToSysPath(AddLocation location, std::string path);
+ static void ComputePythonDirForApple(llvm::SmallVectorImpl<char> &path);
+ static void ComputePythonDirForPosix(llvm::SmallVectorImpl<char> &path);
+ static void ComputePythonDirForWindows(llvm::SmallVectorImpl<char> &path);
+
bool EnterSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err);
void LeaveSession();
diff --git a/source/Plugins/ScriptInterpreter/Python/lldb-python.h b/source/Plugins/ScriptInterpreter/Python/lldb-python.h
index ee13b7a5cd1f..f929baade2e4 100644
--- a/source/Plugins/ScriptInterpreter/Python/lldb-python.h
+++ b/source/Plugins/ScriptInterpreter/Python/lldb-python.h
@@ -1,5 +1,4 @@
-//===-- lldb-python.h --------------------------------------------*- C++
-//-*-===//
+//===-- lldb-python.h -------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,7 +17,7 @@
// Python is disabled in this build
#else
#include "llvm/Support/Compiler.h"
-#if defined(LLVM_ON_WIN32)
+#if defined(_WIN32)
// If anyone #includes Host/PosixApi.h later, it will try to typedef pid_t. We
// need to ensure this doesn't happen. At the same time, Python.h will also try
// to redefine a bunch of stuff that PosixApi.h defines. So define it all now
diff --git a/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp b/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
index 8424b55ee69c..e33e26507fb1 100644
--- a/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
+++ b/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
@@ -23,6 +23,7 @@
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Interpreter/OptionValueString.h"
#include "lldb/Interpreter/Property.h"
@@ -184,10 +185,10 @@ const char *const s_filter_attributes[] = {
"message", // message contents, fully expanded
"subsystem" // subsystem of the log message
- // Consider impelmenting this action as it would be cheaper to filter.
- // "message" requires always formatting the message, which is a waste
- // of cycles if it ends up being rejected.
- // "format", // format string used to format message text
+ // Consider implementing this action as it would be cheaper to filter.
+ // "message" requires always formatting the message, which is a waste of
+ // cycles if it ends up being rejected. "format", // format string
+ // used to format message text
};
static const ConstString &GetDarwinLogTypeName() {
@@ -238,11 +239,10 @@ public:
// Indicate whether this is an accept or reject rule.
dict_p->AddBooleanItem("accept", m_accept);
- // Indicate which attribute of the message this filter references.
- // This can drop into the rule-specific DoSerialization if we get
- // to the point where not all FilterRule derived classes work on
- // an attribute. (e.g. logical and/or and other compound
- // operations).
+ // Indicate which attribute of the message this filter references. This can
+ // drop into the rule-specific DoSerialization if we get to the point where
+ // not all FilterRule derived classes work on an attribute. (e.g. logical
+ // and/or and other compound operations).
dict_p->AddStringItem("attribute", s_filter_attributes[m_attribute_index]);
// Indicate the type of the rule.
@@ -403,9 +403,9 @@ static void RegisterFilterOperations() {
// -------------------------------------------------------------------------
static OptionDefinition g_enable_option_table[] = {
- // Source stream include/exclude options (the first-level filter).
- // This one should be made as small as possible as everything that
- // goes through here must be processed by the process monitor.
+ // Source stream include/exclude options (the first-level filter). This one
+ // should be made as small as possible as everything that goes through here
+ // must be processed by the process monitor.
{LLDB_OPT_SET_ALL, false, "any-process", 'a', OptionParser::eNoArgument,
nullptr, nullptr, 0, eArgTypeNone,
"Specifies log messages from other related processes should be "
@@ -419,10 +419,10 @@ static OptionDefinition g_enable_option_table[] = {
"Specifies info-level log messages should be included."},
{LLDB_OPT_SET_ALL, false, "filter", 'f', OptionParser::eRequiredArgument,
nullptr, nullptr, 0, eArgRawInput,
- // There doesn't appear to be a great way for me to have these
- // multi-line, formatted tables in help. This looks mostly right
- // but there are extra linefeeds added at seemingly random spots,
- // and indentation isn't handled properly on those lines.
+ // There doesn't appear to be a great way for me to have these multi-line,
+ // formatted tables in help. This looks mostly right but there are extra
+ // linefeeds added at seemingly random spots, and indentation isn't
+ // handled properly on those lines.
"Appends a filter rule to the log message filter chain. Multiple "
"rules may be added by specifying this option multiple times, "
"once per filter rule. Filter rules are processed in the order "
@@ -488,11 +488,11 @@ static OptionDefinition g_enable_option_table[] = {
"a log message."},
{LLDB_OPT_SET_ALL, false, "category", 'c', OptionParser::eNoArgument,
nullptr, nullptr, 0, eArgTypeNone,
- "Include the category in the the message header when displaying "
+ "Include the category in the message header when displaying "
"a log message."},
{LLDB_OPT_SET_ALL, false, "activity-chain", 'C', OptionParser::eNoArgument,
nullptr, nullptr, 0, eArgTypeNone,
- "Include the activity parent-child chain in the the message header "
+ "Include the activity parent-child chain in the message header "
"when displaying a log message. The activity hierarchy is "
"displayed as {grandparent-activity}:"
"{parent-activity}:{activity}[:...]."},
@@ -544,7 +544,8 @@ public:
break;
case 'b':
- m_broadcast_events = Args::StringToBoolean(option_arg, true, nullptr);
+ m_broadcast_events =
+ OptionArgParser::ToBoolean(option_arg, true, nullptr);
break;
case 'c':
@@ -560,7 +561,7 @@ public:
break;
case 'e':
- m_echo_to_stderr = Args::StringToBoolean(option_arg, false, nullptr);
+ m_echo_to_stderr = OptionArgParser::ToBoolean(option_arg, false, nullptr);
break;
case 'f':
@@ -571,12 +572,12 @@ public:
break;
case 'l':
- m_live_stream = Args::StringToBoolean(option_arg, false, nullptr);
+ m_live_stream = OptionArgParser::ToBoolean(option_arg, false, nullptr);
break;
case 'n':
m_filter_fall_through_accepts =
- Args::StringToBoolean(option_arg, true, nullptr);
+ OptionArgParser::ToBoolean(option_arg, true, nullptr);
break;
case 'r':
@@ -614,7 +615,7 @@ public:
source_flags_sp->AddBooleanItem("any-process", m_include_any_process);
source_flags_sp->AddBooleanItem("debug-level", m_include_debug_level);
- // The debug-level flag, if set, implies info-level.
+ // The debug-level flag, if set, implies info-level.
source_flags_sp->AddBooleanItem("info-level", m_include_info_level ||
m_include_debug_level);
source_flags_sp->AddBooleanItem("live-stream", m_live_stream);
@@ -784,12 +785,11 @@ protected:
if (!source_name)
return;
- // Check if we're *not* using strict sources. If not,
- // then the user is going to get debug-level info
- // anyways, probably not what they're expecting.
- // Unfortunately we can only fix this by adding an
- // env var, which would have had to have happened
- // already. Thus, a warning is the best we can do here.
+ // Check if we're *not* using strict sources. If not, then the user is
+ // going to get debug-level info anyways, probably not what they're
+ // expecting. Unfortunately we can only fix this by adding an env var,
+ // which would have had to have happened already. Thus, a warning is the
+ // best we can do here.
StreamString stream;
stream.Printf("darwin-log source settings specify to exclude "
"%s messages, but setting "
@@ -803,24 +803,22 @@ protected:
}
bool DoExecute(Args &command, CommandReturnObject &result) override {
- // First off, set the global sticky state of enable/disable
- // based on this command execution.
+ // First off, set the global sticky state of enable/disable based on this
+ // command execution.
s_is_explicitly_enabled = m_enable;
- // Next, if this is an enable, save off the option data.
- // We will need it later if a process hasn't been launched or
- // attached yet.
+ // Next, if this is an enable, save off the option data. We will need it
+ // later if a process hasn't been launched or attached yet.
if (m_enable) {
- // Save off enabled configuration so we can apply these parsed
- // options the next time an attach or launch occurs.
+ // Save off enabled configuration so we can apply these parsed options
+ // the next time an attach or launch occurs.
DebuggerSP debugger_sp =
GetCommandInterpreter().GetDebugger().shared_from_this();
SetGlobalEnableOptions(debugger_sp, m_options_sp);
}
- // Now check if we have a running process. If so, we should
- // instruct the process monitor to enable/disable DarwinLog support
- // now.
+ // Now check if we have a running process. If so, we should instruct the
+ // process monitor to enable/disable DarwinLog support now.
Target *target = GetSelectedOrDummyTarget();
if (!target) {
// No target, so there is nothing more to do right now.
@@ -831,14 +829,13 @@ protected:
// Grab the active process.
auto process_sp = target->GetProcessSP();
if (!process_sp) {
- // No active process, so there is nothing more to do right
- // now.
+ // No active process, so there is nothing more to do right now.
result.SetStatus(eReturnStatusSuccessFinishNoResult);
return true;
}
- // If the process is no longer alive, we can't do this now.
- // We'll catch it the next time the process is started up.
+ // If the process is no longer alive, we can't do this now. We'll catch it
+ // the next time the process is started up.
if (!process_sp->IsAlive()) {
result.SetStatus(eReturnStatusSuccessFinishNoResult);
return true;
@@ -857,19 +854,17 @@ protected:
*static_cast<StructuredDataDarwinLog *>(plugin_sp.get());
if (m_enable) {
- // Hook up the breakpoint for the process that detects when
- // libtrace has been sufficiently initialized to really start
- // the os_log stream. This is insurance to assure us that
- // logging is really enabled. Requesting that logging be
- // enabled for a process before libtrace is initialized
- // results in a scenario where no errors occur, but no logging
- // is captured, either. This step is to eliminate that
- // possibility.
+ // Hook up the breakpoint for the process that detects when libtrace has
+ // been sufficiently initialized to really start the os_log stream. This
+ // is insurance to assure us that logging is really enabled. Requesting
+ // that logging be enabled for a process before libtrace is initialized
+ // results in a scenario where no errors occur, but no logging is
+ // captured, either. This step is to eliminate that possibility.
plugin.AddInitCompletionHook(*process_sp.get());
}
- // Send configuration to the feature by way of the process.
- // Construct the options we will use.
+ // Send configuration to the feature by way of the process. Construct the
+ // options we will use.
auto config_sp = m_options_sp->BuildConfigurationData(m_enable);
const Status error =
process_sp->ConfigureStructuredData(GetDarwinLogTypeName(), config_sp);
@@ -882,8 +877,8 @@ protected:
plugin.SetEnabled(false);
} else {
result.SetStatus(eReturnStatusSuccessFinishNoResult);
- // Our configuration succeeeded, so we're enabled/disabled
- // per whichever one this command is setup to do.
+ // Our configuration succeeded, so we're enabled/disabled per whichever
+ // one this command is setup to do.
plugin.SetEnabled(m_enable);
}
return result.Succeeded();
@@ -914,8 +909,8 @@ protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
auto &stream = result.GetOutputStream();
- // Figure out if we've got a process. If so, we can tell if
- // DarwinLog is available for that process.
+ // Figure out if we've got a process. If so, we can tell if DarwinLog is
+ // available for that process.
Target *target = GetSelectedOrDummyTarget();
auto process_sp = target ? target->GetProcessSP() : ProcessSP();
if (!target || !process_sp) {
@@ -1013,13 +1008,13 @@ public:
};
EnableOptionsSP ParseAutoEnableOptions(Status &error, Debugger &debugger) {
- // We are abusing the options data model here so that we can parse
- // options without requiring the Debugger instance.
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS);
+ // We are abusing the options data model here so that we can parse options
+ // without requiring the Debugger instance.
- // We have an empty execution context at this point. We only want
- // to parse options, and we don't need any context to do this here.
- // In fact, we want to be able to parse the enable options before having
- // any context.
+ // We have an empty execution context at this point. We only want to parse
+ // options, and we don't need any context to do this here. In fact, we want
+ // to be able to parse the enable options before having any context.
ExecutionContext exe_ctx;
EnableOptionsSP options_sp(new EnableOptions());
@@ -1044,22 +1039,23 @@ EnableOptionsSP ParseAutoEnableOptions(Status &error, Debugger &debugger) {
options_property_sp->GetAsString()->GetCurrentValue();
Args args(enable_options);
if (args.GetArgumentCount() > 0) {
- // Eliminate the initial '--' that would be required to set the
- // settings that themselves include '-' and/or '--'.
+ // Eliminate the initial '--' that would be required to set the settings
+ // that themselves include '-' and/or '--'.
const char *first_arg = args.GetArgumentAtIndex(0);
if (first_arg && (strcmp(first_arg, "--") == 0))
args.Shift();
}
- // ParseOptions calls getopt_long_only, which always skips the zero'th item in
- // the array and starts at position 1,
- // so we need to push a dummy value into position zero.
- args.Unshift(llvm::StringRef("dummy_string"));
bool require_validation = false;
- error = args.ParseOptions(*options_sp.get(), &exe_ctx, PlatformSP(),
- require_validation);
- if (!error.Success())
+ llvm::Expected<Args> args_or =
+ options_sp->Parse(args, &exe_ctx, PlatformSP(), require_validation);
+ if (!args_or) {
+ LLDB_LOG_ERROR(
+ log, args_or.takeError(),
+ "Parsing plugin.structured-data.darwin-log.auto-enable-options value "
+ "failed: {0}");
return EnableOptionsSP();
+ }
if (!options_sp->VerifyOptions(result))
return EnableOptionsSP();
@@ -1168,9 +1164,9 @@ void StructuredDataDarwinLog::HandleArrivalOfStructuredData(
return;
}
- // Broadcast the structured data event if we have that enabled.
- // This is the way that the outside world (all clients) get access
- // to this data. This plugin sets policy as to whether we do that.
+ // Broadcast the structured data event if we have that enabled. This is the
+ // way that the outside world (all clients) get access to this data. This
+ // plugin sets policy as to whether we do that.
DebuggerSP debugger_sp = process.GetTarget().GetDebugger().shared_from_this();
auto options_sp = GetGlobalEnableOptions(debugger_sp);
if (options_sp && options_sp->GetBroadcastEvents()) {
@@ -1180,8 +1176,8 @@ void StructuredDataDarwinLog::HandleArrivalOfStructuredData(
process.BroadcastStructuredData(object_sp, shared_from_this());
}
- // Later, hang on to a configurable amount of these and allow commands
- // to inspect, including showing backtraces.
+ // Later, hang on to a configurable amount of these and allow commands to
+ // inspect, including showing backtraces.
}
static void SetErrorWithJSON(Status &error, const char *message,
@@ -1257,8 +1253,8 @@ Status StructuredDataDarwinLog::GetDescription(
return false;
}
- // If we haven't already grabbed the first timestamp
- // value, do that now.
+ // If we haven't already grabbed the first timestamp value, do that
+ // now.
if (!m_recorded_first_timestamp) {
uint64_t timestamp = 0;
if (event->GetValueForKeyAsInteger("timestamp", timestamp)) {
@@ -1296,8 +1292,8 @@ void StructuredDataDarwinLog::ModulesDidLoad(Process &process,
// Check if we should enable the darwin log support on startup/attach.
if (!GetGlobalProperties()->GetEnableOnStartup() &&
!s_is_explicitly_enabled) {
- // We're neither auto-enabled or explicitly enabled, so we shouldn't
- // try to enable here.
+ // We're neither auto-enabled or explicitly enabled, so we shouldn't try to
+ // enable here.
if (log)
log->Printf("StructuredDataDarwinLog::%s not applicable, we're not "
"enabled (process uid %u)",
@@ -1317,9 +1313,9 @@ void StructuredDataDarwinLog::ModulesDidLoad(Process &process,
}
}
- // The logging support module name, specifies the name of
- // the image name that must be loaded into the debugged process before
- // we can try to enable logging.
+ // The logging support module name, specifies the name of the image name that
+ // must be loaded into the debugged process before we can try to enable
+ // logging.
const char *logging_module_cstr =
GetGlobalProperties()->GetLoggingModuleName();
if (!logging_module_cstr || (logging_module_cstr[0] == 0)) {
@@ -1359,8 +1355,8 @@ void StructuredDataDarwinLog::ModulesDidLoad(Process &process,
return;
}
- // Time to enqueue the breakpoint so we can wait for logging support
- // to be initialized before we try to tap the libtrace stream.
+ // Time to enqueue the breakpoint so we can wait for logging support to be
+ // initialized before we try to tap the libtrace stream.
AddInitCompletionHook(process);
if (log)
log->Printf("StructuredDataDarwinLog::%s post-init hook breakpoint "
@@ -1368,13 +1364,13 @@ void StructuredDataDarwinLog::ModulesDidLoad(Process &process,
__FUNCTION__, logging_module_name.AsCString(),
process.GetUniqueID());
- // We need to try the enable here as well, which will succeed
- // in the event that we're attaching to (rather than launching) the
- // process and the process is already past initialization time. In that
- // case, the completion breakpoint will never get hit and therefore won't
- // start that way. It doesn't hurt much beyond a bit of bandwidth
- // if we end up doing this twice. It hurts much more if we don't get
- // the logging enabled when the user expects it.
+ // We need to try the enable here as well, which will succeed in the event
+ // that we're attaching to (rather than launching) the process and the
+ // process is already past initialization time. In that case, the completion
+ // breakpoint will never get hit and therefore won't start that way. It
+ // doesn't hurt much beyond a bit of bandwidth if we end up doing this twice.
+ // It hurts much more if we don't get the logging enabled when the user
+ // expects it.
EnableNow();
}
@@ -1411,8 +1407,7 @@ StructuredDataDarwinLog::StructuredDataDarwinLog(const ProcessWP &process_wp)
StructuredDataPluginSP
StructuredDataDarwinLog::CreateInstance(Process &process) {
- // Currently only Apple targets support the os_log/os_activity
- // protocol.
+ // Currently only Apple targets support the os_log/os_activity protocol.
if (process.GetTarget().GetArchitecture().GetTriple().getVendor() ==
llvm::Triple::VendorType::Apple) {
auto process_wp = ProcessWP(process.shared_from_this());
@@ -1459,20 +1454,20 @@ Status StructuredDataDarwinLog::FilterLaunchInfo(ProcessLaunchInfo &launch_info,
Target *target) {
Status error;
- // If we're not debugging this launched process, there's nothing for us
- // to do here.
+ // If we're not debugging this launched process, there's nothing for us to do
+ // here.
if (!launch_info.GetFlags().AnySet(eLaunchFlagDebug))
return error;
// Darwin os_log() support automatically adds debug-level and info-level
// messages when a debugger is attached to a process. However, with
- // integrated suppport for debugging built into the command-line LLDB,
- // the user may specifically set to *not* include debug-level and info-level
- // content. When the user is using the integrated log support, we want
- // to put the kabosh on that automatic adding of info and debug level.
- // This is done by adding an environment variable to the process on launch.
- // (This also means it is not possible to suppress this behavior if
- // attaching to an already-running app).
+ // integrated support for debugging built into the command-line LLDB, the
+ // user may specifically set to *not* include debug-level and info-level
+ // content. When the user is using the integrated log support, we want to
+ // put the kabosh on that automatic adding of info and debug level. This is
+ // done by adding an environment variable to the process on launch. (This
+ // also means it is not possible to suppress this behavior if attaching to an
+ // already-running app).
// Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
// If the target architecture is not one that supports DarwinLog, we have
@@ -1483,20 +1478,19 @@ Status StructuredDataDarwinLog::FilterLaunchInfo(ProcessLaunchInfo &launch_info,
return error;
}
- // If DarwinLog is not enabled (either by explicit user command or via
- // the auto-enable option), then we have nothing to do.
+ // If DarwinLog is not enabled (either by explicit user command or via the
+ // auto-enable option), then we have nothing to do.
if (!GetGlobalProperties()->GetEnableOnStartup() &&
!s_is_explicitly_enabled) {
// Nothing to do, DarwinLog is not enabled.
return error;
}
- // If we don't have parsed configuration info, that implies we have
- // enable-on-startup set up, but we haven't yet attempted to run the
- // enable command.
+ // If we don't have parsed configuration info, that implies we have enable-
+ // on-startup set up, but we haven't yet attempted to run the enable command.
if (!target) {
- // We really can't do this without a target. We need to be able
- // to get to the debugger to get the proper options to do this right.
+ // We really can't do this without a target. We need to be able to get to
+ // the debugger to get the proper options to do this right.
// TODO log.
error.SetErrorString("requires a target to auto-enable DarwinLog.");
return error;
@@ -1509,34 +1503,28 @@ Status StructuredDataDarwinLog::FilterLaunchInfo(ProcessLaunchInfo &launch_info,
if (!options_sp || !error.Success())
return error;
- // We already parsed the options, save them now so we don't generate
- // them again until the user runs the command manually.
+ // We already parsed the options, save them now so we don't generate them
+ // again until the user runs the command manually.
SetGlobalEnableOptions(debugger_sp, options_sp);
}
- auto &env_vars = launch_info.GetEnvironmentEntries();
if (!options_sp->GetEchoToStdErr()) {
- // The user doesn't want to see os_log/NSLog messages echo to stderr.
- // That mechanism is entirely separate from the DarwinLog support.
- // By default we don't want to get it via stderr, because that would
- // be in duplicate of the explicit log support here.
+ // The user doesn't want to see os_log/NSLog messages echo to stderr. That
+ // mechanism is entirely separate from the DarwinLog support. By default we
+ // don't want to get it via stderr, because that would be in duplicate of
+ // the explicit log support here.
// Here we need to strip out any OS_ACTIVITY_DT_MODE setting to prevent
// echoing of os_log()/NSLog() to stderr in the target program.
- size_t argument_index;
- if (env_vars.ContainsEnvironmentVariable(
- llvm::StringRef("OS_ACTIVITY_DT_MODE"), &argument_index))
- env_vars.DeleteArgumentAtIndex(argument_index);
+ launch_info.GetEnvironment().erase("OS_ACTIVITY_DT_MODE");
- // We will also set the env var that tells any downstream launcher
- // from adding OS_ACTIVITY_DT_MODE.
- env_vars.AddOrReplaceEnvironmentVariable(
- llvm::StringRef("IDE_DISABLED_OS_ACTIVITY_DT_MODE"),
- llvm::StringRef("1"));
+ // We will also set the env var that tells any downstream launcher from
+ // adding OS_ACTIVITY_DT_MODE.
+ launch_info.GetEnvironment()["IDE_DISABLED_OS_ACTIVITY_DT_MODE"] = "1";
}
- // Set the OS_ACTIVITY_MODE env var appropriately to enable/disable
- // debug and info level messages.
+ // Set the OS_ACTIVITY_MODE env var appropriately to enable/disable debug and
+ // info level messages.
const char *env_var_value;
if (options_sp->GetIncludeDebugLevel())
env_var_value = "debug";
@@ -1545,10 +1533,7 @@ Status StructuredDataDarwinLog::FilterLaunchInfo(ProcessLaunchInfo &launch_info,
else
env_var_value = "default";
- if (env_var_value) {
- launch_info.GetEnvironmentEntries().AddOrReplaceEnvironmentVariable(
- llvm::StringRef("OS_ACTIVITY_MODE"), llvm::StringRef(env_var_value));
- }
+ launch_info.GetEnvironment()["OS_ACTIVITY_MODE"] = env_var_value;
return error;
}
@@ -1558,8 +1543,8 @@ bool StructuredDataDarwinLog::InitCompletionHookCallback(
lldb::user_id_t break_loc_id) {
// We hit the init function. We now want to enqueue our new thread plan,
// which will in turn enqueue a StepOut thread plan. When the StepOut
- // finishes and control returns to our new thread plan, that is the time
- // when we can execute our logic to enable the logging support.
+ // finishes and control returns to our new thread plan, that is the time when
+ // we can execute our logic to enable the logging support.
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
if (log)
@@ -1618,8 +1603,8 @@ bool StructuredDataDarwinLog::InitCompletionHookCallback(
process_uid);
return;
}
- // Make sure we only call it once, just in case the
- // thread plan hits the breakpoint twice.
+ // Make sure we only call it once, just in case the thread plan hits
+ // the breakpoint twice.
if (!called_enable_method) {
if (log)
log->Printf("StructuredDataDarwinLog::post-init callback: "
@@ -1629,8 +1614,8 @@ bool StructuredDataDarwinLog::InitCompletionHookCallback(
->EnableNow();
called_enable_method = true;
} else {
- // Our breakpoint was hit more than once. Unexpected but
- // no harm done. Log it.
+ // Our breakpoint was hit more than once. Unexpected but no harm
+ // done. Log it.
if (log)
log->Printf("StructuredDataDarwinLog::post-init callback: "
"skipping EnableNow(), already called by "
@@ -1687,8 +1672,8 @@ void StructuredDataDarwinLog::AddInitCompletionHook(Process &process) {
m_added_breakpoint = true;
}
- // Set a breakpoint for the process that will kick in when libtrace
- // has finished its initialization.
+ // Set a breakpoint for the process that will kick in when libtrace has
+ // finished its initialization.
Target &target = process.GetTarget();
// Build up the module list.
@@ -1793,8 +1778,8 @@ StructuredDataDarwinLog::DumpHeader(Stream &output_stream,
if (header_count > 0)
stream.PutChar(',');
- // Display the activity chain, from parent-most to child-most
- // activity, separated by a colon (:).
+ // Display the activity chain, from parent-most to child-most activity,
+ // separated by a colon (:).
stream.PutCString("activity-chain=");
stream.PutCString(activity_chain);
++header_count;
@@ -1836,8 +1821,8 @@ size_t StructuredDataDarwinLog::HandleDisplayOfEvent(
// Check the type of the event.
ConstString event_type;
if (!event.GetValueForKeyAsString("type", event_type)) {
- // Hmm, we expected to get events that describe
- // what they are. Continue anyway.
+ // Hmm, we expected to get events that describe what they are. Continue
+ // anyway.
return 0;
}
@@ -1885,10 +1870,10 @@ void StructuredDataDarwinLog::EnableNow() {
log->Printf("StructuredDataDarwinLog::%s() call is for process uid %u",
__FUNCTION__, process_sp->GetUniqueID());
- // If we have configuration data, we can directly enable it now.
- // Otherwise, we need to run through the command interpreter to parse
- // the auto-run options (which is the only way we get here without having
- // already-parsed configuration data).
+ // If we have configuration data, we can directly enable it now. Otherwise,
+ // we need to run through the command interpreter to parse the auto-run
+ // options (which is the only way we get here without having already-parsed
+ // configuration data).
DebuggerSP debugger_sp =
process_sp->GetTarget().GetDebugger().shared_from_this();
if (!debugger_sp) {
@@ -1901,8 +1886,8 @@ void StructuredDataDarwinLog::EnableNow() {
auto options_sp = GetGlobalEnableOptions(debugger_sp);
if (!options_sp) {
- // We haven't run the enable command yet. Just do that now, it'll
- // take care of the rest.
+ // We haven't run the enable command yet. Just do that now, it'll take
+ // care of the rest.
auto &interpreter = debugger_sp->GetCommandInterpreter();
const bool success = RunEnableCommand(interpreter);
if (log) {
@@ -1925,8 +1910,8 @@ void StructuredDataDarwinLog::EnableNow() {
return;
}
- // We've previously been enabled. We will re-enable now with the
- // previously specified options.
+ // We've previously been enabled. We will re-enable now with the previously
+ // specified options.
auto config_sp = options_sp->BuildConfigurationData(true);
if (!config_sp) {
if (log)
diff --git a/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp b/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
new file mode 100644
index 000000000000..db75cf9c3bb3
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
@@ -0,0 +1,177 @@
+//===-- AppleDWARFIndex.cpp ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/SymbolFile/DWARF/AppleDWARFIndex.h"
+#include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
+#include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h"
+#include "Plugins/SymbolFile/DWARF/DWARFUnit.h"
+#include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h"
+
+#include "lldb/Core/Module.h"
+#include "lldb/Symbol/Function.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+std::unique_ptr<AppleDWARFIndex> AppleDWARFIndex::Create(
+ Module &module, DWARFDataExtractor apple_names,
+ DWARFDataExtractor apple_namespaces, DWARFDataExtractor apple_types,
+ DWARFDataExtractor apple_objc, DWARFDataExtractor debug_str) {
+ auto apple_names_table_up = llvm::make_unique<DWARFMappedHash::MemoryTable>(
+ apple_names, debug_str, ".apple_names");
+ if (!apple_names_table_up->IsValid())
+ apple_names_table_up.reset();
+
+ auto apple_namespaces_table_up =
+ llvm::make_unique<DWARFMappedHash::MemoryTable>(
+ apple_namespaces, debug_str, ".apple_namespaces");
+ if (!apple_namespaces_table_up->IsValid())
+ apple_namespaces_table_up.reset();
+
+ auto apple_types_table_up = llvm::make_unique<DWARFMappedHash::MemoryTable>(
+ apple_types, debug_str, ".apple_types");
+ if (!apple_types_table_up->IsValid())
+ apple_types_table_up.reset();
+
+ auto apple_objc_table_up = llvm::make_unique<DWARFMappedHash::MemoryTable>(
+ apple_objc, debug_str, ".apple_objc");
+ if (!apple_objc_table_up->IsValid())
+ apple_objc_table_up.reset();
+
+ if (apple_names_table_up || apple_names_table_up || apple_types_table_up ||
+ apple_objc_table_up)
+ return llvm::make_unique<AppleDWARFIndex>(
+ module, std::move(apple_names_table_up),
+ std::move(apple_namespaces_table_up), std::move(apple_types_table_up),
+ std::move(apple_objc_table_up));
+
+ return nullptr;
+}
+
+void AppleDWARFIndex::GetGlobalVariables(ConstString basename, DIEArray &offsets) {
+ if (m_apple_names_up)
+ m_apple_names_up->FindByName(basename.GetStringRef(), offsets);
+}
+
+void AppleDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
+ DIEArray &offsets) {
+ if (!m_apple_names_up)
+ return;
+
+ DWARFMappedHash::DIEInfoArray hash_data;
+ if (m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data))
+ DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
+}
+
+void AppleDWARFIndex::GetGlobalVariables(const DWARFUnit &cu,
+ DIEArray &offsets) {
+ if (!m_apple_names_up)
+ return;
+
+ DWARFMappedHash::DIEInfoArray hash_data;
+ if (m_apple_names_up->AppendAllDIEsInRange(
+ cu.GetOffset(), cu.GetNextCompileUnitOffset(), hash_data))
+ DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
+}
+
+void AppleDWARFIndex::GetObjCMethods(ConstString class_name,
+ DIEArray &offsets) {
+ if (m_apple_objc_up)
+ m_apple_objc_up->FindByName(class_name.GetStringRef(), offsets);
+}
+
+void AppleDWARFIndex::GetCompleteObjCClass(ConstString class_name,
+ bool must_be_implementation,
+ DIEArray &offsets) {
+ if (m_apple_types_up) {
+ m_apple_types_up->FindCompleteObjCClassByName(
+ class_name.GetStringRef(), offsets, must_be_implementation);
+ }
+}
+
+void AppleDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) {
+ if (m_apple_types_up)
+ m_apple_types_up->FindByName(name.GetStringRef(), offsets);
+}
+
+void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context,
+ DIEArray &offsets) {
+ if (!m_apple_types_up)
+ return;
+
+ Log *log = LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION |
+ DWARF_LOG_LOOKUPS);
+ const bool has_tag = m_apple_types_up->GetHeader().header_data.ContainsAtom(
+ DWARFMappedHash::eAtomTypeTag);
+ const bool has_qualified_name_hash =
+ m_apple_types_up->GetHeader().header_data.ContainsAtom(
+ DWARFMappedHash::eAtomTypeQualNameHash);
+ const ConstString type_name(context[0].name);
+ const dw_tag_t tag = context[0].tag;
+ if (has_tag && has_qualified_name_hash) {
+ const char *qualified_name = context.GetQualifiedName();
+ const uint32_t qualified_name_hash = llvm::djbHash(qualified_name);
+ if (log)
+ m_module.LogMessage(log, "FindByNameAndTagAndQualifiedNameHash()");
+ m_apple_types_up->FindByNameAndTagAndQualifiedNameHash(
+ type_name.GetStringRef(), tag, qualified_name_hash, offsets);
+ } else if (has_tag) {
+ if (log)
+ m_module.LogMessage(log, "FindByNameAndTag()");
+ m_apple_types_up->FindByNameAndTag(type_name.GetStringRef(), tag, offsets);
+ } else
+ m_apple_types_up->FindByName(type_name.GetStringRef(), offsets);
+}
+
+void AppleDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) {
+ if (m_apple_namespaces_up)
+ m_apple_namespaces_up->FindByName(name.GetStringRef(), offsets);
+}
+
+void AppleDWARFIndex::GetFunctions(ConstString name, DWARFDebugInfo &info,
+ const CompilerDeclContext &parent_decl_ctx,
+ uint32_t name_type_mask,
+ std::vector<DWARFDIE> &dies) {
+ DIEArray offsets;
+ m_apple_names_up->FindByName(name.GetStringRef(), offsets);
+ for (const DIERef &die_ref : offsets) {
+ ProcessFunctionDIE(name.GetStringRef(), die_ref, info, parent_decl_ctx,
+ name_type_mask, dies);
+ }
+}
+
+void AppleDWARFIndex::GetFunctions(const RegularExpression &regex,
+ DIEArray &offsets) {
+ if (!m_apple_names_up)
+ return;
+
+ DWARFMappedHash::DIEInfoArray hash_data;
+ if (m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data))
+ DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
+}
+
+void AppleDWARFIndex::ReportInvalidDIEOffset(dw_offset_t offset,
+ llvm::StringRef name) {
+ m_module.ReportErrorIfModifyDetected(
+ "the DWARF debug information has been modified (accelerator table had "
+ "bad die 0x%8.8x for '%s')\n",
+ offset, name.str().c_str());
+}
+
+void AppleDWARFIndex::Dump(Stream &s) {
+ if (m_apple_names_up)
+ s.PutCString(".apple_names index present\n");
+ if (m_apple_namespaces_up)
+ s.PutCString(".apple_namespaces index present\n");
+ if (m_apple_types_up)
+ s.PutCString(".apple_types index present\n");
+ if (m_apple_objc_up)
+ s.PutCString(".apple_objc index present\n");
+ // TODO: Dump index contents
+}
diff --git a/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h b/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
new file mode 100644
index 000000000000..ea133d0e73cf
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
@@ -0,0 +1,64 @@
+//===-- AppleDWARFIndex.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_APPLEDWARFINDEX_H
+#define LLDB_APPLEDWARFINDEX_H
+
+#include "Plugins/SymbolFile/DWARF/DWARFIndex.h"
+#include "Plugins/SymbolFile/DWARF/HashedNameToDIE.h"
+
+namespace lldb_private {
+class AppleDWARFIndex : public DWARFIndex {
+public:
+ static std::unique_ptr<AppleDWARFIndex>
+ Create(Module &module, DWARFDataExtractor apple_names,
+ DWARFDataExtractor apple_namespaces, DWARFDataExtractor apple_types,
+ DWARFDataExtractor apple_objc, DWARFDataExtractor debug_str);
+
+ AppleDWARFIndex(
+ Module &module, std::unique_ptr<DWARFMappedHash::MemoryTable> apple_names,
+ std::unique_ptr<DWARFMappedHash::MemoryTable> apple_namespaces,
+ std::unique_ptr<DWARFMappedHash::MemoryTable> apple_types,
+ std::unique_ptr<DWARFMappedHash::MemoryTable> apple_objc)
+ : DWARFIndex(module), m_apple_names_up(std::move(apple_names)),
+ m_apple_namespaces_up(std::move(apple_namespaces)),
+ m_apple_types_up(std::move(apple_types)),
+ m_apple_objc_up(std::move(apple_objc)) {}
+
+ void Preload() override {}
+
+ void GetGlobalVariables(ConstString basename, DIEArray &offsets) override;
+ void GetGlobalVariables(const RegularExpression &regex,
+ DIEArray &offsets) override;
+ void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) override;
+ void GetObjCMethods(ConstString class_name, DIEArray &offsets) override;
+ void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation,
+ DIEArray &offsets) override;
+ void GetTypes(ConstString name, DIEArray &offsets) override;
+ void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) override;
+ void GetNamespaces(ConstString name, DIEArray &offsets) override;
+ void GetFunctions(ConstString name, DWARFDebugInfo &info,
+ const CompilerDeclContext &parent_decl_ctx,
+ uint32_t name_type_mask,
+ std::vector<DWARFDIE> &dies) override;
+ void GetFunctions(const RegularExpression &regex, DIEArray &offsets) override;
+
+ void ReportInvalidDIEOffset(dw_offset_t offset,
+ llvm::StringRef name) override;
+ void Dump(Stream &s) override;
+
+private:
+ std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_names_up;
+ std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_namespaces_up;
+ std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_types_up;
+ std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_objc_up;
+};
+} // namespace lldb_private
+
+#endif // LLDB_APPLEDWARFINDEX_H
diff --git a/source/Plugins/SymbolFile/DWARF/CMakeLists.txt b/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
index 05d9e6642868..f62a496f808a 100644
--- a/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
+++ b/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
@@ -1,4 +1,6 @@
add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN
+ AppleDWARFIndex.cpp
+ DebugNamesDWARFIndex.cpp
DIERef.cpp
DWARFAbbreviationDeclaration.cpp
DWARFASTParserClang.cpp
@@ -6,6 +8,7 @@ add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN
DWARFASTParserJava.cpp
DWARFASTParserOCaml.cpp
DWARFAttribute.cpp
+ DWARFBaseDIE.cpp
DWARFCompileUnit.cpp
DWARFDataExtractor.cpp
DWARFDebugAbbrev.cpp
@@ -17,16 +20,17 @@ add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN
DWARFDebugMacro.cpp
DWARFDebugMacinfo.cpp
DWARFDebugMacinfoEntry.cpp
- DWARFDebugPubnames.cpp
- DWARFDebugPubnamesSet.cpp
DWARFDebugRanges.cpp
DWARFDeclContext.cpp
DWARFDefines.cpp
DWARFDIE.cpp
DWARFDIECollection.cpp
DWARFFormValue.cpp
+ DWARFIndex.cpp
+ DWARFUnit.cpp
HashedNameToDIE.cpp
LogChannelDWARF.cpp
+ ManualDWARFIndex.cpp
NameToDIE.cpp
SymbolFileDWARF.cpp
SymbolFileDWARFDwo.cpp
diff --git a/source/Plugins/SymbolFile/DWARF/DIERef.cpp b/source/Plugins/SymbolFile/DWARF/DIERef.cpp
index c05444c031e6..0cd0f0c0272a 100644
--- a/source/Plugins/SymbolFile/DWARF/DIERef.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DIERef.cpp
@@ -8,17 +8,12 @@
//===----------------------------------------------------------------------===//
#include "DIERef.h"
-#include "DWARFCompileUnit.h"
+#include "DWARFUnit.h"
#include "DWARFDebugInfo.h"
#include "DWARFFormValue.h"
#include "SymbolFileDWARF.h"
#include "SymbolFileDWARFDebugMap.h"
-DIERef::DIERef()
- : cu_offset(DW_INVALID_OFFSET), die_offset(DW_INVALID_OFFSET) {}
-
-DIERef::DIERef(dw_offset_t c, dw_offset_t d) : cu_offset(c), die_offset(d) {}
-
DIERef::DIERef(lldb::user_id_t uid, SymbolFileDWARF *dwarf)
: cu_offset(DW_INVALID_OFFSET), die_offset(uid & 0xffffffff) {
SymbolFileDWARFDebugMap *debug_map = dwarf->GetDebugMapSymfile();
@@ -28,7 +23,7 @@ DIERef::DIERef(lldb::user_id_t uid, SymbolFileDWARF *dwarf)
if (actual_dwarf) {
DWARFDebugInfo *debug_info = actual_dwarf->DebugInfo();
if (debug_info) {
- DWARFCompileUnit *dwarf_cu =
+ DWARFUnit *dwarf_cu =
debug_info->GetCompileUnitContainingDIEOffset(die_offset);
if (dwarf_cu) {
cu_offset = dwarf_cu->GetOffset();
@@ -45,7 +40,7 @@ DIERef::DIERef(lldb::user_id_t uid, SymbolFileDWARF *dwarf)
DIERef::DIERef(const DWARFFormValue &form_value)
: cu_offset(DW_INVALID_OFFSET), die_offset(DW_INVALID_OFFSET) {
if (form_value.IsValid()) {
- const DWARFCompileUnit *dwarf_cu = form_value.GetCompileUnit();
+ const DWARFUnit *dwarf_cu = form_value.GetCompileUnit();
if (dwarf_cu) {
if (dwarf_cu->GetBaseObjOffset() != DW_INVALID_OFFSET)
cu_offset = dwarf_cu->GetBaseObjOffset();
diff --git a/source/Plugins/SymbolFile/DWARF/DIERef.h b/source/Plugins/SymbolFile/DWARF/DIERef.h
index d0048d0f6d6b..cb28c890c25a 100644
--- a/source/Plugins/SymbolFile/DWARF/DIERef.h
+++ b/source/Plugins/SymbolFile/DWARF/DIERef.h
@@ -17,9 +17,9 @@ class DWARFFormValue;
class SymbolFileDWARF;
struct DIERef {
- DIERef();
+ DIERef() = default;
- DIERef(dw_offset_t c, dw_offset_t d);
+ DIERef(dw_offset_t c, dw_offset_t d) : cu_offset(c), die_offset(d) {}
//----------------------------------------------------------------------
// In order to properly decode a lldb::user_id_t back into a DIERef we
@@ -45,8 +45,12 @@ struct DIERef {
bool operator<(const DIERef &ref) { return die_offset < ref.die_offset; }
- dw_offset_t cu_offset;
- dw_offset_t die_offset;
+ explicit operator bool() const {
+ return cu_offset != DW_INVALID_OFFSET || die_offset != DW_INVALID_OFFSET;
+ }
+
+ dw_offset_t cu_offset = DW_INVALID_OFFSET;
+ dw_offset_t die_offset = DW_INVALID_OFFSET;
};
typedef std::vector<DIERef> DIEArray;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 54b12cfb3b8c..fe6f1be3ca48 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -10,13 +10,13 @@
#include <stdlib.h>
#include "DWARFASTParserClang.h"
-#include "DWARFCompileUnit.h"
#include "DWARFDIE.h"
#include "DWARFDIECollection.h"
#include "DWARFDebugInfo.h"
#include "DWARFDeclContext.h"
#include "DWARFDefines.h"
#include "SymbolFileDWARF.h"
+#include "SymbolFileDWARFDwo.h"
#include "SymbolFileDWARFDebugMap.h"
#include "UniqueDWARFASTType.h"
@@ -24,7 +24,6 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/Value.h"
#include "lldb/Host/Host.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/ClangUtil.h"
@@ -39,8 +38,10 @@
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"
+#include "clang/AST/CXXInheritance.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
#include <map>
#include <vector>
@@ -105,9 +106,9 @@ struct BitfieldInfo {
bool NextBitfieldOffsetIsValid(const uint64_t next_bit_offset) const {
if (IsValid()) {
- // This bitfield info is valid, so any subsequent bitfields
- // must not overlap and must be at a higher bit offset than
- // any previous bitfield + size.
+ // This bitfield info is valid, so any subsequent bitfields must not
+ // overlap and must be at a higher bit offset than any previous bitfield
+ // + size.
return (bit_size + bit_offset) <= next_bit_offset;
} else {
// If the this BitfieldInfo is not valid, then any offset isOK
@@ -123,57 +124,108 @@ ClangASTImporter &DWARFASTParserClang::GetClangASTImporter() {
return *m_clang_ast_importer_ap;
}
+/// Detect a forward declaration that is nested in a DW_TAG_module.
+static bool isClangModuleFwdDecl(const DWARFDIE &Die) {
+ if (!Die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0))
+ return false;
+ auto Parent = Die.GetParent();
+ while (Parent.IsValid()) {
+ if (Parent.Tag() == DW_TAG_module)
+ return true;
+ Parent = Parent.GetParent();
+ }
+ return false;
+}
+
TypeSP DWARFASTParserClang::ParseTypeFromDWO(const DWARFDIE &die, Log *log) {
ModuleSP dwo_module_sp = die.GetContainingDWOModule();
- if (dwo_module_sp) {
- // This type comes from an external DWO module
- std::vector<CompilerContext> dwo_context;
- die.GetDWOContext(dwo_context);
- TypeMap dwo_types;
- if (dwo_module_sp->GetSymbolVendor()->FindTypes(dwo_context, true,
- dwo_types)) {
- const size_t num_dwo_types = dwo_types.GetSize();
- if (num_dwo_types == 1) {
- // We found a real definition for this type elsewhere
- // so lets use it and cache the fact that we found
- // a complete type for this die
- TypeSP dwo_type_sp = dwo_types.GetTypeAtIndex(0);
- if (dwo_type_sp) {
- lldb_private::CompilerType dwo_type =
- dwo_type_sp->GetForwardCompilerType();
+ if (!dwo_module_sp)
+ return TypeSP();
- lldb_private::CompilerType type =
- GetClangASTImporter().CopyType(m_ast, dwo_type);
+ // This type comes from an external DWO module.
+ std::vector<CompilerContext> dwo_context;
+ die.GetDWOContext(dwo_context);
+ TypeMap dwo_types;
- // printf ("copied_qual_type: ast = %p, clang_type = %p, name =
- // '%s'\n", m_ast, copied_qual_type.getAsOpaquePtr(),
- // external_type->GetName().GetCString());
- if (type) {
- SymbolFileDWARF *dwarf = die.GetDWARF();
- TypeSP type_sp(new Type(die.GetID(), dwarf, dwo_type_sp->GetName(),
- dwo_type_sp->GetByteSize(), NULL,
- LLDB_INVALID_UID, Type::eEncodingInvalid,
- &dwo_type_sp->GetDeclaration(), type,
- Type::eResolveStateForward));
+ if (!dwo_module_sp->GetSymbolVendor()->FindTypes(dwo_context, true,
+ dwo_types)) {
+ if (!isClangModuleFwdDecl(die))
+ return TypeSP();
- dwarf->GetTypeList()->Insert(type_sp);
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- clang::TagDecl *tag_decl = ClangASTContext::GetAsTagDecl(type);
- if (tag_decl)
- LinkDeclContextToDIE(tag_decl, die);
- else {
- clang::DeclContext *defn_decl_ctx =
- GetCachedClangDeclContextForDIE(die);
- if (defn_decl_ctx)
- LinkDeclContextToDIE(defn_decl_ctx, die);
- }
- return type_sp;
- }
- }
- }
+ // Since this this type is defined in one of the Clang modules imported by
+ // this symbol file, search all of them.
+ auto *SymFile = die.GetCU()->GetSymbolFileDWARF();
+ for (const auto &NameModule : SymFile->getExternalTypeModules()) {
+ if (!NameModule.second)
+ continue;
+ SymbolVendor *SymVendor = NameModule.second->GetSymbolVendor();
+ if (SymVendor->FindTypes(dwo_context, true, dwo_types))
+ break;
}
}
- return TypeSP();
+
+ const size_t num_dwo_types = dwo_types.GetSize();
+ if (num_dwo_types != 1)
+ return TypeSP();
+
+ // We found a real definition for this type in the Clang module, so lets use
+ // it and cache the fact that we found a complete type for this die.
+ TypeSP dwo_type_sp = dwo_types.GetTypeAtIndex(0);
+ if (!dwo_type_sp)
+ return TypeSP();
+
+ lldb_private::CompilerType dwo_type = dwo_type_sp->GetForwardCompilerType();
+
+ lldb_private::CompilerType type =
+ GetClangASTImporter().CopyType(m_ast, dwo_type);
+
+ if (!type)
+ return TypeSP();
+
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ TypeSP type_sp(new Type(
+ die.GetID(), dwarf, dwo_type_sp->GetName(), dwo_type_sp->GetByteSize(),
+ NULL, LLDB_INVALID_UID, Type::eEncodingInvalid,
+ &dwo_type_sp->GetDeclaration(), type, Type::eResolveStateForward));
+
+ dwarf->GetTypeList()->Insert(type_sp);
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ clang::TagDecl *tag_decl = ClangASTContext::GetAsTagDecl(type);
+ if (tag_decl)
+ LinkDeclContextToDIE(tag_decl, die);
+ else {
+ clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(die);
+ if (defn_decl_ctx)
+ LinkDeclContextToDIE(defn_decl_ctx, die);
+ }
+
+ return type_sp;
+}
+
+static void CompleteExternalTagDeclType(ClangASTImporter &ast_importer,
+ clang::DeclContext *decl_ctx,
+ DWARFDIE die,
+ const char *type_name_cstr) {
+ auto *tag_decl_ctx = clang::dyn_cast<clang::TagDecl>(decl_ctx);
+ if (!tag_decl_ctx)
+ return;
+
+ // If this type was not imported from an external AST, there's nothing to do.
+ CompilerType type = ClangASTContext::GetTypeForDecl(tag_decl_ctx);
+ if (!type || !ast_importer.CanImport(type))
+ return;
+
+ auto qual_type = ClangUtil::GetQualType(type);
+ if (!ast_importer.RequireCompleteType(qual_type)) {
+ die.GetDWARF()->GetObjectFile()->GetModule()->ReportError(
+ "Unable to complete the Decl context for DIE '%s' at offset "
+ "0x%8.8x.\nPlease file a bug report.",
+ type_name_cstr ? type_name_cstr : "", die.GetOffset());
+ // We need to make the type look complete otherwise, we might crash in
+ // Clang when adding children.
+ if (ClangASTContext::StartTagDeclarationDefinition(type))
+ ClangASTContext::CompleteTagDeclarationDefinition(type);
+ }
}
TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
@@ -198,17 +250,6 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
die.GetOffset(), static_cast<void *>(context),
context_die.GetOffset(), die.GetTagAsCString(), die.GetName());
}
- //
- // Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
- // if (log && dwarf_cu)
- // {
- // StreamString s;
- // die->DumpLocation (this, dwarf_cu, s);
- // dwarf->GetObjectFile()->GetModule()->LogMessage (log,
- // "SymbolFileDwarf::%s %s", __FUNCTION__, s.GetData());
- //
- // }
-
Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE());
TypeList *type_list = dwarf->GetTypeList();
if (type_ptr == NULL) {
@@ -220,6 +261,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
bool is_forward_declaration = false;
DWARFAttributes attributes;
const char *type_name_cstr = NULL;
+ const char *mangled_name_cstr = NULL;
ConstString type_name_const_str;
Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
uint64_t byte_size = 0;
@@ -268,8 +310,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
type_name_cstr = form_value.AsCString();
// Work around a bug in llvm-gcc where they give a name to a
- // reference type which doesn't
- // include the "&"...
+ // reference type which doesn't include the "&"...
if (tag == DW_TAG_reference_type) {
if (strchr(type_name_cstr, '&') == NULL)
type_name_cstr = NULL;
@@ -295,32 +336,32 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
}
if (tag == DW_TAG_typedef && encoding_uid.IsValid()) {
- // Try to parse a typedef from the DWO file first as modules
- // can contain typedef'ed structures that have no names like:
+ // Try to parse a typedef from the DWO file first as modules can
+ // contain typedef'ed structures that have no names like:
//
// typedef struct { int a; } Foo;
//
- // In this case we will have a structure with no name and a
- // typedef named "Foo" that points to this unnamed structure.
- // The name in the typedef is the only identifier for the struct,
- // so always try to get typedefs from DWO files if possible.
+ // In this case we will have a structure with no name and a typedef
+ // named "Foo" that points to this unnamed structure. The name in the
+ // typedef is the only identifier for the struct, so always try to
+ // get typedefs from DWO files if possible.
//
- // The type_sp returned will be empty if the typedef doesn't exist
- // in a DWO file, so it is cheap to call this function just to check.
+ // The type_sp returned will be empty if the typedef doesn't exist in
+ // a DWO file, so it is cheap to call this function just to check.
//
- // If we don't do this we end up creating a TypeSP that says this
- // is a typedef to type 0x123 (the DW_AT_type value would be 0x123
- // in the DW_TAG_typedef), and this is the unnamed structure type.
- // We will have a hard time tracking down an unnammed structure
- // type in the module DWO file, so we make sure we don't get into
- // this situation by always resolving typedefs from the DWO file.
+ // If we don't do this we end up creating a TypeSP that says this is
+ // a typedef to type 0x123 (the DW_AT_type value would be 0x123 in
+ // the DW_TAG_typedef), and this is the unnamed structure type. We
+ // will have a hard time tracking down an unnammed structure type in
+ // the module DWO file, so we make sure we don't get into this
+ // situation by always resolving typedefs from the DWO file.
const DWARFDIE encoding_die = dwarf->GetDIE(DIERef(encoding_uid));
- // First make sure that the die that this is typedef'ed to _is_
- // just a declaration (DW_AT_declaration == 1), not a full definition
+ // First make sure that the die that this is typedef'ed to _is_ just
+ // a declaration (DW_AT_declaration == 1), not a full definition
// since template types can't be represented in modules since only
- // concrete instances of templates are ever emitted and modules
- // won't contain those
+ // concrete instances of templates are ever emitted and modules won't
+ // contain those
if (encoding_die &&
encoding_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) ==
1) {
@@ -433,7 +474,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
if (log)
dwarf->GetObjectFile()->GetModule()->LogMessage(
log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' "
- "is Objective C 'id' built-in type.",
+ "is Objective-C 'id' built-in type.",
die.GetOffset(), die.GetTagAsCString(), die.GetName());
clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
encoding_data_type = Type::eEncodingIsUID;
@@ -444,7 +485,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
if (log)
dwarf->GetObjectFile()->GetModule()->LogMessage(
log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' "
- "is Objective C 'Class' built-in type.",
+ "is Objective-C 'Class' built-in type.",
die.GetOffset(), die.GetTagAsCString(), die.GetName());
clang_type = m_ast.GetBasicType(eBasicTypeObjCClass);
encoding_data_type = Type::eEncodingIsUID;
@@ -454,7 +495,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
if (log)
dwarf->GetObjectFile()->GetModule()->LogMessage(
log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' "
- "is Objective C 'selector' built-in type.",
+ "is Objective-C 'selector' built-in type.",
die.GetOffset(), die.GetTagAsCString(), die.GetName());
clang_type = m_ast.GetBasicType(eBasicTypeObjCSel);
encoding_data_type = Type::eEncodingIsUID;
@@ -495,17 +536,6 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
&decl, clang_type, resolve_state));
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
-
- // Type* encoding_type =
- // GetUniquedTypeForDIEOffset(encoding_uid, type_sp,
- // NULL, 0, 0, false);
- // if (encoding_type != NULL)
- // {
- // if (encoding_type != DIE_IS_BEING_PARSED)
- // type_sp->SetEncodingType(encoding_type);
- // else
- // m_indirect_fixups.push_back(type_sp.get());
- // }
} break;
case DW_TAG_structure_type:
@@ -517,7 +547,9 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
LanguageType class_language = eLanguageTypeUnknown;
bool is_complete_objc_class = false;
- // bool struct_is_class = false;
+ size_t calling_convention
+ = llvm::dwarf::CallingConvention::DW_CC_normal;
+
const size_t num_attributes = die.GetAttributes(attributes);
if (num_attributes > 0) {
uint32_t i;
@@ -528,10 +560,9 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
case DW_AT_decl_file:
if (die.GetCU()->DW_AT_decl_file_attributes_are_invalid()) {
// llvm-gcc outputs invalid DW_AT_decl_file attributes that
- // always
- // point to the compile unit file, so we clear this invalid
- // value
- // so that we can still unique types efficiently.
+ // always point to the compile unit file, so we clear this
+ // invalid value so that we can still unique types
+ // efficiently.
decl.SetFile(FileSpec("<invalid>", false));
} else
decl.SetFile(
@@ -572,7 +603,10 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
case DW_AT_APPLE_objc_complete_type:
is_complete_objc_class = form_value.Signed();
break;
-
+ case DW_AT_calling_convention:
+ calling_convention = form_value.Unsigned();
+ break;
+
case DW_AT_allocated:
case DW_AT_associated:
case DW_AT_data_location:
@@ -587,10 +621,10 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
}
}
- // UniqueDWARFASTType is large, so don't create a local variables on the
- // stack, put it on the heap. This function is often called recursively
- // and clang isn't good and sharing the stack space for variables in
- // different blocks.
+ // UniqueDWARFASTType is large, so don't create a local variables on
+ // the stack, put it on the heap. This function is often called
+ // recursively and clang isn't good and sharing the stack space for
+ // variables in different blocks.
std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_ap(
new UniqueDWARFASTType());
@@ -601,10 +635,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
LanguageType die_language = die.GetLanguage();
if (Language::LanguageIsCPlusPlus(die_language)) {
// For C++, we rely solely upon the one definition rule that says
- // only
- // one thing can exist at a given decl context. We ignore the file
- // and
- // line that things are declared on.
+ // only one thing can exist at a given decl context. We ignore the
+ // file and line that things are declared on.
std::string qualified_name;
if (die.GetQualifiedName(qualified_name))
unique_typename = ConstString(qualified_name);
@@ -641,17 +673,16 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
if (byte_size_valid && byte_size == 0 && type_name_cstr &&
die.HasChildren() == false &&
sc.comp_unit->GetLanguage() == eLanguageTypeObjC) {
- // Work around an issue with clang at the moment where
- // forward declarations for objective C classes are emitted
- // as:
+ // Work around an issue with clang at the moment where forward
+ // declarations for objective C classes are emitted as:
// DW_TAG_structure_type [2]
// DW_AT_name( "ForwardObjcClass" )
// DW_AT_byte_size( 0x00 )
// DW_AT_decl_file( "..." )
// DW_AT_decl_line( 1 )
//
- // Note that there is no DW_AT_declaration and there are
- // no children, and the byte size is zero.
+ // Note that there is no DW_AT_declaration and there are no children,
+ // and the byte size is zero.
is_forward_declaration = true;
}
@@ -659,11 +690,11 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
class_language == eLanguageTypeObjC_plus_plus) {
if (!is_complete_objc_class &&
die.Supports_DW_AT_APPLE_objc_complete_type()) {
- // We have a valid eSymbolTypeObjCClass class symbol whose
- // name matches the current objective C class that we
- // are trying to find and this DIE isn't the complete
- // definition (we checked is_complete_objc_class above and
- // know it is false), so the real definition is in here somewhere
+ // We have a valid eSymbolTypeObjCClass class symbol whose name
+ // matches the current objective C class that we are trying to find
+ // and this DIE isn't the complete definition (we checked
+ // is_complete_objc_class above and know it is false), so the real
+ // definition is in here somewhere
type_sp = dwarf->FindCompleteObjCDefinitionTypeForDIE(
die, type_name_const_str, true);
@@ -671,9 +702,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
SymbolFileDWARFDebugMap *debug_map_symfile =
dwarf->GetDebugMapSymfile();
if (debug_map_symfile) {
- // We weren't able to find a full declaration in
- // this DWARF, see if we have a declaration anywhere
- // else...
+ // We weren't able to find a full declaration in this DWARF,
+ // see if we have a declaration anywhere else...
type_sp =
debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE(
die, type_name_const_str, true);
@@ -690,9 +720,9 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
type_sp->GetID());
}
- // We found a real definition for this type elsewhere
- // so lets use it and cache the fact that we found
- // a complete type for this die
+ // We found a real definition for this type elsewhere so lets use
+ // it and cache the fact that we found a complete type for this
+ // die
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
return type_sp;
}
@@ -700,11 +730,11 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
}
if (is_forward_declaration) {
- // We have a forward declaration to a type and we need
- // to try and find a full declaration. We look in the
- // current type index just in case we have a forward
- // declaration followed by an actual declarations in the
- // DWARF. If this fails, we need to look elsewhere...
+ // We have a forward declaration to a type and we need to try and
+ // find a full declaration. We look in the current type index just in
+ // case we have a forward declaration followed by an actual
+ // declarations in the DWARF. If this fails, we need to look
+ // elsewhere...
if (log) {
dwarf->GetObjectFile()->GetModule()->LogMessage(
log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
@@ -730,9 +760,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
SymbolFileDWARFDebugMap *debug_map_symfile =
dwarf->GetDebugMapSymfile();
if (debug_map_symfile) {
- // We weren't able to find a full declaration in
- // this DWARF, see if we have a declaration anywhere
- // else...
+ // We weren't able to find a full declaration in this DWARF, see
+ // if we have a declaration anywhere else...
type_sp =
debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(
die_decl_ctx);
@@ -748,9 +777,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
DW_TAG_value_to_name(tag), type_name_cstr, type_sp->GetID());
}
- // We found a real definition for this type elsewhere
- // so lets use it and cache the fact that we found
- // a complete type for this die
+ // We found a real definition for this type elsewhere so lets use
+ // it and cache the fact that we found a complete type for this die
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(
dwarf->DebugInfo()->GetDIE(DIERef(type_sp->GetID(), dwarf)));
@@ -766,9 +794,18 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
if (!clang_type) {
clang::DeclContext *decl_ctx =
GetClangDeclContextContainingDIE(die, nullptr);
+
+ // If your decl context is a record that was imported from another
+ // AST context (in the gmodules case), we need to make sure the type
+ // backing the Decl is complete before adding children to it. This is
+ // not an issue in the non-gmodules case because the debug info will
+ // always contain a full definition of parent types in that case.
+ CompleteExternalTagDeclType(GetClangASTImporter(), decl_ctx, die,
+ type_name_cstr);
+
if (accessibility == eAccessNone && decl_ctx) {
- // Check the decl context that contains this class/struct/union.
- // If it is a class we must give it an accessibility.
+ // Check the decl context that contains this class/struct/union. If
+ // it is a class we must give it an accessibility.
const clang::Decl::Kind containing_decl_kind =
decl_ctx->getDeclKind();
if (DeclKindIsCXXClass(containing_decl_kind))
@@ -818,10 +855,10 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
class_language, &metadata);
}
}
-
+
// Store a forward declaration to this class type in case any
- // parameters in any class methods need it for the clang
- // types for function prototypes.
+ // parameters in any class methods need it for the clang types for
+ // function prototypes.
LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die);
type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str,
byte_size, NULL, LLDB_INVALID_UID,
@@ -830,9 +867,9 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
type_sp->SetIsCompleteObjCClass(is_complete_objc_class);
- // Add our type to the unique type map so we don't
- // end up creating many copies of the same type over
- // and over in the ASTContext for our module
+ // Add our type to the unique type map so we don't end up creating many
+ // copies of the same type over and over in the ASTContext for our
+ // module
unique_ast_entry_ap->m_type_sp = type_sp;
unique_ast_entry_ap->m_die = die;
unique_ast_entry_ap->m_declaration = unique_decl;
@@ -844,8 +881,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
// Check to see if the DIE actually has a definition, some version of
// GCC will
// emit DIEs with DW_AT_declaration set to true, but yet still have
- // subprogram,
- // members, or inheritance, so we can't trust it
+ // subprogram, members, or inheritance, so we can't trust it
DWARFDIE child_die = die.GetFirstChild();
while (child_die) {
switch (child_die.Tag()) {
@@ -869,10 +905,10 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
}
if (!is_forward_declaration) {
- // Always start the definition for a class type so that
- // if the class has child classes or types that require
- // the class to be created for use as their decl contexts
- // the class will be ready to accept these child definitions.
+ // Always start the definition for a class type so that if the class
+ // has child classes or types that require the class to be created
+ // for use as their decl contexts the class will be ready to accept
+ // these child definitions.
if (die.HasChildren() == false) {
// No children for this struct/union/class, lets finish it
if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
@@ -896,33 +932,30 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
}
}
} else if (clang_type_was_created) {
- // Start the definition if the class is not objective C since
- // the underlying decls respond to isCompleteDefinition(). Objective
+ // Start the definition if the class is not objective C since the
+ // underlying decls respond to isCompleteDefinition(). Objective
// C decls don't respond to isCompleteDefinition() so we can't
// start the declaration definition right away. For C++
- // class/union/structs
- // we want to start the definition in case the class is needed as
- // the
- // declaration context for a contained class or type without the
- // need
- // to complete that type..
+ // class/union/structs we want to start the definition in case the
+ // class is needed as the declaration context for a contained class
+ // or type without the need to complete that type..
if (class_language != eLanguageTypeObjC &&
class_language != eLanguageTypeObjC_plus_plus)
ClangASTContext::StartTagDeclarationDefinition(clang_type);
- // Leave this as a forward declaration until we need
- // to know the details of the type. lldb_private::Type
- // will automatically call the SymbolFile virtual function
- // "SymbolFileDWARF::CompleteType(Type *)"
- // When the definition needs to be defined.
+ // Leave this as a forward declaration until we need to know the
+ // details of the type. lldb_private::Type will automatically call
+ // the SymbolFile virtual function
+ // "SymbolFileDWARF::CompleteType(Type *)" When the definition
+ // needs to be defined.
assert(!dwarf->GetForwardDeclClangTypeToDie().count(
ClangUtil::RemoveFastQualifiers(clang_type)
.GetOpaqueQualType()) &&
"Type already in the forward declaration map!");
- // Can't assume m_ast.GetSymbolFile() is actually a SymbolFileDWARF,
- // it can be a
- // SymbolFileDWARFDebugMap for Apple binaries.
+ // Can't assume m_ast.GetSymbolFile() is actually a
+ // SymbolFileDWARF, it can be a SymbolFileDWARFDebugMap for Apple
+ // binaries.
dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] =
clang_type.GetOpaqueQualType();
dwarf->GetForwardDeclClangTypeToDie()
@@ -931,6 +964,19 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
}
}
+
+ // If we made a clang type, set the trivial abi if applicable: We only
+ // do this for pass by value - which implies the Trivial ABI. There
+ // isn't a way to assert that something that would normally be pass by
+ // value is pass by reference, so we ignore that attribute if set.
+ if (calling_convention == llvm::dwarf::DW_CC_pass_by_value) {
+ clang::CXXRecordDecl *record_decl =
+ m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
+ if (record_decl) {
+ record_decl->setHasTrivialSpecialMemberForCall();
+ }
+ }
+
} break;
case DW_TAG_enumeration_type: {
@@ -1008,9 +1054,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
SymbolFileDWARFDebugMap *debug_map_symfile =
dwarf->GetDebugMapSymfile();
if (debug_map_symfile) {
- // We weren't able to find a full declaration in
- // this DWARF, see if we have a declaration anywhere
- // else...
+ // We weren't able to find a full declaration in this DWARF,
+ // see if we have a declaration anywhere else...
type_sp =
debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(
die_decl_ctx);
@@ -1027,9 +1072,9 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
type_sp->GetID());
}
- // We found a real definition for this type elsewhere
- // so lets use it and cache the fact that we found
- // a complete type for this die
+ // We found a real definition for this type elsewhere so lets use
+ // it and cache the fact that we found a complete type for this
+ // die
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
clang::DeclContext *defn_decl_ctx =
GetCachedClangDeclContextForDIE(dwarf->DebugInfo()->GetDIE(
@@ -1145,9 +1190,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
case DW_AT_linkage_name:
case DW_AT_MIPS_linkage_name:
- break; // mangled =
- // form_value.AsCString(&dwarf->get_debug_str_data());
- // break;
+ mangled_name_cstr = form_value.AsCString();
+ break;
case DW_AT_type:
type_die_form = form_value;
break;
@@ -1256,8 +1300,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
bool is_cxx_method = DeclKindIsCXXClass(containing_decl_kind);
// Start off static. This will be set to false in
- // ParseChildParameters(...)
- // if we find a "this" parameters as the first parameter
+ // ParseChildParameters(...) if we find a "this" parameters as the
+ // first parameter
if (is_cxx_method) {
is_static = true;
}
@@ -1272,25 +1316,22 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
bool ignore_containing_context = false;
// Check for templatized class member functions. If we had any
- // DW_TAG_template_type_parameter
- // or DW_TAG_template_value_parameter the DW_TAG_subprogram DIE, then we
- // can't let this become
- // a method in a class. Why? Because templatized functions are only
- // emitted if one of the
- // templatized methods is used in the current compile unit and we will
- // end up with classes
- // that may or may not include these member functions and this means one
- // class won't match another
- // class definition and it affects our ability to use a class in the
- // clang expression parser. So
- // for the greater good, we currently must not allow any template member
- // functions in a class definition.
+ // DW_TAG_template_type_parameter or DW_TAG_template_value_parameter
+ // the DW_TAG_subprogram DIE, then we can't let this become a method in
+ // a class. Why? Because templatized functions are only emitted if one
+ // of the templatized methods is used in the current compile unit and
+ // we will end up with classes that may or may not include these member
+ // functions and this means one class won't match another class
+ // definition and it affects our ability to use a class in the clang
+ // expression parser. So for the greater good, we currently must not
+ // allow any template member functions in a class definition.
if (is_cxx_method && has_template_params) {
ignore_containing_context = true;
is_cxx_method = false;
}
- // clang_type will get the function prototype clang type after this call
+ // clang_type will get the function prototype clang type after this
+ // call
clang_type = m_ast.CreateFunctionType(
return_clang_type, function_param_types.data(),
function_param_types.size(), is_variadic, type_quals);
@@ -1318,8 +1359,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
if (class_opaque_type) {
// If accessibility isn't set to anything valid, assume public
- // for
- // now...
+ // for now...
if (accessibility == eAccessNone)
accessibility = eAccessPublic;
@@ -1341,9 +1381,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
}
}
} else if (is_cxx_method) {
- // Look at the parent of this DIE and see if is is
- // a class or struct and see if this is actually a
- // C++ method
+ // Look at the parent of this DIE and see if is is a class or
+ // struct and see if this is actually a C++ method
Type *class_type = dwarf->ResolveType(decl_ctx_die);
if (class_type) {
bool alternate_defn = false;
@@ -1352,10 +1391,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
alternate_defn = true;
// We uniqued the parent class of this function to another
- // class
- // so we now need to associate all dies under "decl_ctx_die"
- // to
- // DIEs in the DIE for "class_type"...
+ // class so we now need to associate all dies under
+ // "decl_ctx_die" to DIEs in the DIE for "class_type"...
SymbolFileDWARF *class_symfile = NULL;
DWARFDIE class_type_die;
@@ -1381,10 +1418,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
// FIXME do something with these failures that's smarter
// than
// just dropping them on the ground. Unfortunately classes
- // don't
- // like having stuff added to them after their definitions
- // are
- // complete...
+ // don't like having stuff added to them after their
+ // definitions are complete...
type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) {
@@ -1396,16 +1431,13 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
if (specification_die_form.IsValid()) {
// We have a specification which we are going to base our
- // function
- // prototype off of, so we need this type to be completed so
- // that the
- // m_die_to_decl_ctx for the method in the specification has a
- // valid
- // clang decl context.
+ // function prototype off of, so we need this type to be
+ // completed so that the m_die_to_decl_ctx for the method in
+ // the specification has a valid clang decl context.
class_type->GetForwardCompilerType();
// If we have a specification, then the function type should
- // have been
- // made with the specification and not with this die.
+ // have been made with the specification and not with this
+ // die.
DWARFDIE spec_die = dwarf->DebugInfo()->GetDIE(
DIERef(specification_die_form));
clang::DeclContext *spec_clang_decl_ctx =
@@ -1421,12 +1453,9 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
type_handled = true;
} else if (abstract_origin_die_form.IsValid()) {
// We have a specification which we are going to base our
- // function
- // prototype off of, so we need this type to be completed so
- // that the
- // m_die_to_decl_ctx for the method in the abstract origin has
- // a valid
- // clang decl context.
+ // function prototype off of, so we need this type to be
+ // completed so that the m_die_to_decl_ctx for the method in
+ // the abstract origin has a valid clang decl context.
class_type->GetForwardCompilerType();
DWARFDIE abs_die = dwarf->DebugInfo()->GetDIE(
@@ -1449,17 +1478,16 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
if (class_opaque_type.IsBeingDefined() || alternate_defn) {
if (!is_static && !die.HasChildren()) {
// We have a C++ member function with no children (this
- // pointer!)
- // and clang will get mad if we try and make a function
- // that isn't
- // well formed in the DWARF, so we will just skip it...
+ // pointer!) and clang will get mad if we try and make
+ // a function that isn't well formed in the DWARF, so
+ // we will just skip it...
type_handled = true;
} else {
bool add_method = true;
if (alternate_defn) {
// If an alternate definition for the class exists,
- // then add the method only if an
- // equivalent is not already present.
+ // then add the method only if an equivalent is not
+ // already present.
clang::CXXRecordDecl *record_decl =
m_ast.GetAsCXXRecordDecl(
class_opaque_type.GetOpaqueQualType());
@@ -1499,18 +1527,18 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
const bool is_attr_used = false;
// Neither GCC 4.2 nor clang++ currently set a valid
- // accessibility
- // in the DWARF for C++ methods... Default to public
- // for now...
+ // accessibility in the DWARF for C++ methods...
+ // Default to public for now...
if (accessibility == eAccessNone)
accessibility = eAccessPublic;
clang::CXXMethodDecl *cxx_method_decl =
m_ast.AddMethodToCXXRecordType(
class_opaque_type.GetOpaqueQualType(),
- type_name_cstr, clang_type, accessibility,
- is_virtual, is_static, is_inline, is_explicit,
- is_attr_used, is_artificial);
+ type_name_cstr, mangled_name_cstr, clang_type,
+ accessibility, is_virtual, is_static,
+ is_inline, is_explicit, is_attr_used,
+ is_artificial);
type_handled = cxx_method_decl != NULL;
@@ -1541,25 +1569,21 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
}
} else {
// We were asked to parse the type for a method in a
- // class, yet the
- // class hasn't been asked to complete itself through the
- // clang::ExternalASTSource protocol, so we need to just
- // have the
- // class complete itself and do things the right way, then
- // our
+ // class, yet the class hasn't been asked to complete
+ // itself through the clang::ExternalASTSource protocol,
+ // so we need to just have the class complete itself and
+ // do things the right way, then our
// DIE should then have an entry in the
// dwarf->GetDIEToType() map. First
// we need to modify the dwarf->GetDIEToType() so it
- // doesn't think we are
- // trying to parse this DIE anymore...
+ // doesn't think we are trying to parse this DIE
+ // anymore...
dwarf->GetDIEToType()[die.GetDIE()] = NULL;
// Now we get the full type to force our class type to
- // complete itself
- // using the clang::ExternalASTSource protocol which will
- // parse all
- // base classes and all methods (including the method for
- // this DIE).
+ // complete itself using the clang::ExternalASTSource
+ // protocol which will parse all base classes and all
+ // methods (including the method for this DIE).
class_type->GetFullCompilerType();
// The type for this DIE should have been filled in the
@@ -1573,8 +1597,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
// FIXME This is fixing some even uglier behavior but we
// really need to
// uniq the methods of each class as well as the class
- // itself.
- // <rdar://problem/11240464>
+ // itself. <rdar://problem/11240464>
type_handled = true;
}
}
@@ -1737,8 +1760,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
array_element_type.GetCompleteType() == false) {
ModuleSP module_sp = die.GetModule();
if (module_sp) {
- if (die.GetCU()->GetProducer() ==
- DWARFCompileUnit::eProducerClang)
+ if (die.GetCU()->GetProducer() == eProducerClang)
module_sp->ReportError(
"DWARF DW_TAG_array_type DIE at 0x%8.8x has a "
"class/union/struct element type DIE 0x%8.8x that is a "
@@ -1760,11 +1782,10 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
}
// We have no choice other than to pretend that the element class
- // type
- // is complete. If we don't do this, clang will crash when trying
- // to layout the class. Since we provide layout assistance, all
- // ivars in this class and other classes will be fine, this is
- // the best we can do short of crashing.
+ // type is complete. If we don't do this, clang will crash when
+ // trying to layout the class. Since we provide layout
+ // assistance, all ivars in this class and other classes will be
+ // fine, this is the best we can do short of crashing.
if (ClangASTContext::StartTagDeclarationDefinition(
array_element_type)) {
ClangASTContext::CompleteTagDeclarationDefinition(
@@ -1864,7 +1885,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
dw_tag_t sc_parent_tag = sc_parent_die.Tag();
SymbolContextScope *symbol_context_scope = NULL;
- if (sc_parent_tag == DW_TAG_compile_unit) {
+ if (sc_parent_tag == DW_TAG_compile_unit ||
+ sc_parent_tag == DW_TAG_partial_unit) {
symbol_context_scope = sc.comp_unit;
} else if (sc.function != NULL && sc_parent_die) {
symbol_context_scope =
@@ -1956,6 +1978,7 @@ bool DWARFASTParserClang::ParseTemplateDIE(
const DWARFDIE &die,
ClangASTContext::TemplateParameterInfos &template_param_infos) {
const dw_tag_t tag = die.Tag();
+ bool is_template_template_argument = false;
switch (tag) {
case DW_TAG_GNU_template_parameter_pack: {
@@ -1971,11 +1994,15 @@ bool DWARFASTParserClang::ParseTemplateDIE(
}
return true;
}
+ case DW_TAG_GNU_template_template_param:
+ is_template_template_argument = true;
+ LLVM_FALLTHROUGH;
case DW_TAG_template_type_parameter:
case DW_TAG_template_value_parameter: {
DWARFAttributes attributes;
const size_t num_attributes = die.GetAttributes(attributes);
const char *name = nullptr;
+ const char *template_name = nullptr;
CompilerType clang_type;
uint64_t uval64 = 0;
bool uval64_valid = false;
@@ -1990,6 +2017,11 @@ bool DWARFASTParserClang::ParseTemplateDIE(
name = form_value.AsCString();
break;
+ case DW_AT_GNU_template_name:
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ template_name = form_value.AsCString();
+ break;
+
case DW_AT_type:
if (attributes.ExtractFormValueAtIndex(i, form_value)) {
Type *lldb_type = die.ResolveTypeUID(DIERef(form_value));
@@ -2013,7 +2045,7 @@ bool DWARFASTParserClang::ParseTemplateDIE(
if (!clang_type)
clang_type = m_ast.GetBasicType(eBasicTypeVoid);
- if (clang_type) {
+ if (!is_template_template_argument) {
bool is_signed = false;
if (name && name[0])
template_param_infos.names.push_back(name);
@@ -2033,7 +2065,10 @@ bool DWARFASTParserClang::ParseTemplateDIE(
clang::TemplateArgument(ClangUtil::GetQualType(clang_type)));
}
} else {
- return false;
+ auto *tplt_type = m_ast.CreateTemplateTemplateParmDecl(template_name);
+ template_param_infos.names.push_back(name);
+ template_param_infos.args.push_back(
+ clang::TemplateArgument(clang::TemplateName(tplt_type)));
}
}
}
@@ -2052,7 +2087,6 @@ bool DWARFASTParserClang::ParseTemplateParameterInfos(
if (!parent_die)
return false;
- Args template_parameter_names;
for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
die = die.GetSibling()) {
const dw_tag_t tag = die.Tag();
@@ -2061,6 +2095,7 @@ bool DWARFASTParserClang::ParseTemplateParameterInfos(
case DW_TAG_template_type_parameter:
case DW_TAG_template_value_parameter:
case DW_TAG_GNU_template_parameter_pack:
+ case DW_TAG_GNU_template_template_param:
ParseTemplateDIE(die, template_param_infos);
break;
@@ -2073,6 +2108,95 @@ bool DWARFASTParserClang::ParseTemplateParameterInfos(
return template_param_infos.args.size() == template_param_infos.names.size();
}
+// Checks whether m1 is an overload of m2 (as opposed to an override). This is
+// called by addOverridesForMethod to distinguish overrides (which share a
+// vtable entry) from overloads (which require distinct entries).
+static bool isOverload(clang::CXXMethodDecl *m1, clang::CXXMethodDecl *m2) {
+ // FIXME: This should detect covariant return types, but currently doesn't.
+ lldbassert(&m1->getASTContext() == &m2->getASTContext() &&
+ "Methods should have the same AST context");
+ clang::ASTContext &context = m1->getASTContext();
+
+ const auto *m1Type =
+ llvm::cast<clang::FunctionProtoType>(
+ context.getCanonicalType(m1->getType()));
+
+ const auto *m2Type =
+ llvm::cast<clang::FunctionProtoType>(
+ context.getCanonicalType(m2->getType()));
+
+ auto compareArgTypes =
+ [&context](const clang::QualType &m1p, const clang::QualType &m2p) {
+ return context.hasSameType(m1p.getUnqualifiedType(),
+ m2p.getUnqualifiedType());
+ };
+
+ // FIXME: In C++14 and later, we can just pass m2Type->param_type_end()
+ // as a fourth parameter to std::equal().
+ return (m1->getNumParams() != m2->getNumParams()) ||
+ !std::equal(m1Type->param_type_begin(), m1Type->param_type_end(),
+ m2Type->param_type_begin(), compareArgTypes);
+}
+
+// If decl is a virtual method, walk the base classes looking for methods that
+// decl overrides. This table of overridden methods is used by IRGen to
+// determine the vtable layout for decl's parent class.
+static void addOverridesForMethod(clang::CXXMethodDecl *decl) {
+ if (!decl->isVirtual())
+ return;
+
+ clang::CXXBasePaths paths;
+
+ auto find_overridden_methods =
+ [decl](const clang::CXXBaseSpecifier *specifier, clang::CXXBasePath &path) {
+ if (auto *base_record =
+ llvm::dyn_cast<clang::CXXRecordDecl>(
+ specifier->getType()->getAs<clang::RecordType>()->getDecl())) {
+
+ clang::DeclarationName name = decl->getDeclName();
+
+ // If this is a destructor, check whether the base class destructor is
+ // virtual.
+ if (name.getNameKind() == clang::DeclarationName::CXXDestructorName)
+ if (auto *baseDtorDecl = base_record->getDestructor()) {
+ if (baseDtorDecl->isVirtual()) {
+ path.Decls = baseDtorDecl;
+ return true;
+ } else
+ return false;
+ }
+
+ // Otherwise, search for name in the base class.
+ for (path.Decls = base_record->lookup(name); !path.Decls.empty();
+ path.Decls = path.Decls.slice(1)) {
+ if (auto *method_decl =
+ llvm::dyn_cast<clang::CXXMethodDecl>(path.Decls.front()))
+ if (method_decl->isVirtual() && !isOverload(decl, method_decl)) {
+ path.Decls = method_decl;
+ return true;
+ }
+ }
+ }
+
+ return false;
+ };
+
+ if (decl->getParent()->lookupInBases(find_overridden_methods, paths)) {
+ for (auto *overridden_decl : paths.found_decls())
+ decl->addOverriddenMethod(
+ llvm::cast<clang::CXXMethodDecl>(overridden_decl));
+ }
+}
+
+// If clang_type is a CXXRecordDecl, builds the method override list for each
+// of its virtual methods.
+static void addMethodOverrides(ClangASTContext &ast, CompilerType &clang_type) {
+ if (auto *record =
+ ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType()))
+ for (auto *method : record->methods())
+ addOverridesForMethod(method);
+}
+
bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
lldb_private::Type *type,
CompilerType &clang_type) {
@@ -2090,10 +2214,10 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
#if defined LLDB_CONFIGURATION_DEBUG
//----------------------------------------------------------------------
- // For debugging purposes, the LLDB_DWARF_DONT_COMPLETE_TYPENAMES
- // environment variable can be set with one or more typenames separated
- // by ';' characters. This will cause this function to not complete any
- // types whose names match.
+ // For debugging purposes, the LLDB_DWARF_DONT_COMPLETE_TYPENAMES environment
+ // variable can be set with one or more typenames separated by ';'
+ // characters. This will cause this function to not complete any types whose
+ // names match.
//
// Examples of setting this environment variable:
//
@@ -2144,8 +2268,8 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
LanguageType class_language = eLanguageTypeUnknown;
if (ClangASTContext::IsObjCObjectOrInterfaceType(clang_type)) {
class_language = eLanguageTypeObjC;
- // For objective C we don't start the definition when
- // the class is created.
+ // For objective C we don't start the definition when the class is
+ // created.
ClangASTContext::StartTagDeclarationDefinition(clang_type);
}
@@ -2217,29 +2341,27 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
clang::TTK_Class);
}
- // Since DW_TAG_structure_type gets used for both classes
- // and structures, we may need to set any DW_TAG_member
- // fields to have a "private" access if none was specified.
- // When we parsed the child members we tracked that actual
- // accessibility value for each DW_TAG_member in the
- // "member_accessibilities" array. If the value for the
- // member is zero, then it was set to the "default_accessibility"
- // which for structs was "public". Below we correct this
- // by setting any fields to "private" that weren't correctly
- // set.
+ // Since DW_TAG_structure_type gets used for both classes and
+ // structures, we may need to set any DW_TAG_member fields to have a
+ // "private" access if none was specified. When we parsed the child
+ // members we tracked that actual accessibility value for each
+ // DW_TAG_member in the "member_accessibilities" array. If the value
+ // for the member is zero, then it was set to the
+ // "default_accessibility" which for structs was "public". Below we
+ // correct this by setting any fields to "private" that weren't
+ // correctly set.
if (is_a_class && !member_accessibilities.empty()) {
- // This is a class and all members that didn't have
- // their access specified are private.
+ // This is a class and all members that didn't have their access
+ // specified are private.
m_ast.SetDefaultAccessForRecordFields(
m_ast.GetAsRecordDecl(clang_type), eAccessPrivate,
&member_accessibilities.front(), member_accessibilities.size());
}
if (!base_classes.empty()) {
- // Make sure all base classes refer to complete types and not
- // forward declarations. If we don't do this, clang will crash
- // with an assertion in the call to
- // clang_type.SetBaseClassesForClassType()
+ // Make sure all base classes refer to complete types and not forward
+ // declarations. If we don't do this, clang will crash with an
+ // assertion in the call to clang_type.SetBaseClassesForClassType()
for (auto &base_class : base_classes) {
clang::TypeSourceInfo *type_source_info =
base_class->getTypeSourceInfo();
@@ -2252,19 +2374,17 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
"does not have a complete definition.",
die.GetName(),
base_class_type.GetTypeName().GetCString());
- if (die.GetCU()->GetProducer() ==
- DWARFCompileUnit::eProducerClang)
+ if (die.GetCU()->GetProducer() == eProducerClang)
module->ReportError(":: Try compiling the source file with "
"-fstandalone-debug.");
// We have no choice other than to pretend that the base class
// is complete. If we don't do this, clang will crash when we
// call setBases() inside of
- // "clang_type.SetBaseClassesForClassType()"
- // below. Since we provide layout assistance, all ivars in this
- // class and other classes will be fine, this is the best we can
- // do
- // short of crashing.
+ // "clang_type.SetBaseClassesForClassType()" below. Since we
+ // provide layout assistance, all ivars in this class and other
+ // classes will be fine, this is the best we can do short of
+ // crashing.
if (ClangASTContext::StartTagDeclarationDefinition(
base_class_type)) {
ClangASTContext::CompleteTagDeclarationDefinition(
@@ -2277,14 +2397,15 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
&base_classes.front(),
base_classes.size());
- // Clang will copy each CXXBaseSpecifier in "base_classes"
- // so we have to free them all.
+ // Clang will copy each CXXBaseSpecifier in "base_classes" so we have
+ // to free them all.
ClangASTContext::DeleteBaseClassSpecifiers(&base_classes.front(),
base_classes.size());
}
}
}
+ addMethodOverrides(m_ast, clang_type);
ClangASTContext::BuildIndirectFields(clang_type);
ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
@@ -2582,14 +2703,13 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc,
Mangled func_name;
if (mangled)
func_name.SetValue(ConstString(mangled), true);
- else if (die.GetParent().Tag() == DW_TAG_compile_unit &&
+ else if ((die.GetParent().Tag() == DW_TAG_compile_unit ||
+ die.GetParent().Tag() == DW_TAG_partial_unit) &&
Language::LanguageIsCPlusPlus(die.GetLanguage()) && name &&
strcmp(name, "main") != 0) {
// If the mangled name is not present in the DWARF, generate the
- // demangled name
- // using the decl context. We skip if the function is "main" as its name
- // is
- // never mangled.
+ // demangled name using the decl context. We skip if the function is
+ // "main" as its name is never mangled.
bool is_static = false;
bool is_variadic = false;
bool has_template_params = false;
@@ -2748,8 +2868,7 @@ bool DWARFASTParserClang::ParseChildMembers(
if (form_value.BlockData()) {
Value initialValue(0);
Value memberOffset(0);
- const DWARFDataExtractor &debug_info_data =
- die.GetDWARF()->get_debug_info_data();
+ const DWARFDataExtractor &debug_info_data = die.GetData();
uint32_t block_length = form_value.Unsigned();
uint32_t block_offset =
form_value.BlockData() - debug_info_data.GetDataStart();
@@ -2763,8 +2882,8 @@ bool DWARFASTParserClang::ParseChildMembers(
}
} else {
// With DWARF 3 and later, if the value is an integer constant,
- // this form value is the offset in bytes from the beginning
- // of the containing entity.
+ // this form value is the offset in bytes from the beginning of
+ // the containing entity.
member_byte_offset = form_value.Unsigned();
}
break;
@@ -2806,8 +2925,8 @@ bool DWARFASTParserClang::ParseChildMembers(
ConstString fixed_getter;
ConstString fixed_setter;
- // Check if the property getter/setter were provided as full
- // names. We want basenames, so we extract them.
+ // Check if the property getter/setter were provided as full names.
+ // We want basenames, so we extract them.
if (prop_getter_name && prop_getter_name[0] == '-') {
ObjCLanguage::MethodName prop_getter_method(prop_getter_name, true);
@@ -2819,8 +2938,7 @@ bool DWARFASTParserClang::ParseChildMembers(
prop_setter_name = prop_setter_method.GetSelector().GetCString();
}
- // If the names haven't been provided, they need to be
- // filled in.
+ // If the names haven't been provided, they need to be filled in.
if (!prop_getter_name) {
prop_getter_name = prop_name;
@@ -2836,19 +2954,18 @@ bool DWARFASTParserClang::ParseChildMembers(
}
}
- // Clang has a DWARF generation bug where sometimes it
- // represents fields that are references with bad byte size
- // and bit size/offset information such as:
+ // Clang has a DWARF generation bug where sometimes it represents
+ // fields that are references with bad byte size and bit size/offset
+ // information such as:
//
// DW_AT_byte_size( 0x00 )
// DW_AT_bit_size( 0x40 )
// DW_AT_bit_offset( 0xffffffffffffffc0 )
//
- // So check the bit offset to make sure it is sane, and if
- // the values are not sane, remove them. If we don't do this
- // then we will end up with a crash if we try to use this
- // type in an expression when clang becomes unhappy with its
- // recycled debug info.
+ // So check the bit offset to make sure it is sane, and if the values
+ // are not sane, remove them. If we don't do this then we will end up
+ // with a crash if we try to use this type in an expression when clang
+ // becomes unhappy with its recycled debug info.
if (byte_size == 0 && bit_offset < 0) {
bit_size = 0;
@@ -2862,12 +2979,10 @@ bool DWARFASTParserClang::ParseChildMembers(
if (member_idx == 0 && !is_artificial && name &&
(strstr(name, "_vptr$") == name)) {
- // Not all compilers will mark the vtable pointer
- // member as artificial (llvm-gcc). We can't have
- // the virtual members in our classes otherwise it
- // throws off all child offsets since we end up
- // having and extra pointer sized member in our
- // class layouts.
+ // Not all compilers will mark the vtable pointer member as
+ // artificial (llvm-gcc). We can't have the virtual members in our
+ // classes otherwise it throws off all child offsets since we end up
+ // having and extra pointer sized member in our class layouts.
is_artificial = true;
}
@@ -2907,15 +3022,15 @@ bool DWARFASTParserClang::ParseChildMembers(
/////////////////////////////////////////////////////////////
// How to locate a field given the DWARF debug information
//
- // AT_byte_size indicates the size of the word in which the
- // bit offset must be interpreted.
+ // AT_byte_size indicates the size of the word in which the bit
+ // offset must be interpreted.
//
// AT_data_member_location indicates the byte offset of the
// word from the base address of the structure.
//
// AT_bit_offset indicates how many bits into the word
- // (according to the host endianness) the low-order bit of
- // the field starts. AT_bit_offset can be negative.
+ // (according to the host endianness) the low-order bit of the
+ // field starts. AT_bit_offset can be negative.
//
// AT_bit_size indicates the size of the field in bits.
/////////////////////////////////////////////////////////////
@@ -2956,12 +3071,9 @@ bool DWARFASTParserClang::ParseChildMembers(
field_bit_offset = this_field_info.bit_offset;
// If the member to be emitted did not start on a character
- // boundary and there is
- // empty space between the last field and this one, then we need
- // to emit an
- // anonymous member filling up the space up to its start. There
- // are three cases
- // here:
+ // boundary and there is empty space between the last field and
+ // this one, then we need to emit an anonymous member filling
+ // up the space up to its start. There are three cases here:
//
// 1 If the previous member ended on a character boundary, then
// we can emit an
@@ -2986,10 +3098,8 @@ bool DWARFASTParserClang::ParseChildMembers(
const uint64_t word_width = 32;
// Objective-C has invalid DW_AT_bit_offset values in older
- // versions
- // of clang, so we have to be careful and only insert unnamed
- // bitfields
- // if we have a new enough clang.
+ // versions of clang, so we have to be careful and only insert
+ // unnamed bitfields if we have a new enough clang.
bool detect_unnamed_bitfields = true;
if (class_language == eLanguageTypeObjC ||
@@ -3052,10 +3162,10 @@ bool DWARFASTParserClang::ParseChildMembers(
{
// Older versions of clang emit array[0] and array[1] in the
- // same way (<rdar://problem/12566646>).
- // If the current field is at the end of the structure, then
- // there is definitely no room for extra
- // elements and we override the type to array[0].
+ // same way (<rdar://problem/12566646>). If the current field
+ // is at the end of the structure, then there is definitely no
+ // room for extra elements and we override the type to
+ // array[0].
CompilerType member_array_element_type;
uint64_t member_array_size;
@@ -3089,8 +3199,7 @@ bool DWARFASTParserClang::ParseChildMembers(
if (ClangASTContext::IsCXXClassType(member_clang_type) &&
member_clang_type.GetCompleteType() == false) {
- if (die.GetCU()->GetProducer() ==
- DWARFCompileUnit::eProducerClang)
+ if (die.GetCU()->GetProducer() == eProducerClang)
module_sp->ReportError(
"DWARF DIE at 0x%8.8x (class %s) has a member variable "
"0x%8.8x (%s) whose type is a forward declaration, not a "
@@ -3108,12 +3217,11 @@ bool DWARFASTParserClang::ParseChildMembers(
die.GetOffset(), name,
sc.comp_unit ? sc.comp_unit->GetPath().c_str()
: "the source file");
- // We have no choice other than to pretend that the member class
- // is complete. If we don't do this, clang will crash when
- // trying
- // to layout the class. Since we provide layout assistance, all
- // ivars in this class and other classes will be fine, this is
- // the best we can do short of crashing.
+ // We have no choice other than to pretend that the member
+ // class is complete. If we don't do this, clang will crash
+ // when trying to layout the class. Since we provide layout
+ // assistance, all ivars in this class and other classes will
+ // be fine, this is the best we can do short of crashing.
if (ClangASTContext::StartTagDeclarationDefinition(
member_clang_type)) {
ClangASTContext::CompleteTagDeclarationDefinition(
@@ -3221,8 +3329,7 @@ bool DWARFASTParserClang::ParseChildMembers(
if (form_value.BlockData()) {
Value initialValue(0);
Value memberOffset(0);
- const DWARFDataExtractor &debug_info_data =
- die.GetDWARF()->get_debug_info_data();
+ const DWARFDataExtractor &debug_info_data = die.GetData();
uint32_t block_length = form_value.Unsigned();
uint32_t block_offset =
form_value.BlockData() - debug_info_data.GetDataStart();
@@ -3235,8 +3342,8 @@ bool DWARFASTParserClang::ParseChildMembers(
}
} else {
// With DWARF 3 and later, if the value is an integer constant,
- // this form value is the offset in bytes from the beginning
- // of the containing entity.
+ // this form value is the offset in bytes from the beginning of
+ // the containing entity.
member_byte_offset = form_value.Unsigned();
}
break;
@@ -3282,18 +3389,16 @@ bool DWARFASTParserClang::ParseChildMembers(
if (is_virtual) {
// Do not specify any offset for virtual inheritance. The DWARF
- // produced by clang doesn't
- // give us a constant offset, but gives us a DWARF expressions that
- // requires an actual object
- // in memory. the DW_AT_data_member_location for a virtual base
- // class looks like:
+ // produced by clang doesn't give us a constant offset, but gives
+ // us a DWARF expressions that requires an actual object in memory.
+ // the DW_AT_data_member_location for a virtual base class looks
+ // like:
// DW_AT_data_member_location( DW_OP_dup, DW_OP_deref,
// DW_OP_constu(0x00000018), DW_OP_minus, DW_OP_deref,
// DW_OP_plus )
// Given this, there is really no valid response we can give to
- // clang for virtual base
- // class offsets, and this should eventually be removed from
- // LayoutRecordType() in the external
+ // clang for virtual base class offsets, and this should eventually
+ // be removed from LayoutRecordType() in the external
// AST source in clang.
} else {
layout_info.base_offsets.insert(std::make_pair(
@@ -3365,22 +3470,6 @@ size_t DWARFASTParserClang::ParseChildParameters(
is_artificial = form_value.Boolean();
break;
case DW_AT_location:
- // if (form_value.BlockData())
- // {
- // const DWARFDataExtractor&
- // debug_info_data = debug_info();
- // uint32_t block_length =
- // form_value.Unsigned();
- // DWARFDataExtractor
- // location(debug_info_data,
- // form_value.BlockData() -
- // debug_info_data.GetDataStart(),
- // block_length);
- // }
- // else
- // {
- // }
- // break;
case DW_AT_const_value:
case DW_AT_default_value:
case DW_AT_description:
@@ -3397,52 +3486,29 @@ size_t DWARFASTParserClang::ParseChildParameters(
}
bool skip = false;
- if (skip_artificial) {
- if (is_artificial) {
- // In order to determine if a C++ member function is
- // "const" we have to look at the const-ness of "this"...
- // Ugly, but that
- if (arg_idx == 0) {
- if (DeclKindIsCXXClass(containing_decl_ctx->getDeclKind())) {
- // Often times compilers omit the "this" name for the
- // specification DIEs, so we can't rely upon the name
- // being in the formal parameter DIE...
- if (name == NULL || ::strcmp(name, "this") == 0) {
- Type *this_type =
- die.ResolveTypeUID(DIERef(param_type_die_form));
- if (this_type) {
- uint32_t encoding_mask = this_type->GetEncodingMask();
- if (encoding_mask & Type::eEncodingIsPointerUID) {
- is_static = false;
+ if (skip_artificial && is_artificial) {
+ // In order to determine if a C++ member function is "const" we
+ // have to look at the const-ness of "this"...
+ if (arg_idx == 0 &&
+ DeclKindIsCXXClass(containing_decl_ctx->getDeclKind()) &&
+ // Often times compilers omit the "this" name for the
+ // specification DIEs, so we can't rely upon the name being in
+ // the formal parameter DIE...
+ (name == NULL || ::strcmp(name, "this") == 0)) {
+ Type *this_type = die.ResolveTypeUID(DIERef(param_type_die_form));
+ if (this_type) {
+ uint32_t encoding_mask = this_type->GetEncodingMask();
+ if (encoding_mask & Type::eEncodingIsPointerUID) {
+ is_static = false;
- if (encoding_mask & (1u << Type::eEncodingIsConstUID))
- type_quals |= clang::Qualifiers::Const;
- if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
- type_quals |= clang::Qualifiers::Volatile;
- }
- }
- }
- }
- }
- skip = true;
- } else {
-
- // HACK: Objective C formal parameters "self" and "_cmd"
- // are not marked as artificial in the DWARF...
- CompileUnit *comp_unit = die.GetLLDBCompileUnit();
- if (comp_unit) {
- switch (comp_unit->GetLanguage()) {
- case eLanguageTypeObjC:
- case eLanguageTypeObjC_plus_plus:
- if (name && name[0] &&
- (strcmp(name, "self") == 0 || strcmp(name, "_cmd") == 0))
- skip = true;
- break;
- default:
- break;
+ if (encoding_mask & (1u << Type::eEncodingIsConstUID))
+ type_quals |= clang::Qualifiers::Const;
+ if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
+ type_quals |= clang::Qualifiers::Volatile;
}
}
}
+ skip = true;
}
if (!skip) {
@@ -3470,10 +3536,10 @@ size_t DWARFASTParserClang::ParseChildParameters(
case DW_TAG_template_type_parameter:
case DW_TAG_template_value_parameter:
case DW_TAG_GNU_template_parameter_pack:
- // The one caller of this was never using the template_param_infos,
- // and the local variable was taking up a large amount of stack space
- // in SymbolFileDWARF::ParseType() so this was removed. If we ever need
- // the template params back, we can add them back.
+ // The one caller of this was never using the template_param_infos, and
+ // the local variable was taking up a large amount of stack space in
+ // SymbolFileDWARF::ParseType() so this was removed. If we ever need the
+ // template params back, we can add them back.
// ParseTemplateDIE (dwarf_cu, die, template_param_infos);
has_template_params = true;
break;
@@ -3692,6 +3758,7 @@ DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die) {
bool try_parsing_type = true;
switch (die.Tag()) {
case DW_TAG_compile_unit:
+ case DW_TAG_partial_unit:
decl_ctx = m_ast.GetTranslationUnitDecl();
try_parsing_type = false;
break;
@@ -4008,8 +4075,8 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
// Now do the work of linking the DeclContexts and Types.
if (fast_path) {
- // We can do this quickly. Just run across the tables index-for-index since
- // we know each node has matching names and tags.
+ // We can do this quickly. Just run across the tables index-for-index
+ // since we know each node has matching names and tags.
for (idx = 0; idx < src_size; ++idx) {
src_die = src_name_to_die.GetValueAtIndexUnchecked(idx);
dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);
@@ -4046,9 +4113,9 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
}
}
} else {
- // We must do this slowly. For each member of the destination, look
- // up a member in the source with the same name, check its tag, and
- // unique them if everything matches up. Report failures.
+ // We must do this slowly. For each member of the destination, look up a
+ // member in the source with the same name, check its tag, and unique them
+ // if everything matches up. Report failures.
if (!src_name_to_die.IsEmpty() && !dst_name_to_die.IsEmpty()) {
src_name_to_die.Sort();
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
index e04dc76d1dbe..328212e4b684 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
@@ -10,7 +10,6 @@
#include "DWARFASTParserGo.h"
#include "DWARFASTParserGo.h"
-#include "DWARFCompileUnit.h"
#include "DWARFDIE.h"
#include "DWARFDIECollection.h"
#include "DWARFDebugInfo.h"
@@ -158,7 +157,8 @@ TypeSP DWARFASTParserGo::ParseTypeFromDWARF(
Type *type = dwarf->ResolveTypeUID(encoding_uid);
if (type) {
if (go_kind == 0 && type->GetName() == type_name_const_str) {
- // Go emits extra typedefs as a forward declaration. Ignore these.
+ // Go emits extra typedefs as a forward declaration. Ignore
+ // these.
dwarf->m_die_to_type[die.GetDIE()] = type;
return type->shared_from_this();
}
@@ -213,10 +213,10 @@ TypeSP DWARFASTParserGo::ParseTypeFromDWARF(
// TODO(ribrdb): Do we need this?
- // UniqueDWARFASTType is large, so don't create a local variables on the
- // stack, put it on the heap. This function is often called recursively
- // and clang isn't good and sharing the stack space for variables in
- // different blocks.
+ // UniqueDWARFASTType is large, so don't create a local variables on
+ // the stack, put it on the heap. This function is often called
+ // recursively and clang isn't good and sharing the stack space for
+ // variables in different blocks.
std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_ap(
new UniqueDWARFASTType());
@@ -225,11 +225,10 @@ TypeSP DWARFASTParserGo::ParseTypeFromDWARF(
dwarf->GetUniqueDWARFASTTypeMap().Find(
type_name_const_str, die, decl,
byte_size_valid ? byte_size : -1, *unique_ast_entry_ap)) {
- // We have already parsed this type or from another
- // compile unit. GCC loves to use the "one definition
- // rule" which can result in multiple definitions
- // of the same class over and over in each compile
- // unit.
+ // We have already parsed this type or from another compile unit. GCC
+ // loves to use the "one definition rule" which can result in
+ // multiple definitions of the same class over and over in each
+ // compile unit.
type_sp = unique_ast_entry_ap->m_type_sp;
if (type_sp) {
dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
@@ -255,9 +254,9 @@ TypeSP DWARFASTParserGo::ParseTypeFromDWARF(
Type::eEncodingIsUID, &decl, compiler_type,
Type::eResolveStateForward));
- // Add our type to the unique type map so we don't
- // end up creating many copies of the same type over
- // and over in the ASTContext for our module
+ // Add our type to the unique type map so we don't end up creating many
+ // copies of the same type over and over in the ASTContext for our
+ // module
unique_ast_entry_ap->m_type_sp = type_sp;
unique_ast_entry_ap->m_die = die;
unique_ast_entry_ap->m_declaration = decl;
@@ -266,19 +265,19 @@ TypeSP DWARFASTParserGo::ParseTypeFromDWARF(
*unique_ast_entry_ap);
if (!is_forward_declaration) {
- // Always start the definition for a class type so that
- // if the class has child classes or types that require
- // the class to be created for use as their decl contexts
- // the class will be ready to accept these child definitions.
+ // Always start the definition for a class type so that if the class
+ // has child classes or types that require the class to be created
+ // for use as their decl contexts the class will be ready to accept
+ // these child definitions.
if (die.HasChildren() == false) {
// No children for this struct/union/class, lets finish it
m_ast.CompleteStructType(compiler_type);
} else if (compiler_type_was_created) {
- // Leave this as a forward declaration until we need
- // to know the details of the type. lldb_private::Type
- // will automatically call the SymbolFile virtual function
- // "SymbolFileDWARF::CompleteType(Type *)"
- // When the definition needs to be defined.
+ // Leave this as a forward declaration until we need to know the
+ // details of the type. lldb_private::Type will automatically call
+ // the SymbolFile virtual function
+ // "SymbolFileDWARF::CompleteType(Type *)" When the definition
+ // needs to be defined.
dwarf->m_forward_decl_die_to_clang_type[die.GetDIE()] =
compiler_type.GetOpaqueQualType();
dwarf->m_forward_decl_clang_type_to_die[compiler_type
@@ -432,7 +431,8 @@ TypeSP DWARFASTParserGo::ParseTypeFromDWARF(
dw_tag_t sc_parent_tag = sc_parent_die.Tag();
SymbolContextScope *symbol_context_scope = NULL;
- if (sc_parent_tag == DW_TAG_compile_unit) {
+ if (sc_parent_tag == DW_TAG_compile_unit ||
+ sc_parent_tag == DW_TAG_partial_unit) {
symbol_context_scope = sc.comp_unit;
} else if (sc.function != NULL && sc_parent_die) {
symbol_context_scope =
@@ -655,8 +655,7 @@ size_t DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc,
if (form_value.BlockData()) {
Value initialValue(0);
Value memberOffset(0);
- const DWARFDataExtractor &debug_info_data =
- die.GetDWARF()->get_debug_info_data();
+ const DWARFDataExtractor &debug_info_data = die.GetData();
uint32_t block_length = form_value.Unsigned();
uint32_t block_offset =
form_value.BlockData() - debug_info_data.GetDataStart();
@@ -670,8 +669,8 @@ size_t DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc,
}
} else {
// With DWARF 3 and later, if the value is an integer constant,
- // this form value is the offset in bytes from the beginning
- // of the containing entity.
+ // this form value is the offset in bytes from the beginning of
+ // the containing entity.
member_byte_offset = form_value.Unsigned();
}
break;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp
index 8b5202ba265f..476394487985 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp
@@ -9,7 +9,7 @@
#include "DWARFASTParserJava.h"
#include "DWARFAttribute.h"
-#include "DWARFCompileUnit.h"
+#include "DWARFUnit.h"
#include "DWARFDebugInfoEntry.h"
#include "DWARFDebugInfoEntry.h"
#include "DWARFDeclContext.h"
@@ -324,7 +324,8 @@ lldb::TypeSP DWARFASTParserJava::ParseTypeFromDWARF(
dw_tag_t sc_parent_tag = sc_parent_die.Tag();
SymbolContextScope *symbol_context_scope = nullptr;
- if (sc_parent_tag == DW_TAG_compile_unit) {
+ if (sc_parent_tag == DW_TAG_compile_unit ||
+ sc_parent_tag == DW_TAG_partial_unit) {
symbol_context_scope = sc.comp_unit;
} else if (sc.function != nullptr && sc_parent_die) {
symbol_context_scope =
@@ -418,7 +419,7 @@ bool DWARFASTParserJava::CompleteTypeFromDWARF(
void DWARFASTParserJava::ParseChildMembers(const DWARFDIE &parent_die,
CompilerType &compiler_type) {
- DWARFCompileUnit *dwarf_cu = parent_die.GetCU();
+ DWARFUnit *dwarf_cu = parent_die.GetCU();
for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
die = die.GetSibling()) {
switch (die.Tag()) {
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp
index 3b1466df21b0..3ef5c2eb8626 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp
@@ -98,7 +98,8 @@ lldb::TypeSP DWARFASTParserOCaml::ParseTypeFromDWARF(const SymbolContext &sc,
dw_tag_t sc_parent_tag = sc_parent_die.Tag();
SymbolContextScope *symbol_context_scope = nullptr;
- if (sc_parent_tag == DW_TAG_compile_unit) {
+ if (sc_parent_tag == DW_TAG_compile_unit ||
+ sc_parent_tag == DW_TAG_partial_unit) {
symbol_context_scope = sc.comp_unit;
} else if (sc.function != nullptr && sc_parent_die) {
symbol_context_scope =
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h
index e3b2279ca8fc..09cb5e14934f 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h
@@ -4,7 +4,6 @@
#define SymbolFileDWARF_DWARFASTParserOCaml_h_
#include "DWARFASTParser.h"
-#include "DWARFCompileUnit.h"
#include "DWARFDIE.h"
#include "DWARFDebugInfo.h"
#include "DWARFDefines.h"
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
index bc49fc5de2cd..a765be0b46d0 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
@@ -10,6 +10,7 @@
#include "DWARFAbbreviationDeclaration.h"
#include "lldb/Core/dwarf.h"
+#include "lldb/Utility/Stream.h"
#include "DWARFFormValue.h"
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
index 28e713f9beb1..b2296c455d6a 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
@@ -13,8 +13,6 @@
#include "DWARFAttribute.h"
#include "SymbolFileDWARF.h"
-class DWARFCompileUnit;
-
class DWARFAbbreviationDeclaration {
public:
enum { InvalidCode = 0 };
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp b/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
index d2573f3742ba..2586d1f18530 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
#include "DWARFAttribute.h"
-#include "DWARFCompileUnit.h"
+#include "DWARFUnit.h"
#include "DWARFDebugInfo.h"
DWARFAttributes::DWARFAttributes() : m_infos() {}
@@ -26,7 +26,7 @@ uint32_t DWARFAttributes::FindAttributeIndex(dw_attr_t attr) const {
return UINT32_MAX;
}
-void DWARFAttributes::Append(const DWARFCompileUnit *cu,
+void DWARFAttributes::Append(const DWARFUnit *cu,
dw_offset_t attr_die_offset, dw_attr_t attr,
dw_form_t form) {
AttributeValue attr_value = {cu, attr_die_offset, {attr, form}};
@@ -48,12 +48,11 @@ bool DWARFAttributes::RemoveAttribute(dw_attr_t attr) {
bool DWARFAttributes::ExtractFormValueAtIndex(
uint32_t i, DWARFFormValue &form_value) const {
- const DWARFCompileUnit *cu = CompileUnitAtIndex(i);
+ const DWARFUnit *cu = CompileUnitAtIndex(i);
form_value.SetCompileUnit(cu);
form_value.SetForm(FormAtIndex(i));
lldb::offset_t offset = DIEOffsetAtIndex(i);
- return form_value.ExtractValue(
- cu->GetSymbolFileDWARF()->get_debug_info_data(), &offset);
+ return form_value.ExtractValue(cu->GetData(), &offset);
}
uint64_t DWARFAttributes::FormValueAsUnsigned(dw_attr_t attr,
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h b/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
index 317e710e6d94..db4324cf7725 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
@@ -14,7 +14,7 @@
#include "llvm/ADT/SmallVector.h"
#include <vector>
-class DWARFCompileUnit;
+class DWARFUnit;
class DWARFFormValue;
class DWARFAttribute {
@@ -50,9 +50,9 @@ public:
DWARFAttributes();
~DWARFAttributes();
- void Append(const DWARFCompileUnit *cu, dw_offset_t attr_die_offset,
+ void Append(const DWARFUnit *cu, dw_offset_t attr_die_offset,
dw_attr_t attr, dw_form_t form);
- const DWARFCompileUnit *CompileUnitAtIndex(uint32_t i) const {
+ const DWARFUnit *CompileUnitAtIndex(uint32_t i) const {
return m_infos[i].cu;
}
dw_offset_t DIEOffsetAtIndex(uint32_t i) const {
@@ -73,7 +73,7 @@ public:
protected:
struct AttributeValue {
- const DWARFCompileUnit *cu; // Keep the compile unit with each attribute in
+ const DWARFUnit *cu; // Keep the compile unit with each attribute in
// case we have DW_FORM_ref_addr values
dw_offset_t die_offset;
DWARFAttribute attr;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp b/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
new file mode 100644
index 000000000000..077de9604f1d
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
@@ -0,0 +1,193 @@
+//===-- DWARFBaseDIE.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFBaseDIE.h"
+
+#include "DWARFUnit.h"
+#include "DWARFDebugInfoEntry.h"
+#include "SymbolFileDWARF.h"
+
+#include "lldb/Core/Module.h"
+#include "lldb/Symbol/ObjectFile.h"
+
+using namespace lldb_private;
+
+DIERef DWARFBaseDIE::GetDIERef() const {
+ if (!IsValid())
+ return DIERef();
+
+ dw_offset_t cu_offset = m_cu->GetOffset();
+ if (m_cu->GetBaseObjOffset() != DW_INVALID_OFFSET)
+ cu_offset = m_cu->GetBaseObjOffset();
+ return DIERef(cu_offset, m_die->GetOffset());
+}
+
+dw_tag_t DWARFBaseDIE::Tag() const {
+ if (m_die)
+ return m_die->Tag();
+ else
+ return 0;
+}
+
+const char *DWARFBaseDIE::GetTagAsCString() const {
+ return lldb_private::DW_TAG_value_to_name(Tag());
+}
+
+const char *DWARFBaseDIE::GetAttributeValueAsString(const dw_attr_t attr,
+ const char *fail_value) const {
+ if (IsValid())
+ return m_die->GetAttributeValueAsString(GetDWARF(), GetCU(), attr,
+ fail_value);
+ else
+ return fail_value;
+}
+
+uint64_t DWARFBaseDIE::GetAttributeValueAsUnsigned(const dw_attr_t attr,
+ uint64_t fail_value) const {
+ if (IsValid())
+ return m_die->GetAttributeValueAsUnsigned(GetDWARF(), GetCU(), attr,
+ fail_value);
+ else
+ return fail_value;
+}
+
+int64_t DWARFBaseDIE::GetAttributeValueAsSigned(const dw_attr_t attr,
+ int64_t fail_value) const {
+ if (IsValid())
+ return m_die->GetAttributeValueAsSigned(GetDWARF(), GetCU(), attr,
+ fail_value);
+ else
+ return fail_value;
+}
+
+uint64_t DWARFBaseDIE::GetAttributeValueAsReference(const dw_attr_t attr,
+ uint64_t fail_value) const {
+ if (IsValid())
+ return m_die->GetAttributeValueAsReference(GetDWARF(), GetCU(), attr,
+ fail_value);
+ else
+ return fail_value;
+}
+
+uint64_t DWARFBaseDIE::GetAttributeValueAsAddress(const dw_attr_t attr,
+ uint64_t fail_value) const {
+ if (IsValid())
+ return m_die->GetAttributeValueAsAddress(GetDWARF(), GetCU(), attr,
+ fail_value);
+ else
+ return fail_value;
+}
+
+lldb::user_id_t DWARFBaseDIE::GetID() const {
+ return GetDIERef().GetUID(GetDWARF());
+}
+
+const char *DWARFBaseDIE::GetName() const {
+ if (IsValid())
+ return m_die->GetName(GetDWARF(), m_cu);
+ else
+ return nullptr;
+}
+
+lldb::LanguageType DWARFBaseDIE::GetLanguage() const {
+ if (IsValid())
+ return m_cu->GetLanguageType();
+ else
+ return lldb::eLanguageTypeUnknown;
+}
+
+lldb::ModuleSP DWARFBaseDIE::GetModule() const {
+ SymbolFileDWARF *dwarf = GetDWARF();
+ if (dwarf)
+ return dwarf->GetObjectFile()->GetModule();
+ else
+ return lldb::ModuleSP();
+}
+
+lldb_private::CompileUnit *DWARFBaseDIE::GetLLDBCompileUnit() const {
+ if (IsValid())
+ return GetDWARF()->GetCompUnitForDWARFCompUnit(GetCU());
+ else
+ return nullptr;
+}
+
+dw_offset_t DWARFBaseDIE::GetOffset() const {
+ if (IsValid())
+ return m_die->GetOffset();
+ else
+ return DW_INVALID_OFFSET;
+}
+
+dw_offset_t DWARFBaseDIE::GetCompileUnitRelativeOffset() const {
+ if (IsValid())
+ return m_die->GetOffset() - m_cu->GetOffset();
+ else
+ return DW_INVALID_OFFSET;
+}
+
+SymbolFileDWARF *DWARFBaseDIE::GetDWARF() const {
+ if (m_cu)
+ return m_cu->GetSymbolFileDWARF();
+ else
+ return nullptr;
+}
+
+lldb_private::TypeSystem *DWARFBaseDIE::GetTypeSystem() const {
+ if (m_cu)
+ return m_cu->GetTypeSystem();
+ else
+ return nullptr;
+}
+
+DWARFASTParser *DWARFBaseDIE::GetDWARFParser() const {
+ lldb_private::TypeSystem *type_system = GetTypeSystem();
+ if (type_system)
+ return type_system->GetDWARFParser();
+ else
+ return nullptr;
+}
+
+bool DWARFBaseDIE::HasChildren() const {
+ return m_die && m_die->HasChildren();
+}
+
+bool DWARFBaseDIE::Supports_DW_AT_APPLE_objc_complete_type() const {
+ return IsValid() && GetDWARF()->Supports_DW_AT_APPLE_objc_complete_type(m_cu);
+}
+
+size_t DWARFBaseDIE::GetAttributes(DWARFAttributes &attributes,
+ uint32_t depth) const {
+ if (IsValid()) {
+ return m_die->GetAttributes(m_cu, m_cu->GetFixedFormSizes(), attributes,
+ depth);
+ }
+ if (depth == 0)
+ attributes.Clear();
+ return 0;
+}
+
+void DWARFBaseDIE::Dump(lldb_private::Stream *s,
+ const uint32_t recurse_depth) const {
+ if (s && IsValid())
+ m_die->Dump(GetDWARF(), GetCU(), *s, recurse_depth);
+}
+
+bool operator==(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs) {
+ return lhs.GetDIE() == rhs.GetDIE() && lhs.GetCU() == rhs.GetCU();
+}
+
+bool operator!=(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs) {
+ return !(lhs == rhs);
+}
+
+const DWARFDataExtractor &DWARFBaseDIE::GetData() const {
+ // Clients must check if this DIE is valid before calling this function.
+ assert(IsValid());
+ return m_cu->GetData();
+}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h b/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
new file mode 100644
index 000000000000..2163a027ffbc
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
@@ -0,0 +1,157 @@
+//===-- DWARFBaseDIE.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SymbolFileDWARF_DWARFBaseDIE_h_
+#define SymbolFileDWARF_DWARFBaseDIE_h_
+
+#include "lldb/Core/dwarf.h"
+#include "lldb/lldb-types.h"
+
+struct DIERef;
+class DWARFASTParser;
+class DWARFAttributes;
+class DWARFUnit;
+class DWARFDebugInfoEntry;
+class DWARFDeclContext;
+class DWARFDIECollection;
+class SymbolFileDWARF;
+
+class DWARFBaseDIE {
+public:
+ DWARFBaseDIE() : m_cu(nullptr), m_die(nullptr) {}
+
+ DWARFBaseDIE(DWARFUnit *cu, DWARFDebugInfoEntry *die)
+ : m_cu(cu), m_die(die) {}
+
+ DWARFBaseDIE(const DWARFUnit *cu, DWARFDebugInfoEntry *die)
+ : m_cu(const_cast<DWARFUnit *>(cu)), m_die(die) {}
+
+ DWARFBaseDIE(DWARFUnit *cu, const DWARFDebugInfoEntry *die)
+ : m_cu(cu), m_die(const_cast<DWARFDebugInfoEntry *>(die)) {}
+
+ DWARFBaseDIE(const DWARFUnit *cu, const DWARFDebugInfoEntry *die)
+ : m_cu(const_cast<DWARFUnit *>(cu)),
+ m_die(const_cast<DWARFDebugInfoEntry *>(die)) {}
+
+ //----------------------------------------------------------------------
+ // Tests
+ //----------------------------------------------------------------------
+ explicit operator bool() const { return IsValid(); }
+
+ bool IsValid() const { return m_cu && m_die; }
+
+ bool HasChildren() const;
+
+ bool Supports_DW_AT_APPLE_objc_complete_type() const;
+
+ //----------------------------------------------------------------------
+ // Accessors
+ //----------------------------------------------------------------------
+ SymbolFileDWARF *GetDWARF() const;
+
+ DWARFUnit *GetCU() const { return m_cu; }
+
+ DWARFDebugInfoEntry *GetDIE() const { return m_die; }
+
+ DIERef GetDIERef() const;
+
+ lldb_private::TypeSystem *GetTypeSystem() const;
+
+ DWARFASTParser *GetDWARFParser() const;
+
+ void Set(DWARFUnit *cu, DWARFDebugInfoEntry *die) {
+ if (cu && die) {
+ m_cu = cu;
+ m_die = die;
+ } else {
+ Clear();
+ }
+ }
+
+ void Clear() {
+ m_cu = nullptr;
+ m_die = nullptr;
+ }
+
+ //----------------------------------------------------------------------
+ // Get the data that contains the attribute values for this DIE. Support
+ // for .debug_types means that any DIE can have its data either in the
+ // .debug_info or the .debug_types section; this method will return the
+ // correct section data.
+ //
+ // Clients must validate that this object is valid before calling this.
+ //----------------------------------------------------------------------
+ const lldb_private::DWARFDataExtractor &GetData() const;
+
+ //----------------------------------------------------------------------
+ // Accessing information about a DIE
+ //----------------------------------------------------------------------
+ dw_tag_t Tag() const;
+
+ const char *GetTagAsCString() const;
+
+ dw_offset_t GetOffset() const;
+
+ dw_offset_t GetCompileUnitRelativeOffset() const;
+
+ //----------------------------------------------------------------------
+ // Get the LLDB user ID for this DIE. This is often just the DIE offset,
+ // but it might have a SymbolFileDWARF::GetID() in the high 32 bits if
+ // we are doing Darwin DWARF in .o file, or DWARF stand alone debug
+ // info.
+ //----------------------------------------------------------------------
+ lldb::user_id_t GetID() const;
+
+ const char *GetName() const;
+
+ lldb::LanguageType GetLanguage() const;
+
+ lldb::ModuleSP GetModule() const;
+
+ lldb_private::CompileUnit *GetLLDBCompileUnit() const;
+
+ //----------------------------------------------------------------------
+ // Getting attribute values from the DIE.
+ //
+ // GetAttributeValueAsXXX() functions should only be used if you are
+ // looking for one or two attributes on a DIE. If you are trying to
+ // parse all attributes, use GetAttributes (...) instead
+ //----------------------------------------------------------------------
+ const char *GetAttributeValueAsString(const dw_attr_t attr,
+ const char *fail_value) const;
+
+ uint64_t GetAttributeValueAsUnsigned(const dw_attr_t attr,
+ uint64_t fail_value) const;
+
+ int64_t GetAttributeValueAsSigned(const dw_attr_t attr,
+ int64_t fail_value) const;
+
+ uint64_t GetAttributeValueAsReference(const dw_attr_t attr,
+ uint64_t fail_value) const;
+
+ uint64_t GetAttributeValueAsAddress(const dw_attr_t attr,
+ uint64_t fail_value) const;
+
+ size_t GetAttributes(DWARFAttributes &attributes, uint32_t depth = 0) const;
+
+ //----------------------------------------------------------------------
+ // Pretty printing
+ //----------------------------------------------------------------------
+
+ void Dump(lldb_private::Stream *s, const uint32_t recurse_depth) const;
+
+protected:
+ DWARFUnit *m_cu;
+ DWARFDebugInfoEntry *m_die;
+};
+
+bool operator==(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs);
+bool operator!=(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs);
+
+#endif // SymbolFileDWARF_DWARFBaseDIE_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
index 5d7b12067263..8541f1cfe1f6 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -9,48 +9,22 @@
#include "DWARFCompileUnit.h"
-#include "Plugins/Language/ObjC/ObjCLanguage.h"
-#include "lldb/Core/DumpDataExtractor.h"
-#include "lldb/Core/Mangled.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Host/StringConvert.h"
-#include "lldb/Symbol/CompileUnit.h"
-#include "lldb/Symbol/LineTable.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Utility/Stream.h"
-#include "lldb/Utility/StreamString.h"
-#include "lldb/Utility/Timer.h"
-
-#include "DWARFDIECollection.h"
-#include "DWARFDebugAbbrev.h"
-#include "DWARFDebugAranges.h"
-#include "DWARFDebugInfo.h"
-#include "DWARFFormValue.h"
-#include "LogChannelDWARF.h"
-#include "NameToDIE.h"
#include "SymbolFileDWARF.h"
-#include "SymbolFileDWARFDebugMap.h"
-#include "SymbolFileDWARFDwo.h"
+#include "lldb/Utility/Stream.h"
using namespace lldb;
using namespace lldb_private;
-using namespace std;
extern int g_verbose;
DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF *dwarf2Data)
- : m_dwarf2Data(dwarf2Data) {}
+ : DWARFUnit(dwarf2Data) {}
-DWARFCompileUnit::~DWARFCompileUnit() {}
-
-DWARFCompileUnitSP DWARFCompileUnit::Extract(SymbolFileDWARF *dwarf2Data,
- lldb::offset_t *offset_ptr) {
- DWARFCompileUnitSP cu_sp(new DWARFCompileUnit(dwarf2Data));
- // Out of memory?
- if (cu_sp.get() == NULL)
- return nullptr;
-
- const DWARFDataExtractor &debug_info = dwarf2Data->get_debug_info_data();
+DWARFUnitSP DWARFCompileUnit::Extract(SymbolFileDWARF *dwarf2Data,
+ const DWARFDataExtractor &debug_info,
+ lldb::offset_t *offset_ptr) {
+ // std::make_shared would require the ctor to be public.
+ std::shared_ptr<DWARFCompileUnit> cu_sp(new DWARFCompileUnit(dwarf2Data));
cu_sp->m_offset = *offset_ptr;
@@ -83,259 +57,6 @@ DWARFCompileUnitSP DWARFCompileUnit::Extract(SymbolFileDWARF *dwarf2Data,
return nullptr;
}
-void DWARFCompileUnit::ClearDIEs(bool keep_compile_unit_die) {
- if (m_die_array.size() > 1) {
- // std::vectors never get any smaller when resized to a smaller size,
- // or when clear() or erase() are called, the size will report that it
- // is smaller, but the memory allocated remains intact (call capacity()
- // to see this). So we need to create a temporary vector and swap the
- // contents which will cause just the internal pointers to be swapped
- // so that when "tmp_array" goes out of scope, it will destroy the
- // contents.
-
- // Save at least the compile unit DIE
- DWARFDebugInfoEntry::collection tmp_array;
- m_die_array.swap(tmp_array);
- if (keep_compile_unit_die)
- m_die_array.push_back(tmp_array.front());
- }
-
- if (m_dwo_symbol_file)
- m_dwo_symbol_file->GetCompileUnit()->ClearDIEs(keep_compile_unit_die);
-}
-
-//----------------------------------------------------------------------
-// ParseCompileUnitDIEsIfNeeded
-//
-// Parses a compile unit and indexes its DIEs if it hasn't already been
-// done.
-//----------------------------------------------------------------------
-size_t DWARFCompileUnit::ExtractDIEsIfNeeded(bool cu_die_only) {
- const size_t initial_die_array_size = m_die_array.size();
- if ((cu_die_only && initial_die_array_size > 0) || initial_die_array_size > 1)
- return 0; // Already parsed
-
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(
- func_cat,
- "%8.8x: DWARFCompileUnit::ExtractDIEsIfNeeded( cu_die_only = %i )",
- m_offset, cu_die_only);
-
- // Set the offset to that of the first DIE and calculate the start of the
- // next compilation unit header.
- lldb::offset_t offset = GetFirstDIEOffset();
- lldb::offset_t next_cu_offset = GetNextCompileUnitOffset();
-
- DWARFDebugInfoEntry die;
- // Keep a flat array of the DIE for binary lookup by DIE offset
- if (!cu_die_only) {
- Log *log(
- LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_LOOKUPS));
- if (log) {
- m_dwarf2Data->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
- log, "DWARFCompileUnit::ExtractDIEsIfNeeded () for compile unit at "
- ".debug_info[0x%8.8x]",
- GetOffset());
- }
- }
-
- uint32_t depth = 0;
- // We are in our compile unit, parse starting at the offset
- // we were told to parse
- const DWARFDataExtractor &debug_info_data =
- m_dwarf2Data->get_debug_info_data();
- std::vector<uint32_t> die_index_stack;
- die_index_stack.reserve(32);
- die_index_stack.push_back(0);
- bool prev_die_had_children = false;
- DWARFFormValue::FixedFormSizes fixed_form_sizes =
- DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(),
- m_is_dwarf64);
- while (offset < next_cu_offset &&
- die.FastExtract(debug_info_data, this, fixed_form_sizes, &offset)) {
- // if (log)
- // log->Printf("0x%8.8x: %*.*s%s%s",
- // die.GetOffset(),
- // depth * 2, depth * 2, "",
- // DW_TAG_value_to_name (die.Tag()),
- // die.HasChildren() ? " *" : "");
-
- const bool null_die = die.IsNULL();
- if (depth == 0) {
- if (initial_die_array_size == 0)
- AddCompileUnitDIE(die);
- uint64_t base_addr = die.GetAttributeValueAsAddress(
- m_dwarf2Data, this, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
- if (base_addr == LLDB_INVALID_ADDRESS)
- base_addr = die.GetAttributeValueAsAddress(m_dwarf2Data, this,
- DW_AT_entry_pc, 0);
- SetBaseAddress(base_addr);
- if (cu_die_only)
- return 1;
- } else {
- if (null_die) {
- if (prev_die_had_children) {
- // This will only happen if a DIE says is has children
- // but all it contains is a NULL tag. Since we are removing
- // the NULL DIEs from the list (saves up to 25% in C++ code),
- // we need a way to let the DIE know that it actually doesn't
- // have children.
- if (!m_die_array.empty())
- m_die_array.back().SetEmptyChildren(true);
- }
- } else {
- die.SetParentIndex(m_die_array.size() - die_index_stack[depth - 1]);
-
- if (die_index_stack.back())
- m_die_array[die_index_stack.back()].SetSiblingIndex(
- m_die_array.size() - die_index_stack.back());
-
- // Only push the DIE if it isn't a NULL DIE
- m_die_array.push_back(die);
- }
- }
-
- if (null_die) {
- // NULL DIE.
- if (!die_index_stack.empty())
- die_index_stack.pop_back();
-
- if (depth > 0)
- --depth;
- if (depth == 0)
- break; // We are done with this compile unit!
-
- prev_die_had_children = false;
- } else {
- die_index_stack.back() = m_die_array.size() - 1;
- // Normal DIE
- const bool die_has_children = die.HasChildren();
- if (die_has_children) {
- die_index_stack.push_back(0);
- ++depth;
- }
- prev_die_had_children = die_has_children;
- }
- }
-
- // Give a little bit of info if we encounter corrupt DWARF (our offset
- // should always terminate at or before the start of the next compilation
- // unit header).
- if (offset > next_cu_offset) {
- m_dwarf2Data->GetObjectFile()->GetModule()->ReportWarning(
- "DWARF compile unit extends beyond its bounds cu 0x%8.8x at "
- "0x%8.8" PRIx64 "\n",
- GetOffset(), offset);
- }
-
- // Since std::vector objects will double their size, we really need to
- // make a new array with the perfect size so we don't end up wasting
- // space. So here we copy and swap to make sure we don't have any extra
- // memory taken up.
-
- if (m_die_array.size() < m_die_array.capacity()) {
- DWARFDebugInfoEntry::collection exact_size_die_array(m_die_array.begin(),
- m_die_array.end());
- exact_size_die_array.swap(m_die_array);
- }
- Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
- if (log && log->GetVerbose()) {
- StreamString strm;
- Dump(&strm);
- if (m_die_array.empty())
- strm.Printf("error: no DIE for compile unit");
- else
- m_die_array[0].Dump(m_dwarf2Data, this, strm, UINT32_MAX);
- log->PutString(strm.GetString());
- }
-
- if (!m_dwo_symbol_file)
- return m_die_array.size();
-
- DWARFCompileUnit *dwo_cu = m_dwo_symbol_file->GetCompileUnit();
- size_t dwo_die_count = dwo_cu->ExtractDIEsIfNeeded(cu_die_only);
- return m_die_array.size() + dwo_die_count -
- 1; // We have 2 CU die, but we want to count it only as one
-}
-
-void DWARFCompileUnit::AddCompileUnitDIE(DWARFDebugInfoEntry &die) {
- assert(m_die_array.empty() && "Compile unit DIE already added");
- AddDIE(die);
-
- const DWARFDebugInfoEntry &cu_die = m_die_array.front();
- std::unique_ptr<SymbolFileDWARFDwo> dwo_symbol_file =
- m_dwarf2Data->GetDwoSymbolFileForCompileUnit(*this, cu_die);
- if (!dwo_symbol_file)
- return;
-
- DWARFCompileUnit *dwo_cu = dwo_symbol_file->GetCompileUnit();
- if (!dwo_cu)
- return; // Can't fetch the compile unit from the dwo file.
-
- DWARFDIE dwo_cu_die = dwo_cu->GetCompileUnitDIEOnly();
- if (!dwo_cu_die.IsValid())
- return; // Can't fetch the compile unit DIE from the dwo file.
-
- uint64_t main_dwo_id = cu_die.GetAttributeValueAsUnsigned(
- m_dwarf2Data, this, DW_AT_GNU_dwo_id, 0);
- uint64_t sub_dwo_id =
- dwo_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_dwo_id, 0);
- if (main_dwo_id != sub_dwo_id)
- return; // The 2 dwo ID isn't match. Don't use the dwo file as it belongs to
- // a differectn compilation.
-
- m_dwo_symbol_file = std::move(dwo_symbol_file);
-
- dw_addr_t addr_base = cu_die.GetAttributeValueAsUnsigned(
- m_dwarf2Data, this, DW_AT_GNU_addr_base, 0);
- dw_addr_t ranges_base = cu_die.GetAttributeValueAsUnsigned(
- m_dwarf2Data, this, DW_AT_GNU_ranges_base, 0);
- dwo_cu->SetAddrBase(addr_base, ranges_base, m_offset);
-}
-
-dw_offset_t DWARFCompileUnit::GetAbbrevOffset() const {
- return m_abbrevs ? m_abbrevs->GetOffset() : DW_INVALID_OFFSET;
-}
-
-bool DWARFCompileUnit::Verify(Stream *s) const {
- const DWARFDataExtractor &debug_info = m_dwarf2Data->get_debug_info_data();
- bool valid_offset = debug_info.ValidOffset(m_offset);
- bool length_OK = debug_info.ValidOffset(GetNextCompileUnitOffset() - 1);
- bool version_OK = SymbolFileDWARF::SupportedVersion(m_version);
- bool abbr_offset_OK =
- m_dwarf2Data->get_debug_abbrev_data().ValidOffset(GetAbbrevOffset());
- bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8));
- if (valid_offset && length_OK && version_OK && addr_size_OK &&
- abbr_offset_OK) {
- return true;
- } else {
- s->Printf(" 0x%8.8x: ", m_offset);
- DumpDataExtractor(m_dwarf2Data->get_debug_info_data(), s, m_offset,
- lldb::eFormatHex, 1, Size(), 32, LLDB_INVALID_ADDRESS, 0,
- 0);
- s->EOL();
- if (valid_offset) {
- if (!length_OK)
- s->Printf(" The length (0x%8.8x) for this compile unit is too "
- "large for the .debug_info provided.\n",
- m_length);
- if (!version_OK)
- s->Printf(" The 16 bit compile unit header version is not "
- "supported.\n");
- if (!abbr_offset_OK)
- s->Printf(" The offset into the .debug_abbrev section (0x%8.8x) "
- "is not valid.\n",
- GetAbbrevOffset());
- if (!addr_size_OK)
- s->Printf(" The address size is unsupported: 0x%2.2x\n",
- m_addr_size);
- } else
- s->Printf(" The start offset of the compile unit header in the "
- ".debug_info is invalid.\n");
- }
- return false;
-}
-
void DWARFCompileUnit::Dump(Stream *s) const {
s->Printf("0x%8.8x: Compile Unit: length = 0x%8.8x, version = 0x%4.4x, "
"abbr_offset = 0x%8.8x, addr_size = 0x%2.2x (next CU at "
@@ -344,768 +65,7 @@ void DWARFCompileUnit::Dump(Stream *s) const {
GetNextCompileUnitOffset());
}
-static uint8_t g_default_addr_size = 4;
-
-uint8_t DWARFCompileUnit::GetAddressByteSize(const DWARFCompileUnit *cu) {
- if (cu)
- return cu->GetAddressByteSize();
- return DWARFCompileUnit::GetDefaultAddressSize();
-}
-
-bool DWARFCompileUnit::IsDWARF64(const DWARFCompileUnit *cu) {
- if (cu)
- return cu->IsDWARF64();
- return false;
-}
-
-uint8_t DWARFCompileUnit::GetDefaultAddressSize() {
- return g_default_addr_size;
-}
-
-void DWARFCompileUnit::SetDefaultAddressSize(uint8_t addr_size) {
- g_default_addr_size = addr_size;
-}
-
-lldb::user_id_t DWARFCompileUnit::GetID() const {
- dw_offset_t local_id =
- m_base_obj_offset != DW_INVALID_OFFSET ? m_base_obj_offset : m_offset;
- if (m_dwarf2Data)
- return DIERef(local_id, local_id).GetUID(m_dwarf2Data);
- else
- return local_id;
-}
-
-void DWARFCompileUnit::BuildAddressRangeTable(
- SymbolFileDWARF *dwarf2Data, DWARFDebugAranges *debug_aranges) {
- // This function is usually called if there in no .debug_aranges section
- // in order to produce a compile unit level set of address ranges that
- // is accurate.
-
- size_t num_debug_aranges = debug_aranges->GetNumRanges();
-
- // First get the compile unit DIE only and check if it has a DW_AT_ranges
- const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly();
-
- const dw_offset_t cu_offset = GetOffset();
- if (die) {
- DWARFRangeList ranges;
- const size_t num_ranges =
- die->GetAttributeAddressRanges(dwarf2Data, this, ranges, false);
- if (num_ranges > 0) {
- // This compile unit has DW_AT_ranges, assume this is correct if it
- // is present since clang no longer makes .debug_aranges by default
- // and it emits DW_AT_ranges for DW_TAG_compile_units. GCC also does
- // this with recent GCC builds.
- for (size_t i = 0; i < num_ranges; ++i) {
- const DWARFRangeList::Entry &range = ranges.GetEntryRef(i);
- debug_aranges->AppendRange(cu_offset, range.GetRangeBase(),
- range.GetRangeEnd());
- }
-
- return; // We got all of our ranges from the DW_AT_ranges attribute
- }
- }
- // We don't have a DW_AT_ranges attribute, so we need to parse the DWARF
-
- // If the DIEs weren't parsed, then we don't want all dies for all compile
- // units
- // to stay loaded when they weren't needed. So we can end up parsing the DWARF
- // and then throwing them all away to keep memory usage down.
- const bool clear_dies = ExtractDIEsIfNeeded(false) > 1;
-
- die = DIEPtr();
- if (die)
- die->BuildAddressRangeTable(dwarf2Data, this, debug_aranges);
-
- if (debug_aranges->GetNumRanges() == num_debug_aranges) {
- // We got nothing from the functions, maybe we have a line tables only
- // situation. Check the line tables and build the arange table from this.
- SymbolContext sc;
- sc.comp_unit = dwarf2Data->GetCompUnitForDWARFCompUnit(this);
- if (sc.comp_unit) {
- SymbolFileDWARFDebugMap *debug_map_sym_file =
- m_dwarf2Data->GetDebugMapSymfile();
- if (debug_map_sym_file == NULL) {
- LineTable *line_table = sc.comp_unit->GetLineTable();
-
- if (line_table) {
- LineTable::FileAddressRanges file_ranges;
- const bool append = true;
- const size_t num_ranges =
- line_table->GetContiguousFileAddressRanges(file_ranges, append);
- for (uint32_t idx = 0; idx < num_ranges; ++idx) {
- const LineTable::FileAddressRanges::Entry &range =
- file_ranges.GetEntryRef(idx);
- debug_aranges->AppendRange(cu_offset, range.GetRangeBase(),
- range.GetRangeEnd());
- }
- }
- } else
- debug_map_sym_file->AddOSOARanges(dwarf2Data, debug_aranges);
- }
- }
-
- if (debug_aranges->GetNumRanges() == num_debug_aranges) {
- // We got nothing from the functions, maybe we have a line tables only
- // situation. Check the line tables and build the arange table from this.
- SymbolContext sc;
- sc.comp_unit = dwarf2Data->GetCompUnitForDWARFCompUnit(this);
- if (sc.comp_unit) {
- LineTable *line_table = sc.comp_unit->GetLineTable();
-
- if (line_table) {
- LineTable::FileAddressRanges file_ranges;
- const bool append = true;
- const size_t num_ranges =
- line_table->GetContiguousFileAddressRanges(file_ranges, append);
- for (uint32_t idx = 0; idx < num_ranges; ++idx) {
- const LineTable::FileAddressRanges::Entry &range =
- file_ranges.GetEntryRef(idx);
- debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(),
- range.GetRangeEnd());
- }
- }
- }
- }
-
- // Keep memory down by clearing DIEs if this generate function
- // caused them to be parsed
- if (clear_dies)
- ClearDIEs(true);
-}
-
-const DWARFDebugAranges &DWARFCompileUnit::GetFunctionAranges() {
- if (m_func_aranges_ap.get() == NULL) {
- m_func_aranges_ap.reset(new DWARFDebugAranges());
- Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES));
-
- if (log) {
- m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage(
- log, "DWARFCompileUnit::GetFunctionAranges() for compile unit at "
- ".debug_info[0x%8.8x]",
- GetOffset());
- }
- const DWARFDebugInfoEntry *die = DIEPtr();
- if (die)
- die->BuildFunctionAddressRangeTable(m_dwarf2Data, this,
- m_func_aranges_ap.get());
-
- if (m_dwo_symbol_file) {
- DWARFCompileUnit *dwo_cu = m_dwo_symbol_file->GetCompileUnit();
- const DWARFDebugInfoEntry *dwo_die = dwo_cu->DIEPtr();
- if (dwo_die)
- dwo_die->BuildFunctionAddressRangeTable(m_dwo_symbol_file.get(), dwo_cu,
- m_func_aranges_ap.get());
- }
-
- const bool minimize = false;
- m_func_aranges_ap->Sort(minimize);
- }
- return *m_func_aranges_ap.get();
-}
-
-DWARFDIE
-DWARFCompileUnit::LookupAddress(const dw_addr_t address) {
- if (DIE()) {
- const DWARFDebugAranges &func_aranges = GetFunctionAranges();
-
- // Re-check the aranges auto pointer contents in case it was created above
- if (!func_aranges.IsEmpty())
- return GetDIE(func_aranges.FindAddress(address));
- }
- return DWARFDIE();
-}
-
-//----------------------------------------------------------------------
-// Compare function DWARFDebugAranges::Range structures
-//----------------------------------------------------------------------
-static bool CompareDIEOffset(const DWARFDebugInfoEntry &die,
- const dw_offset_t die_offset) {
- return die.GetOffset() < die_offset;
-}
-
-//----------------------------------------------------------------------
-// GetDIE()
-//
-// Get the DIE (Debug Information Entry) with the specified offset by
-// first checking if the DIE is contained within this compile unit and
-// grabbing the DIE from this compile unit. Otherwise we grab the DIE
-// from the DWARF file.
-//----------------------------------------------------------------------
-DWARFDIE
-DWARFCompileUnit::GetDIE(dw_offset_t die_offset) {
- if (die_offset != DW_INVALID_OFFSET) {
- if (m_dwo_symbol_file)
- return m_dwo_symbol_file->GetCompileUnit()->GetDIE(die_offset);
-
- if (ContainsDIEOffset(die_offset)) {
- ExtractDIEsIfNeeded(false);
- DWARFDebugInfoEntry::iterator end = m_die_array.end();
- DWARFDebugInfoEntry::iterator pos =
- lower_bound(m_die_array.begin(), end, die_offset, CompareDIEOffset);
- if (pos != end) {
- if (die_offset == (*pos).GetOffset())
- return DWARFDIE(this, &(*pos));
- }
- } else {
- // Don't specify the compile unit offset as we don't know it because the
- // DIE belongs to
- // a different compile unit in the same symbol file.
- return m_dwarf2Data->DebugInfo()->GetDIEForDIEOffset(die_offset);
- }
- }
- return DWARFDIE(); // Not found
-}
-
-size_t DWARFCompileUnit::AppendDIEsWithTag(const dw_tag_t tag,
- DWARFDIECollection &dies,
- uint32_t depth) const {
- size_t old_size = dies.Size();
- DWARFDebugInfoEntry::const_iterator pos;
- DWARFDebugInfoEntry::const_iterator end = m_die_array.end();
- for (pos = m_die_array.begin(); pos != end; ++pos) {
- if (pos->Tag() == tag)
- dies.Append(DWARFDIE(this, &(*pos)));
- }
-
- // Return the number of DIEs added to the collection
- return dies.Size() - old_size;
-}
-
-// void
-// DWARFCompileUnit::AddGlobalDIEByIndex (uint32_t die_idx)
-//{
-// m_global_die_indexes.push_back (die_idx);
-//}
-//
-//
-// void
-// DWARFCompileUnit::AddGlobal (const DWARFDebugInfoEntry* die)
-//{
-// // Indexes to all file level global and static variables
-// m_global_die_indexes;
-//
-// if (m_die_array.empty())
-// return;
-//
-// const DWARFDebugInfoEntry* first_die = &m_die_array[0];
-// const DWARFDebugInfoEntry* end = first_die + m_die_array.size();
-// if (first_die <= die && die < end)
-// m_global_die_indexes.push_back (die - first_die);
-//}
-
-void DWARFCompileUnit::Index(NameToDIE &func_basenames,
- NameToDIE &func_fullnames, NameToDIE &func_methods,
- NameToDIE &func_selectors,
- NameToDIE &objc_class_selectors,
- NameToDIE &globals, NameToDIE &types,
- NameToDIE &namespaces) {
- assert(!m_dwarf2Data->GetBaseCompileUnit() &&
- "DWARFCompileUnit associated with .dwo or .dwp "
- "should not be indexed directly");
-
- Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
-
- if (log) {
- m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage(
- log,
- "DWARFCompileUnit::Index() for compile unit at .debug_info[0x%8.8x]",
- GetOffset());
- }
-
- const LanguageType cu_language = GetLanguageType();
- DWARFFormValue::FixedFormSizes fixed_form_sizes =
- DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(),
- m_is_dwarf64);
-
- IndexPrivate(this, cu_language, fixed_form_sizes, GetOffset(), func_basenames,
- func_fullnames, func_methods, func_selectors,
- objc_class_selectors, globals, types, namespaces);
-
- SymbolFileDWARFDwo *dwo_symbol_file = GetDwoSymbolFile();
- if (dwo_symbol_file) {
- IndexPrivate(dwo_symbol_file->GetCompileUnit(), cu_language,
- fixed_form_sizes, GetOffset(), func_basenames, func_fullnames,
- func_methods, func_selectors, objc_class_selectors, globals,
- types, namespaces);
- }
-}
-
-void DWARFCompileUnit::IndexPrivate(
- DWARFCompileUnit *dwarf_cu, const LanguageType cu_language,
- const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
- const dw_offset_t cu_offset, NameToDIE &func_basenames,
- NameToDIE &func_fullnames, NameToDIE &func_methods,
- NameToDIE &func_selectors, NameToDIE &objc_class_selectors,
- NameToDIE &globals, NameToDIE &types, NameToDIE &namespaces) {
- DWARFDebugInfoEntry::const_iterator pos;
- DWARFDebugInfoEntry::const_iterator begin = dwarf_cu->m_die_array.begin();
- DWARFDebugInfoEntry::const_iterator end = dwarf_cu->m_die_array.end();
- for (pos = begin; pos != end; ++pos) {
- const DWARFDebugInfoEntry &die = *pos;
-
- const dw_tag_t tag = die.Tag();
-
- switch (tag) {
- case DW_TAG_array_type:
- case DW_TAG_base_type:
- case DW_TAG_class_type:
- case DW_TAG_constant:
- case DW_TAG_enumeration_type:
- case DW_TAG_inlined_subroutine:
- case DW_TAG_namespace:
- case DW_TAG_string_type:
- case DW_TAG_structure_type:
- case DW_TAG_subprogram:
- case DW_TAG_subroutine_type:
- case DW_TAG_typedef:
- case DW_TAG_union_type:
- case DW_TAG_unspecified_type:
- case DW_TAG_variable:
- break;
-
- default:
- continue;
- }
-
- DWARFAttributes attributes;
- const char *name = NULL;
- const char *mangled_cstr = NULL;
- bool is_declaration = false;
- // bool is_artificial = false;
- bool has_address = false;
- bool has_location_or_const_value = false;
- bool is_global_or_static_variable = false;
-
- DWARFFormValue specification_die_form;
- const size_t num_attributes =
- die.GetAttributes(dwarf_cu, fixed_form_sizes, attributes);
- if (num_attributes > 0) {
- for (uint32_t i = 0; i < num_attributes; ++i) {
- dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
- switch (attr) {
- case DW_AT_name:
- if (attributes.ExtractFormValueAtIndex(i, form_value))
- name = form_value.AsCString();
- break;
-
- case DW_AT_declaration:
- if (attributes.ExtractFormValueAtIndex(i, form_value))
- is_declaration = form_value.Unsigned() != 0;
- break;
-
- // case DW_AT_artificial:
- // if (attributes.ExtractFormValueAtIndex(i,
- // form_value))
- // is_artificial = form_value.Unsigned() != 0;
- // break;
-
- case DW_AT_MIPS_linkage_name:
- case DW_AT_linkage_name:
- if (attributes.ExtractFormValueAtIndex(i, form_value))
- mangled_cstr = form_value.AsCString();
- break;
-
- case DW_AT_low_pc:
- case DW_AT_high_pc:
- case DW_AT_ranges:
- has_address = true;
- break;
-
- case DW_AT_entry_pc:
- has_address = true;
- break;
-
- case DW_AT_location:
- case DW_AT_const_value:
- has_location_or_const_value = true;
- if (tag == DW_TAG_variable) {
- const DWARFDebugInfoEntry *parent_die = die.GetParent();
- while (parent_die != NULL) {
- switch (parent_die->Tag()) {
- case DW_TAG_subprogram:
- case DW_TAG_lexical_block:
- case DW_TAG_inlined_subroutine:
- // Even if this is a function level static, we don't add it. We
- // could theoretically
- // add these if we wanted to by introspecting into the
- // DW_AT_location and seeing
- // if the location describes a hard coded address, but we dont
- // want the performance
- // penalty of that right now.
- is_global_or_static_variable = false;
- // if
- // (attributes.ExtractFormValueAtIndex(dwarf2Data,
- // i, form_value))
- // {
- // // If we have valid block
- // data, then we have location
- // expression bytes
- // // that are fixed (not a
- // location list).
- // const uint8_t *block_data =
- // form_value.BlockData();
- // if (block_data)
- // {
- // uint32_t block_length =
- // form_value.Unsigned();
- // if (block_length == 1 +
- // attributes.CompileUnitAtIndex(i)->GetAddressByteSize())
- // {
- // if (block_data[0] ==
- // DW_OP_addr)
- // add_die = true;
- // }
- // }
- // }
- parent_die = NULL; // Terminate the while loop.
- break;
-
- case DW_TAG_compile_unit:
- is_global_or_static_variable = true;
- parent_die = NULL; // Terminate the while loop.
- break;
-
- default:
- parent_die =
- parent_die->GetParent(); // Keep going in the while loop.
- break;
- }
- }
- }
- break;
-
- case DW_AT_specification:
- if (attributes.ExtractFormValueAtIndex(i, form_value))
- specification_die_form = form_value;
- break;
- }
- }
- }
-
- switch (tag) {
- case DW_TAG_subprogram:
- if (has_address) {
- if (name) {
- ObjCLanguage::MethodName objc_method(name, true);
- if (objc_method.IsValid(true)) {
- ConstString objc_class_name_with_category(
- objc_method.GetClassNameWithCategory());
- ConstString objc_selector_name(objc_method.GetSelector());
- ConstString objc_fullname_no_category_name(
- objc_method.GetFullNameWithoutCategory(true));
- ConstString objc_class_name_no_category(objc_method.GetClassName());
- func_fullnames.Insert(ConstString(name),
- DIERef(cu_offset, die.GetOffset()));
- if (objc_class_name_with_category)
- objc_class_selectors.Insert(objc_class_name_with_category,
- DIERef(cu_offset, die.GetOffset()));
- if (objc_class_name_no_category &&
- objc_class_name_no_category != objc_class_name_with_category)
- objc_class_selectors.Insert(objc_class_name_no_category,
- DIERef(cu_offset, die.GetOffset()));
- if (objc_selector_name)
- func_selectors.Insert(objc_selector_name,
- DIERef(cu_offset, die.GetOffset()));
- if (objc_fullname_no_category_name)
- func_fullnames.Insert(objc_fullname_no_category_name,
- DIERef(cu_offset, die.GetOffset()));
- }
- // If we have a mangled name, then the DW_AT_name attribute
- // is usually the method name without the class or any parameters
- const DWARFDebugInfoEntry *parent = die.GetParent();
- bool is_method = false;
- if (parent) {
- dw_tag_t parent_tag = parent->Tag();
- if (parent_tag == DW_TAG_class_type ||
- parent_tag == DW_TAG_structure_type) {
- is_method = true;
- } else {
- if (specification_die_form.IsValid()) {
- DWARFDIE specification_die =
- dwarf_cu->GetSymbolFileDWARF()->DebugInfo()->GetDIE(
- DIERef(specification_die_form));
- if (specification_die.GetParent().IsStructOrClass())
- is_method = true;
- }
- }
- }
-
- if (is_method)
- func_methods.Insert(ConstString(name),
- DIERef(cu_offset, die.GetOffset()));
- else
- func_basenames.Insert(ConstString(name),
- DIERef(cu_offset, die.GetOffset()));
-
- if (!is_method && !mangled_cstr && !objc_method.IsValid(true))
- func_fullnames.Insert(ConstString(name),
- DIERef(cu_offset, die.GetOffset()));
- }
- if (mangled_cstr) {
- // Make sure our mangled name isn't the same string table entry
- // as our name. If it starts with '_', then it is ok, else compare
- // the string to make sure it isn't the same and we don't end up
- // with duplicate entries
- if (name && name != mangled_cstr &&
- ((mangled_cstr[0] == '_') ||
- (::strcmp(name, mangled_cstr) != 0))) {
- Mangled mangled(ConstString(mangled_cstr), true);
- func_fullnames.Insert(mangled.GetMangledName(),
- DIERef(cu_offset, die.GetOffset()));
- ConstString demangled = mangled.GetDemangledName(cu_language);
- if (demangled)
- func_fullnames.Insert(demangled,
- DIERef(cu_offset, die.GetOffset()));
- }
- }
- }
- break;
-
- case DW_TAG_inlined_subroutine:
- if (has_address) {
- if (name)
- func_basenames.Insert(ConstString(name),
- DIERef(cu_offset, die.GetOffset()));
- if (mangled_cstr) {
- // Make sure our mangled name isn't the same string table entry
- // as our name. If it starts with '_', then it is ok, else compare
- // the string to make sure it isn't the same and we don't end up
- // with duplicate entries
- if (name && name != mangled_cstr &&
- ((mangled_cstr[0] == '_') ||
- (::strcmp(name, mangled_cstr) != 0))) {
- Mangled mangled(ConstString(mangled_cstr), true);
- func_fullnames.Insert(mangled.GetMangledName(),
- DIERef(cu_offset, die.GetOffset()));
- ConstString demangled = mangled.GetDemangledName(cu_language);
- if (demangled)
- func_fullnames.Insert(demangled,
- DIERef(cu_offset, die.GetOffset()));
- }
- } else
- func_fullnames.Insert(ConstString(name),
- DIERef(cu_offset, die.GetOffset()));
- }
- break;
-
- case DW_TAG_array_type:
- case DW_TAG_base_type:
- case DW_TAG_class_type:
- case DW_TAG_constant:
- case DW_TAG_enumeration_type:
- case DW_TAG_string_type:
- case DW_TAG_structure_type:
- case DW_TAG_subroutine_type:
- case DW_TAG_typedef:
- case DW_TAG_union_type:
- case DW_TAG_unspecified_type:
- if (name && !is_declaration)
- types.Insert(ConstString(name), DIERef(cu_offset, die.GetOffset()));
- if (mangled_cstr && !is_declaration)
- types.Insert(ConstString(mangled_cstr),
- DIERef(cu_offset, die.GetOffset()));
- break;
-
- case DW_TAG_namespace:
- if (name)
- namespaces.Insert(ConstString(name),
- DIERef(cu_offset, die.GetOffset()));
- break;
-
- case DW_TAG_variable:
- if (name && has_location_or_const_value && is_global_or_static_variable) {
- globals.Insert(ConstString(name), DIERef(cu_offset, die.GetOffset()));
- // Be sure to include variables by their mangled and demangled
- // names if they have any since a variable can have a basename
- // "i", a mangled named "_ZN12_GLOBAL__N_11iE" and a demangled
- // mangled name "(anonymous namespace)::i"...
-
- // Make sure our mangled name isn't the same string table entry
- // as our name. If it starts with '_', then it is ok, else compare
- // the string to make sure it isn't the same and we don't end up
- // with duplicate entries
- if (mangled_cstr && name != mangled_cstr &&
- ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) {
- Mangled mangled(ConstString(mangled_cstr), true);
- globals.Insert(mangled.GetMangledName(),
- DIERef(cu_offset, die.GetOffset()));
- ConstString demangled = mangled.GetDemangledName(cu_language);
- if (demangled)
- globals.Insert(demangled, DIERef(cu_offset, die.GetOffset()));
- }
- }
- break;
-
- default:
- continue;
- }
- }
-}
-
-bool DWARFCompileUnit::Supports_unnamed_objc_bitfields() {
- if (GetProducer() == eProducerClang) {
- const uint32_t major_version = GetProducerVersionMajor();
- if (major_version > 425 ||
- (major_version == 425 && GetProducerVersionUpdate() >= 13))
- return true;
- else
- return false;
- }
- return true; // Assume all other compilers didn't have incorrect ObjC bitfield
- // info
-}
-
-bool DWARFCompileUnit::Supports_DW_AT_APPLE_objc_complete_type() {
- if (GetProducer() == eProducerLLVMGCC)
- return false;
- return true;
-}
-
-bool DWARFCompileUnit::DW_AT_decl_file_attributes_are_invalid() {
- // llvm-gcc makes completely invalid decl file attributes and won't ever
- // be fixed, so we need to know to ignore these.
- return GetProducer() == eProducerLLVMGCC;
-}
-
-void DWARFCompileUnit::ParseProducerInfo() {
- m_producer_version_major = UINT32_MAX;
- m_producer_version_minor = UINT32_MAX;
- m_producer_version_update = UINT32_MAX;
-
- const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly();
- if (die) {
-
- const char *producer_cstr = die->GetAttributeValueAsString(
- m_dwarf2Data, this, DW_AT_producer, NULL);
- if (producer_cstr) {
- RegularExpression llvm_gcc_regex(
- llvm::StringRef("^4\\.[012]\\.[01] \\(Based on Apple "
- "Inc\\. build [0-9]+\\) \\(LLVM build "
- "[\\.0-9]+\\)$"));
- if (llvm_gcc_regex.Execute(llvm::StringRef(producer_cstr))) {
- m_producer = eProducerLLVMGCC;
- } else if (strstr(producer_cstr, "clang")) {
- static RegularExpression g_clang_version_regex(
- llvm::StringRef("clang-([0-9]+)\\.([0-9]+)\\.([0-9]+)"));
- RegularExpression::Match regex_match(3);
- if (g_clang_version_regex.Execute(llvm::StringRef(producer_cstr),
- &regex_match)) {
- std::string str;
- if (regex_match.GetMatchAtIndex(producer_cstr, 1, str))
- m_producer_version_major =
- StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
- if (regex_match.GetMatchAtIndex(producer_cstr, 2, str))
- m_producer_version_minor =
- StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
- if (regex_match.GetMatchAtIndex(producer_cstr, 3, str))
- m_producer_version_update =
- StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
- }
- m_producer = eProducerClang;
- } else if (strstr(producer_cstr, "GNU"))
- m_producer = eProducerGCC;
- }
- }
- if (m_producer == eProducerInvalid)
- m_producer = eProcucerOther;
-}
-
-DWARFCompileUnit::Producer DWARFCompileUnit::GetProducer() {
- if (m_producer == eProducerInvalid)
- ParseProducerInfo();
- return m_producer;
-}
-
-uint32_t DWARFCompileUnit::GetProducerVersionMajor() {
- if (m_producer_version_major == 0)
- ParseProducerInfo();
- return m_producer_version_major;
-}
-
-uint32_t DWARFCompileUnit::GetProducerVersionMinor() {
- if (m_producer_version_minor == 0)
- ParseProducerInfo();
- return m_producer_version_minor;
-}
-
-uint32_t DWARFCompileUnit::GetProducerVersionUpdate() {
- if (m_producer_version_update == 0)
- ParseProducerInfo();
- return m_producer_version_update;
-}
-
-LanguageType DWARFCompileUnit::LanguageTypeFromDWARF(uint64_t val) {
- // Note: user languages between lo_user and hi_user
- // must be handled explicitly here.
- switch (val) {
- case DW_LANG_Mips_Assembler:
- return eLanguageTypeMipsAssembler;
- case DW_LANG_GOOGLE_RenderScript:
- return eLanguageTypeExtRenderScript;
- default:
- return static_cast<LanguageType>(val);
- }
-}
-
-LanguageType DWARFCompileUnit::GetLanguageType() {
- if (m_language_type != eLanguageTypeUnknown)
- return m_language_type;
-
- const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly();
- if (die)
- m_language_type = LanguageTypeFromDWARF(die->GetAttributeValueAsUnsigned(
- m_dwarf2Data, this, DW_AT_language, 0));
- return m_language_type;
-}
-
-bool DWARFCompileUnit::IsDWARF64() const { return m_is_dwarf64; }
-
-bool DWARFCompileUnit::GetIsOptimized() {
- if (m_is_optimized == eLazyBoolCalculate) {
- const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly();
- if (die) {
- m_is_optimized = eLazyBoolNo;
- if (die->GetAttributeValueAsUnsigned(m_dwarf2Data, this,
- DW_AT_APPLE_optimized, 0) == 1) {
- m_is_optimized = eLazyBoolYes;
- }
- }
- }
- if (m_is_optimized == eLazyBoolYes) {
- return true;
- } else {
- return false;
- }
-}
-
-DWARFFormValue::FixedFormSizes DWARFCompileUnit::GetFixedFormSizes() {
- return DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(),
- IsDWARF64());
-}
-
-TypeSystem *DWARFCompileUnit::GetTypeSystem() {
- if (m_dwarf2Data)
- return m_dwarf2Data->GetTypeSystemForLanguage(GetLanguageType());
- else
- return nullptr;
-}
-
-void DWARFCompileUnit::SetUserData(void *d) {
- m_user_data = d;
- if (m_dwo_symbol_file)
- m_dwo_symbol_file->GetCompileUnit()->SetUserData(d);
-}
-
-void DWARFCompileUnit::SetAddrBase(dw_addr_t addr_base,
- dw_addr_t ranges_base,
- dw_offset_t base_obj_offset) {
- m_addr_base = addr_base;
- m_ranges_base = ranges_base;
- m_base_obj_offset = base_obj_offset;
-}
-lldb::ByteOrder DWARFCompileUnit::GetByteOrder() const {
- return m_dwarf2Data->GetObjectFile()->GetByteOrder();
+const lldb_private::DWARFDataExtractor &DWARFCompileUnit::GetData() const {
+ return m_dwarf->get_debug_info_data();
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
index 8ea0d6465adf..9c1fc82f58b7 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -10,214 +10,39 @@
#ifndef SymbolFileDWARF_DWARFCompileUnit_h_
#define SymbolFileDWARF_DWARFCompileUnit_h_
-#include "DWARFDIE.h"
-#include "DWARFDebugInfoEntry.h"
-#include "lldb/lldb-enumerations.h"
+#include "DWARFUnit.h"
-class NameToDIE;
-class SymbolFileDWARF;
-class SymbolFileDWARFDwo;
+class DWARFCompileUnit : public DWARFUnit {
+ friend class DWARFUnit;
-typedef std::shared_ptr<DWARFCompileUnit> DWARFCompileUnitSP;
-
-class DWARFCompileUnit {
public:
- enum Producer {
- eProducerInvalid = 0,
- eProducerClang,
- eProducerGCC,
- eProducerLLVMGCC,
- eProcucerOther
- };
-
- static DWARFCompileUnitSP Extract(SymbolFileDWARF *dwarf2Data,
- lldb::offset_t *offset_ptr);
- ~DWARFCompileUnit();
-
- size_t ExtractDIEsIfNeeded(bool cu_die_only);
- DWARFDIE LookupAddress(const dw_addr_t address);
- size_t AppendDIEsWithTag(const dw_tag_t tag,
- DWARFDIECollection &matching_dies,
- uint32_t depth = UINT32_MAX) const;
- bool Verify(lldb_private::Stream *s) const;
- void Dump(lldb_private::Stream *s) const;
- // Offset of the initial length field.
- dw_offset_t GetOffset() const { return m_offset; }
- lldb::user_id_t GetID() const;
- // Size in bytes of the initial length + compile unit header.
- uint32_t Size() const { return m_is_dwarf64 ? 23 : 11; }
- bool ContainsDIEOffset(dw_offset_t die_offset) const {
- return die_offset >= GetFirstDIEOffset() &&
- die_offset < GetNextCompileUnitOffset();
- }
- dw_offset_t GetFirstDIEOffset() const { return m_offset + Size(); }
- dw_offset_t GetNextCompileUnitOffset() const {
- return m_offset + (m_is_dwarf64 ? 12 : 4) + m_length;
- }
- // Size of the CU data (without initial length and without header).
- size_t GetDebugInfoSize() const {
- return (m_is_dwarf64 ? 12 : 4) + m_length - Size();
- }
- // Size of the CU data incl. header but without initial length.
- uint32_t GetLength() const { return m_length; }
- uint16_t GetVersion() const { return m_version; }
- const DWARFAbbreviationDeclarationSet *GetAbbreviations() const {
- return m_abbrevs;
- }
- dw_offset_t GetAbbrevOffset() const;
- uint8_t GetAddressByteSize() const { return m_addr_size; }
- dw_addr_t GetBaseAddress() const { return m_base_addr; }
- dw_addr_t GetAddrBase() const { return m_addr_base; }
- dw_addr_t GetRangesBase() const { return m_ranges_base; }
- void SetAddrBase(dw_addr_t addr_base, dw_addr_t ranges_base, dw_offset_t base_obj_offset);
- void ClearDIEs(bool keep_compile_unit_die);
- void BuildAddressRangeTable(SymbolFileDWARF *dwarf2Data,
- DWARFDebugAranges *debug_aranges);
-
- lldb::ByteOrder GetByteOrder() const;
-
- lldb_private::TypeSystem *GetTypeSystem();
-
- DWARFFormValue::FixedFormSizes GetFixedFormSizes();
-
- void SetBaseAddress(dw_addr_t base_addr) { m_base_addr = base_addr; }
-
- DWARFDIE
- GetCompileUnitDIEOnly() { return DWARFDIE(this, GetCompileUnitDIEPtrOnly()); }
+ static DWARFUnitSP Extract(SymbolFileDWARF *dwarf2Data,
+ const lldb_private::DWARFDataExtractor &debug_info,
+ lldb::offset_t *offset_ptr);
+ void Dump(lldb_private::Stream *s) const override;
- DWARFDIE
- DIE() { return DWARFDIE(this, DIEPtr()); }
+ //------------------------------------------------------------------
+ /// Get the data that contains the DIE information for this unit.
+ ///
+ /// @return
+ /// The correct data (.debug_types for DWARF 4 and earlier, and
+ /// .debug_info for DWARF 5 and later) for the DIE information in
+ /// this unit.
+ //------------------------------------------------------------------
+ const lldb_private::DWARFDataExtractor &GetData() const override;
- void AddDIE(DWARFDebugInfoEntry &die) {
- // The average bytes per DIE entry has been seen to be
- // around 14-20 so lets pre-reserve half of that since
- // we are now stripping the NULL tags.
-
- // Only reserve the memory if we are adding children of
- // the main compile unit DIE. The compile unit DIE is always
- // the first entry, so if our size is 1, then we are adding
- // the first compile unit child DIE and should reserve
- // the memory.
- if (m_die_array.empty())
- m_die_array.reserve(GetDebugInfoSize() / 24);
- m_die_array.push_back(die);
+ //------------------------------------------------------------------
+ /// Get the size in bytes of the header.
+ ///
+ /// @return
+ /// Byte size of the compile unit header
+ //------------------------------------------------------------------
+ uint32_t GetHeaderByteSize() const override {
+ return m_is_dwarf64 ? 23 : 11;
}
- void AddCompileUnitDIE(DWARFDebugInfoEntry &die);
-
- bool HasDIEsParsed() const { return m_die_array.size() > 1; }
-
- DWARFDIE
- GetDIE(dw_offset_t die_offset);
-
- static uint8_t GetAddressByteSize(const DWARFCompileUnit *cu);
-
- static bool IsDWARF64(const DWARFCompileUnit *cu);
-
- static uint8_t GetDefaultAddressSize();
-
- static void SetDefaultAddressSize(uint8_t addr_size);
-
- void *GetUserData() const { return m_user_data; }
-
- void SetUserData(void *d);
-
- bool Supports_DW_AT_APPLE_objc_complete_type();
-
- bool DW_AT_decl_file_attributes_are_invalid();
-
- bool Supports_unnamed_objc_bitfields();
-
- void Index(NameToDIE &func_basenames, NameToDIE &func_fullnames,
- NameToDIE &func_methods, NameToDIE &func_selectors,
- NameToDIE &objc_class_selectors, NameToDIE &globals,
- NameToDIE &types, NameToDIE &namespaces);
-
- const DWARFDebugAranges &GetFunctionAranges();
-
- SymbolFileDWARF *GetSymbolFileDWARF() const { return m_dwarf2Data; }
-
- Producer GetProducer();
-
- uint32_t GetProducerVersionMajor();
-
- uint32_t GetProducerVersionMinor();
-
- uint32_t GetProducerVersionUpdate();
-
- static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val);
-
- lldb::LanguageType GetLanguageType();
-
- bool IsDWARF64() const;
-
- bool GetIsOptimized();
-
- SymbolFileDWARFDwo *GetDwoSymbolFile() const {
- return m_dwo_symbol_file.get();
- }
-
- dw_offset_t GetBaseObjOffset() const { return m_base_obj_offset; }
-
-protected:
- SymbolFileDWARF *m_dwarf2Data;
- std::unique_ptr<SymbolFileDWARFDwo> m_dwo_symbol_file;
- const DWARFAbbreviationDeclarationSet *m_abbrevs;
- void *m_user_data = nullptr;
- DWARFDebugInfoEntry::collection
- m_die_array; // The compile unit debug information entry item
- std::unique_ptr<DWARFDebugAranges> m_func_aranges_ap; // A table similar to
- // the .debug_aranges
- // table, but this one
- // points to the exact
- // DW_TAG_subprogram
- // DIEs
- dw_addr_t m_base_addr = 0;
- // Offset of the initial length field.
- dw_offset_t m_offset;
- dw_offset_t m_length;
- uint16_t m_version;
- uint8_t m_addr_size;
- Producer m_producer = eProducerInvalid;
- uint32_t m_producer_version_major = 0;
- uint32_t m_producer_version_minor = 0;
- uint32_t m_producer_version_update = 0;
- lldb::LanguageType m_language_type = lldb::eLanguageTypeUnknown;
- bool m_is_dwarf64;
- lldb_private::LazyBool m_is_optimized = lldb_private::eLazyBoolCalculate;
- dw_addr_t m_addr_base = 0; // Value of DW_AT_addr_base
- dw_addr_t m_ranges_base = 0; // Value of DW_AT_ranges_base
- // If this is a dwo compile unit this is the offset of the base compile unit
- // in the main object file
- dw_offset_t m_base_obj_offset = DW_INVALID_OFFSET;
-
- void ParseProducerInfo();
-
- static void
- IndexPrivate(DWARFCompileUnit *dwarf_cu, const lldb::LanguageType cu_language,
- const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
- const dw_offset_t cu_offset, NameToDIE &func_basenames,
- NameToDIE &func_fullnames, NameToDIE &func_methods,
- NameToDIE &func_selectors, NameToDIE &objc_class_selectors,
- NameToDIE &globals, NameToDIE &types, NameToDIE &namespaces);
-
private:
DWARFCompileUnit(SymbolFileDWARF *dwarf2Data);
-
- const DWARFDebugInfoEntry *GetCompileUnitDIEPtrOnly() {
- ExtractDIEsIfNeeded(true);
- if (m_die_array.empty())
- return NULL;
- return &m_die_array[0];
- }
-
- const DWARFDebugInfoEntry *DIEPtr() {
- ExtractDIEsIfNeeded(false);
- if (m_die_array.empty())
- return NULL;
- return &m_die_array[0];
- }
-
DISALLOW_COPY_AND_ASSIGN(DWARFCompileUnit);
};
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index 4ef2e772ea5d..d9754e911017 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -10,43 +10,27 @@
#include "DWARFDIE.h"
#include "DWARFASTParser.h"
-#include "DWARFCompileUnit.h"
#include "DWARFDIECollection.h"
-#include "DWARFDebugAbbrev.h"
-#include "DWARFDebugAranges.h"
#include "DWARFDebugInfo.h"
#include "DWARFDebugInfoEntry.h"
-#include "DWARFDebugRanges.h"
#include "DWARFDeclContext.h"
-#include "DWARFFormValue.h"
-#include "SymbolFileDWARF.h"
-
-#include "lldb/Core/Module.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/Type.h"
-#include "lldb/Symbol/TypeSystem.h"
+#include "DWARFUnit.h"
using namespace lldb_private;
-DIERef DWARFDIE::GetDIERef() const {
- if (!IsValid())
- return DIERef();
-
- dw_offset_t cu_offset = m_cu->GetOffset();
- if (m_cu->GetBaseObjOffset() != DW_INVALID_OFFSET)
- cu_offset = m_cu->GetBaseObjOffset();
- return DIERef(cu_offset, m_die->GetOffset());
-}
+void DWARFDIE::ElaboratingDIEIterator::Next() {
+ assert(!m_worklist.empty() && "Incrementing end iterator?");
-dw_tag_t DWARFDIE::Tag() const {
- if (m_die)
- return m_die->Tag();
- else
- return 0;
-}
+ // Pop the current item from the list.
+ DWARFDIE die = m_worklist.back();
+ m_worklist.pop_back();
-const char *DWARFDIE::GetTagAsCString() const {
- return lldb_private::DW_TAG_value_to_name(Tag());
+ // And add back any items that elaborate it.
+ for (dw_attr_t attr : {DW_AT_specification, DW_AT_abstract_origin}) {
+ if (DWARFDIE d = die.GetReferencedDIE(attr))
+ if (m_seen.insert(die.GetID()).second)
+ m_worklist.push_back(d);
+ }
}
DWARFDIE
@@ -91,37 +75,10 @@ DWARFDIE::GetDIE(dw_offset_t die_offset) const {
return DWARFDIE();
}
-const char *DWARFDIE::GetAttributeValueAsString(const dw_attr_t attr,
- const char *fail_value) const {
- if (IsValid())
- return m_die->GetAttributeValueAsString(GetDWARF(), GetCU(), attr,
- fail_value);
- else
- return fail_value;
-}
-
-uint64_t DWARFDIE::GetAttributeValueAsUnsigned(const dw_attr_t attr,
- uint64_t fail_value) const {
- if (IsValid())
- return m_die->GetAttributeValueAsUnsigned(GetDWARF(), GetCU(), attr,
- fail_value);
- else
- return fail_value;
-}
-
-int64_t DWARFDIE::GetAttributeValueAsSigned(const dw_attr_t attr,
- int64_t fail_value) const {
- if (IsValid())
- return m_die->GetAttributeValueAsSigned(GetDWARF(), GetCU(), attr,
- fail_value);
- else
- return fail_value;
-}
-
DWARFDIE
DWARFDIE::GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const {
if (IsValid()) {
- DWARFCompileUnit *cu = GetCU();
+ DWARFUnit *cu = GetCU();
SymbolFileDWARF *dwarf = cu->GetSymbolFileDWARF();
const bool check_specification_or_abstract_origin = true;
DWARFFormValue form_value;
@@ -132,29 +89,11 @@ DWARFDIE::GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const {
return DWARFDIE();
}
-uint64_t DWARFDIE::GetAttributeValueAsReference(const dw_attr_t attr,
- uint64_t fail_value) const {
- if (IsValid())
- return m_die->GetAttributeValueAsReference(GetDWARF(), GetCU(), attr,
- fail_value);
- else
- return fail_value;
-}
-
-uint64_t DWARFDIE::GetAttributeValueAsAddress(const dw_attr_t attr,
- uint64_t fail_value) const {
- if (IsValid())
- return m_die->GetAttributeValueAsAddress(GetDWARF(), GetCU(), attr,
- fail_value);
- else
- return fail_value;
-}
-
DWARFDIE
DWARFDIE::LookupDeepestBlock(lldb::addr_t file_addr) const {
if (IsValid()) {
SymbolFileDWARF *dwarf = GetDWARF();
- DWARFCompileUnit *cu = GetCU();
+ DWARFUnit *cu = GetCU();
DWARFDebugInfoEntry *function_die = nullptr;
DWARFDebugInfoEntry *block_die = nullptr;
if (m_die->LookupAddress(file_addr, dwarf, cu, &function_die, &block_die)) {
@@ -171,17 +110,6 @@ DWARFDIE::LookupDeepestBlock(lldb::addr_t file_addr) const {
return DWARFDIE();
}
-lldb::user_id_t DWARFDIE::GetID() const {
- return GetDIERef().GetUID(GetDWARF());
-}
-
-const char *DWARFDIE::GetName() const {
- if (IsValid())
- return m_die->GetName(GetDWARF(), m_cu);
- else
- return nullptr;
-}
-
const char *DWARFDIE::GetMangledName() const {
if (IsValid())
return m_die->GetMangledName(GetDWARF(), m_cu);
@@ -203,28 +131,6 @@ const char *DWARFDIE::GetQualifiedName(std::string &storage) const {
return nullptr;
}
-lldb::LanguageType DWARFDIE::GetLanguage() const {
- if (IsValid())
- return m_cu->GetLanguageType();
- else
- return lldb::eLanguageTypeUnknown;
-}
-
-lldb::ModuleSP DWARFDIE::GetModule() const {
- SymbolFileDWARF *dwarf = GetDWARF();
- if (dwarf)
- return dwarf->GetObjectFile()->GetModule();
- else
- return lldb::ModuleSP();
-}
-
-lldb_private::CompileUnit *DWARFDIE::GetLLDBCompileUnit() const {
- if (IsValid())
- return GetDWARF()->GetCompUnitForDWARFCompUnit(GetCU());
- else
- return nullptr;
-}
-
lldb_private::Type *DWARFDIE::ResolveType() const {
if (IsValid())
return GetDWARF()->ResolveType(*this, true);
@@ -262,7 +168,7 @@ void DWARFDIE::GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const {
void DWARFDIE::GetDWOContext(std::vector<CompilerContext> &context) const {
const dw_tag_t tag = Tag();
- if (tag == DW_TAG_compile_unit)
+ if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit)
return;
DWARFDIE parent = GetParent();
if (parent)
@@ -317,45 +223,17 @@ DWARFDIE::GetParentDeclContextDIE() const {
return DWARFDIE();
}
-dw_offset_t DWARFDIE::GetOffset() const {
- if (IsValid())
- return m_die->GetOffset();
- else
- return DW_INVALID_OFFSET;
-}
-
-dw_offset_t DWARFDIE::GetCompileUnitRelativeOffset() const {
- if (IsValid())
- return m_die->GetOffset() - m_cu->GetOffset();
- else
- return DW_INVALID_OFFSET;
-}
-
-SymbolFileDWARF *DWARFDIE::GetDWARF() const {
- if (m_cu)
- return m_cu->GetSymbolFileDWARF();
- else
- return nullptr;
-}
-
-lldb_private::TypeSystem *DWARFDIE::GetTypeSystem() const {
- if (m_cu)
- return m_cu->GetTypeSystem();
- else
- return nullptr;
-}
-
-DWARFASTParser *DWARFDIE::GetDWARFParser() const {
- lldb_private::TypeSystem *type_system = GetTypeSystem();
- if (type_system)
- return type_system->GetDWARFParser();
- else
- return nullptr;
+bool DWARFDIE::IsStructUnionOrClass() const {
+ const dw_tag_t tag = Tag();
+ return tag == DW_TAG_class_type || tag == DW_TAG_structure_type ||
+ tag == DW_TAG_union_type;
}
-bool DWARFDIE::IsStructOrClass() const {
- const dw_tag_t tag = Tag();
- return tag == DW_TAG_class_type || tag == DW_TAG_structure_type;
+bool DWARFDIE::IsMethod() const {
+ for (DWARFDIE d: elaborating_dies())
+ if (d.GetParent().IsStructUnionOrClass())
+ return true;
+ return false;
}
DWARFDIE
@@ -369,7 +247,7 @@ DWARFDIE::GetContainingDWOModuleDIE() const {
const dw_tag_t tag = parent.Tag();
if (tag == DW_TAG_module)
top_module_die = parent;
- else if (tag == DW_TAG_compile_unit)
+ else if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit)
break;
}
@@ -391,25 +269,6 @@ lldb::ModuleSP DWARFDIE::GetContainingDWOModule() const {
return lldb::ModuleSP();
}
-bool DWARFDIE::HasChildren() const {
- return m_die && m_die->HasChildren();
-}
-
-bool DWARFDIE::Supports_DW_AT_APPLE_objc_complete_type() const {
- return IsValid() && GetDWARF()->Supports_DW_AT_APPLE_objc_complete_type(m_cu);
-}
-
-size_t DWARFDIE::GetAttributes(DWARFAttributes &attributes,
- uint32_t depth) const {
- if (IsValid()) {
- return m_die->GetAttributes(m_cu, m_cu->GetFixedFormSizes(), attributes,
- depth);
- }
- if (depth == 0)
- attributes.Clear();
- return 0;
-}
-
bool DWARFDIE::GetDIENamesAndRanges(
const char *&name, const char *&mangled, DWARFRangeList &ranges,
int &decl_file, int &decl_line, int &decl_column, int &call_file,
@@ -423,12 +282,6 @@ bool DWARFDIE::GetDIENamesAndRanges(
return false;
}
-void DWARFDIE::Dump(lldb_private::Stream *s,
- const uint32_t recurse_depth) const {
- if (s && IsValid())
- m_die->Dump(GetDWARF(), GetCU(), *s, recurse_depth);
-}
-
CompilerDecl DWARFDIE::GetDecl() const {
DWARFASTParser *dwarf_ast = GetDWARFParser();
if (dwarf_ast)
@@ -452,11 +305,3 @@ CompilerDeclContext DWARFDIE::GetContainingDeclContext() const {
else
return CompilerDeclContext();
}
-
-bool operator==(const DWARFDIE &lhs, const DWARFDIE &rhs) {
- return lhs.GetDIE() == rhs.GetDIE() && lhs.GetCU() == rhs.GetCU();
-}
-
-bool operator!=(const DWARFDIE &lhs, const DWARFDIE &rhs) {
- return !(lhs == rhs);
-}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
index 8af3015b9d76..ecbf4912634e 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -10,115 +10,41 @@
#ifndef SymbolFileDWARF_DWARFDIE_h_
#define SymbolFileDWARF_DWARFDIE_h_
-#include "lldb/Core/dwarf.h"
-#include "lldb/lldb-types.h"
+#include "DWARFBaseDIE.h"
+#include "llvm/ADT/SmallSet.h"
-struct DIERef;
-class DWARFASTParser;
-class DWARFAttributes;
-class DWARFCompileUnit;
-class DWARFDebugInfoEntry;
-class DWARFDeclContext;
-class DWARFDIECollection;
-class SymbolFileDWARF;
-
-class DWARFDIE {
+class DWARFDIE : public DWARFBaseDIE {
public:
- DWARFDIE() : m_cu(nullptr), m_die(nullptr) {}
-
- DWARFDIE(DWARFCompileUnit *cu, DWARFDebugInfoEntry *die)
- : m_cu(cu), m_die(die) {}
-
- DWARFDIE(const DWARFCompileUnit *cu, DWARFDebugInfoEntry *die)
- : m_cu(const_cast<DWARFCompileUnit *>(cu)), m_die(die) {}
+ class ElaboratingDIEIterator;
- DWARFDIE(DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
- : m_cu(cu), m_die(const_cast<DWARFDebugInfoEntry *>(die)) {}
-
- DWARFDIE(const DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
- : m_cu(const_cast<DWARFCompileUnit *>(cu)),
- m_die(const_cast<DWARFDebugInfoEntry *>(die)) {}
+ using DWARFBaseDIE::DWARFBaseDIE;
//----------------------------------------------------------------------
// Tests
//----------------------------------------------------------------------
- explicit operator bool() const { return IsValid(); }
-
- bool IsValid() const { return m_cu && m_die; }
-
- bool IsStructOrClass() const;
+ bool IsStructUnionOrClass() const;
- bool HasChildren() const;
-
- bool Supports_DW_AT_APPLE_objc_complete_type() const;
+ bool IsMethod() const;
//----------------------------------------------------------------------
// Accessors
//----------------------------------------------------------------------
- SymbolFileDWARF *GetDWARF() const;
-
- DWARFCompileUnit *GetCU() const { return m_cu; }
-
- DWARFDebugInfoEntry *GetDIE() const { return m_die; }
-
- DIERef GetDIERef() const;
-
- lldb_private::TypeSystem *GetTypeSystem() const;
-
- DWARFASTParser *GetDWARFParser() const;
-
- void Set(DWARFCompileUnit *cu, DWARFDebugInfoEntry *die) {
- if (cu && die) {
- m_cu = cu;
- m_die = die;
- } else {
- Clear();
- }
- }
-
- void Clear() {
- m_cu = nullptr;
- m_die = nullptr;
- }
-
lldb::ModuleSP GetContainingDWOModule() const;
DWARFDIE
GetContainingDWOModuleDIE() const;
- //----------------------------------------------------------------------
- // Accessing information about a DIE
- //----------------------------------------------------------------------
- dw_tag_t Tag() const;
-
- const char *GetTagAsCString() const;
-
- dw_offset_t GetOffset() const;
-
- dw_offset_t GetCompileUnitRelativeOffset() const;
+ inline llvm::iterator_range<ElaboratingDIEIterator> elaborating_dies() const;
//----------------------------------------------------------------------
- // Get the LLDB user ID for this DIE. This is often just the DIE offset,
- // but it might have a SymbolFileDWARF::GetID() in the high 32 bits if
- // we are doing Darwin DWARF in .o file, or DWARF stand alone debug
- // info.
+ // Accessing information about a DIE
//----------------------------------------------------------------------
- lldb::user_id_t GetID() const;
-
- const char *GetName() const;
-
const char *GetMangledName() const;
const char *GetPubname() const;
const char *GetQualifiedName(std::string &storage) const;
- lldb::LanguageType GetLanguage() const;
-
- lldb::ModuleSP GetModule() const;
-
- lldb_private::CompileUnit *GetLLDBCompileUnit() const;
-
lldb_private::Type *ResolveType() const;
//----------------------------------------------------------------------
@@ -149,6 +75,7 @@ public:
//----------------------------------------------------------------------
DWARFDIE
GetDIE(dw_offset_t die_offset) const;
+ using DWARFBaseDIE::GetDIE;
DWARFDIE
LookupDeepestBlock(lldb::addr_t file_addr) const;
@@ -172,26 +99,9 @@ public:
// looking for one or two attributes on a DIE. If you are trying to
// parse all attributes, use GetAttributes (...) instead
//----------------------------------------------------------------------
- const char *GetAttributeValueAsString(const dw_attr_t attr,
- const char *fail_value) const;
-
- uint64_t GetAttributeValueAsUnsigned(const dw_attr_t attr,
- uint64_t fail_value) const;
-
- int64_t GetAttributeValueAsSigned(const dw_attr_t attr,
- int64_t fail_value) const;
-
- uint64_t GetAttributeValueAsReference(const dw_attr_t attr,
- uint64_t fail_value) const;
-
DWARFDIE
GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const;
- uint64_t GetAttributeValueAsAddress(const dw_attr_t attr,
- uint64_t fail_value) const;
-
- size_t GetAttributes(DWARFAttributes &attributes, uint32_t depth = 0) const;
-
bool GetDIENamesAndRanges(const char *&name, const char *&mangled,
DWARFRangeList &ranges, int &decl_file,
int &decl_line, int &decl_column, int &call_file,
@@ -199,23 +109,68 @@ public:
lldb_private::DWARFExpression *frame_base) const;
//----------------------------------------------------------------------
- // Pretty printing
+ // CompilerDecl related functions
//----------------------------------------------------------------------
- void Dump(lldb_private::Stream *s, const uint32_t recurse_depth) const;
-
lldb_private::CompilerDecl GetDecl() const;
lldb_private::CompilerDeclContext GetDeclContext() const;
lldb_private::CompilerDeclContext GetContainingDeclContext() const;
+};
+
+/// Iterate through all DIEs elaborating (i.e. reachable by a chain of
+/// DW_AT_specification and DW_AT_abstract_origin attributes) a given DIE. For
+/// convenience, the starting die is included in the sequence as the first
+/// item.
+class DWARFDIE::ElaboratingDIEIterator
+ : public std::iterator<std::input_iterator_tag, DWARFDIE> {
+
+ // The operating invariant is: top of m_worklist contains the "current" item
+ // and the rest of the list are items yet to be visited. An empty worklist
+ // means we've reached the end.
+ // Infinite recursion is prevented by maintaining a list of seen DIEs.
+ // Container sizes are optimized for the case of following DW_AT_specification
+ // and DW_AT_abstract_origin just once.
+ llvm::SmallVector<DWARFDIE, 2> m_worklist;
+ llvm::SmallSet<lldb::user_id_t, 3> m_seen;
+
+ void Next();
+
+public:
+ /// An iterator starting at die d.
+ explicit ElaboratingDIEIterator(DWARFDIE d) : m_worklist(1, d) {}
-protected:
- DWARFCompileUnit *m_cu;
- DWARFDebugInfoEntry *m_die;
+ /// End marker
+ ElaboratingDIEIterator() {}
+
+ const DWARFDIE &operator*() const { return m_worklist.back(); }
+ ElaboratingDIEIterator &operator++() {
+ Next();
+ return *this;
+ }
+ ElaboratingDIEIterator operator++(int) {
+ ElaboratingDIEIterator I = *this;
+ Next();
+ return I;
+ }
+
+ friend bool operator==(const ElaboratingDIEIterator &a,
+ const ElaboratingDIEIterator &b) {
+ if (a.m_worklist.empty() || b.m_worklist.empty())
+ return a.m_worklist.empty() == b.m_worklist.empty();
+ return a.m_worklist.back() == b.m_worklist.back();
+ }
+ friend bool operator!=(const ElaboratingDIEIterator &a,
+ const ElaboratingDIEIterator &b) {
+ return !(a == b);
+ }
};
-bool operator==(const DWARFDIE &lhs, const DWARFDIE &rhs);
-bool operator!=(const DWARFDIE &lhs, const DWARFDIE &rhs);
+llvm::iterator_range<DWARFDIE::ElaboratingDIEIterator>
+DWARFDIE::elaborating_dies() const {
+ return llvm::make_range(ElaboratingDIEIterator(*this),
+ ElaboratingDIEIterator());
+}
#endif // SymbolFileDWARF_DWARFDIE_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp
index 0c807d7d604b..2fcdd34d532f 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp
@@ -22,6 +22,6 @@ DWARFDataExtractor::GetDWARFInitialLength(lldb::offset_t *offset_ptr) const {
dw_offset_t
DWARFDataExtractor::GetDWARFOffset(lldb::offset_t *offset_ptr) const {
- return GetMaxU64(offset_ptr, m_is_dwarf64 ? 8 : 4);
+ return GetMaxU64(offset_ptr, GetDWARFSizeOfOffset());
}
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h b/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
index 46d09f1ca237..ce0bfb3931d5 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
@@ -29,7 +29,7 @@ public:
dw_offset_t GetDWARFOffset(lldb::offset_t *offset_ptr) const;
size_t GetDWARFSizeofInitialLength() const { return m_is_dwarf64 ? 12 : 4; }
-
+ size_t GetDWARFSizeOfOffset() const { return m_is_dwarf64 ? 8 : 4; }
bool IsDWARF64() const { return m_is_dwarf64; }
protected:
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
index 1cf0e7eeeb60..affe4b85bdab 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
@@ -80,8 +80,8 @@ DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration(
//----------------------------------------------------------------------
// DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential()
//
-// Append an abbreviation declaration with a sequential code for O(n)
-// lookups. Handy when creating an DWARFAbbreviationDeclarationSet.
+// Append an abbreviation declaration with a sequential code for O(n) lookups.
+// Handy when creating an DWARFAbbreviationDeclarationSet.
//----------------------------------------------------------------------
dw_uleb128_t DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential(
const DWARFAbbreviationDeclaration &abbrevDecl) {
@@ -115,9 +115,9 @@ void DWARFAbbreviationDeclarationSet::GetUnsupportedForms(
//----------------------------------------------------------------------
// Encode
//
-// Encode the abbreviation table onto the end of the buffer provided
-// into a byte representation as would be found in a ".debug_abbrev"
-// debug information section.
+// Encode the abbreviation table onto the end of the buffer provided into a
+// byte representation as would be found in a ".debug_abbrev" debug information
+// section.
//----------------------------------------------------------------------
// void
// DWARFAbbreviationDeclarationSet::Encode(BinaryStreamBuf& debug_abbrev_buf)
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
index cecb69c8fb46..00265361f865 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
@@ -46,19 +46,17 @@ void DWARFDebugArangeSet::Compact() {
if (m_arange_descriptors.empty())
return;
- // Iterate through all arange descriptors and combine any ranges that
- // overlap or have matching boundaries. The m_arange_descriptors are assumed
- // to be in ascending order after being built by adding descriptors
- // using the AddDescriptor method.
+ // Iterate through all arange descriptors and combine any ranges that overlap
+ // or have matching boundaries. The m_arange_descriptors are assumed to be in
+ // ascending order after being built by adding descriptors using the
+ // AddDescriptor method.
uint32_t i = 0;
while (i + 1 < m_arange_descriptors.size()) {
if (m_arange_descriptors[i].end_address() >=
m_arange_descriptors[i + 1].address) {
// The current range ends at or exceeds the start of the next address
- // range.
- // Compute the max end address between the two and use that to make the
- // new
- // length.
+ // range. Compute the max end address between the two and use that to
+ // make the new length.
const dw_addr_t max_end_addr =
std::max(m_arange_descriptors[i].end_address(),
m_arange_descriptors[i + 1].end_address());
@@ -82,8 +80,8 @@ static bool DescriptorLessThan(const DWARFDebugArangeSet::Descriptor &range1,
}
//----------------------------------------------------------------------
-// Add a range descriptor and keep things sorted so we can easily
-// compact the ranges before being saved or used.
+// Add a range descriptor and keep things sorted so we can easily compact the
+// ranges before being saved or used.
//----------------------------------------------------------------------
void DWARFDebugArangeSet::AddDescriptor(
const DWARFDebugArangeSet::Descriptor &range) {
@@ -103,15 +101,14 @@ void DWARFDebugArangeSet::AddDescriptor(
// Non-contiguous entries, add this one before the found entry
m_arange_descriptors.insert(pos, range);
} else if (range_end_addr == pos->address) {
- // The top end of 'range' is the lower end of the entry
- // pointed to by 'pos'. We can combine range with the
- // entry we found by setting the starting address and
- // increasing the length since they don't overlap.
+ // The top end of 'range' is the lower end of the entry pointed to by
+ // 'pos'. We can combine range with the entry we found by setting the
+ // starting address and increasing the length since they don't overlap.
pos->address = range.address;
pos->length += range.length;
} else {
- // We can combine these two and make sure the largest end
- // address is used to make end address.
+ // We can combine these two and make sure the largest end address is
+ // used to make end address.
pos->address = range.address;
pos->length = std::max(found_end_addr, range_end_addr) - pos->address;
}
@@ -142,18 +139,18 @@ bool DWARFDebugArangeSet::Extract(const DWARFDataExtractor &data,
// 7.20 Address Range Table
//
- // Each set of entries in the table of address ranges contained in
- // the .debug_aranges section begins with a header consisting of: a
- // 4-byte length containing the length of the set of entries for this
- // compilation unit, not including the length field itself; a 2-byte
- // version identifier containing the value 2 for DWARF Version 2; a
- // 4-byte offset into the.debug_infosection; a 1-byte unsigned integer
- // containing the size in bytes of an address (or the offset portion of
- // an address for segmented addressing) on the target system; and a
- // 1-byte unsigned integer containing the size in bytes of a segment
- // descriptor on the target system. This header is followed by a series
- // of tuples. Each tuple consists of an address and a length, each in
- // the size appropriate for an address on the target architecture.
+ // Each set of entries in the table of address ranges contained in the
+ // .debug_aranges section begins with a header consisting of: a 4-byte
+ // length containing the length of the set of entries for this compilation
+ // unit, not including the length field itself; a 2-byte version identifier
+ // containing the value 2 for DWARF Version 2; a 4-byte offset into
+ // the.debug_infosection; a 1-byte unsigned integer containing the size in
+ // bytes of an address (or the offset portion of an address for segmented
+ // addressing) on the target system; and a 1-byte unsigned integer
+ // containing the size in bytes of a segment descriptor on the target
+ // system. This header is followed by a series of tuples. Each tuple
+ // consists of an address and a length, each in the size appropriate for an
+ // address on the target architecture.
m_header.length = data.GetDWARFInitialLength(offset_ptr);
m_header.version = data.GetU16(offset_ptr);
m_header.cu_offset = data.GetDWARFOffset(offset_ptr);
@@ -195,8 +192,8 @@ bool DWARFDebugArangeSet::Extract(const DWARFDataExtractor &data,
arangeDescriptor.length =
data.GetMaxU64(offset_ptr, m_header.addr_size);
- // Each set of tuples is terminated by a 0 for the address and 0
- // for the length.
+ // Each set of tuples is terminated by a 0 for the address and 0 for
+ // the length.
if (arangeDescriptor.address || arangeDescriptor.length)
m_arange_descriptors.push_back(arangeDescriptor);
else
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
index 13c2d8726821..02f528d571b0 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
@@ -18,7 +18,7 @@
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/Timer.h"
-#include "DWARFCompileUnit.h"
+#include "DWARFUnit.h"
#include "DWARFDebugInfo.h"
#include "LogChannelDWARF.h"
#include "SymbolFileDWARF.h"
@@ -82,7 +82,7 @@ bool DWARFDebugAranges::Generate(SymbolFileDWARF *dwarf2Data) {
uint32_t cu_idx = 0;
const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits();
for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
- DWARFCompileUnit *cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+ DWARFUnit *cu = debug_info->GetCompileUnitAtIndex(cu_idx);
if (cu)
cu->BuildAddressRangeTable(dwarf2Data, this);
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
index 9c0f1d3c8905..dadc30dc918a 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -72,7 +72,7 @@ DWARFDebugAranges &DWARFDebugInfo::GetCompileUnitAranges() {
bool printed = false;
const size_t num_compile_units = GetNumCompileUnits();
for (size_t idx = 0; idx < num_compile_units; ++idx) {
- DWARFCompileUnit *cu = GetCompileUnitAtIndex(idx);
+ DWARFUnit *cu = GetCompileUnitAtIndex(idx);
dw_offset_t offset = cu->GetOffset();
if (cus_with_data.find(offset) == cus_with_data.end()) {
@@ -97,8 +97,10 @@ void DWARFDebugInfo::ParseCompileUnitHeadersIfNeeded() {
if (m_compile_units.empty()) {
if (m_dwarf2Data != NULL) {
lldb::offset_t offset = 0;
- DWARFCompileUnitSP cu_sp;
- while ((cu_sp = DWARFCompileUnit::Extract(m_dwarf2Data, &offset))) {
+ DWARFUnitSP cu_sp;
+ const auto &debug_info_data = m_dwarf2Data->get_debug_info_data();
+ while ((cu_sp = DWARFCompileUnit::Extract(m_dwarf2Data, debug_info_data,
+ &offset))) {
m_compile_units.push_back(cu_sp);
offset = cu_sp->GetNextCompileUnitOffset();
@@ -112,16 +114,16 @@ size_t DWARFDebugInfo::GetNumCompileUnits() {
return m_compile_units.size();
}
-DWARFCompileUnit *DWARFDebugInfo::GetCompileUnitAtIndex(uint32_t idx) {
- DWARFCompileUnit *cu = NULL;
+DWARFUnit *DWARFDebugInfo::GetCompileUnitAtIndex(uint32_t idx) {
+ DWARFUnit *cu = NULL;
if (idx < GetNumCompileUnits())
cu = m_compile_units[idx].get();
return cu;
}
-bool DWARFDebugInfo::ContainsCompileUnit(const DWARFCompileUnit *cu) const {
- // Not a verify efficient function, but it is handy for use in assertions
- // to make sure that a compile unit comes from a debug information file.
+bool DWARFDebugInfo::ContainsCompileUnit(const DWARFUnit *cu) const {
+ // Not a verify efficient function, but it is handy for use in assertions to
+ // make sure that a compile unit comes from a debug information file.
CompileUnitColl::const_iterator end_pos = m_compile_units.end();
CompileUnitColl::const_iterator pos;
@@ -133,13 +135,13 @@ bool DWARFDebugInfo::ContainsCompileUnit(const DWARFCompileUnit *cu) const {
}
bool DWARFDebugInfo::OffsetLessThanCompileUnitOffset(
- dw_offset_t offset, const DWARFCompileUnitSP &cu_sp) {
+ dw_offset_t offset, const DWARFUnitSP &cu_sp) {
return offset < cu_sp->GetOffset();
}
-DWARFCompileUnit *DWARFDebugInfo::GetCompileUnit(dw_offset_t cu_offset,
+DWARFUnit *DWARFDebugInfo::GetCompileUnit(dw_offset_t cu_offset,
uint32_t *idx_ptr) {
- DWARFCompileUnitSP cu_sp;
+ DWARFUnitSP cu_sp;
uint32_t cu_idx = DW_INVALID_INDEX;
if (cu_offset != DW_INVALID_OFFSET) {
ParseCompileUnitHeadersIfNeeded();
@@ -170,18 +172,18 @@ DWARFCompileUnit *DWARFDebugInfo::GetCompileUnit(dw_offset_t cu_offset,
return cu_sp.get();
}
-DWARFCompileUnit *DWARFDebugInfo::GetCompileUnit(const DIERef &die_ref) {
+DWARFUnit *DWARFDebugInfo::GetCompileUnit(const DIERef &die_ref) {
if (die_ref.cu_offset == DW_INVALID_OFFSET)
return GetCompileUnitContainingDIEOffset(die_ref.die_offset);
else
return GetCompileUnit(die_ref.cu_offset);
}
-DWARFCompileUnit *
+DWARFUnit *
DWARFDebugInfo::GetCompileUnitContainingDIEOffset(dw_offset_t die_offset) {
ParseCompileUnitHeadersIfNeeded();
- DWARFCompileUnitSP cu_sp;
+ DWARFUnitSP cu_sp;
// Watch out for single compile unit executable as they are pretty common
const size_t num_cus = m_compile_units.size();
@@ -205,7 +207,7 @@ DWARFDebugInfo::GetCompileUnitContainingDIEOffset(dw_offset_t die_offset) {
DWARFDIE
DWARFDebugInfo::GetDIEForDIEOffset(dw_offset_t die_offset) {
- DWARFCompileUnit *cu = GetCompileUnitContainingDIEOffset(die_offset);
+ DWARFUnit *cu = GetCompileUnitContainingDIEOffset(die_offset);
if (cu)
return cu->GetDIE(die_offset);
return DWARFDIE();
@@ -218,275 +220,9 @@ DWARFDebugInfo::GetDIEForDIEOffset(dw_offset_t die_offset) {
//----------------------------------------------------------------------
DWARFDIE
DWARFDebugInfo::GetDIE(const DIERef &die_ref) {
- DWARFCompileUnit *cu = GetCompileUnit(die_ref);
+ DWARFUnit *cu = GetCompileUnit(die_ref);
if (cu)
return cu->GetDIE(die_ref.die_offset);
return DWARFDIE(); // Not found
}
-//----------------------------------------------------------------------
-// Parse
-//
-// Parses the .debug_info section and uses the .debug_abbrev section
-// and various other sections in the SymbolFileDWARF class and calls the
-// supplied callback function each time a compile unit header, or debug
-// information entry is successfully parsed. This function can be used
-// for different tasks such as parsing the file contents into a
-// structured data, dumping, verifying and much more.
-//----------------------------------------------------------------------
-void DWARFDebugInfo::Parse(SymbolFileDWARF *dwarf2Data, Callback callback,
- void *userData) {
- if (dwarf2Data) {
- lldb::offset_t offset = 0;
- uint32_t depth = 0;
- DWARFDebugInfoEntry die;
-
- DWARFCompileUnitSP cu;
- while ((cu = DWARFCompileUnit::Extract(dwarf2Data, &offset))) {
- const dw_offset_t next_cu_offset = cu->GetNextCompileUnitOffset();
-
- depth = 0;
- // Call the callback function with no DIE pointer for the compile unit
- // and get the offset that we are to continue to parse from
- offset = callback(dwarf2Data, cu.get(), NULL, offset, depth, userData);
-
- // Make sure we are within our compile unit
- if (offset < next_cu_offset) {
- // We are in our compile unit, parse starting at the offset
- // we were told to parse
- bool done = false;
- while (!done && die.Extract(dwarf2Data, cu.get(), &offset)) {
- // Call the callback function with DIE pointer that falls within the
- // compile unit
- offset =
- callback(dwarf2Data, cu.get(), &die, offset, depth, userData);
-
- if (die.IsNULL()) {
- if (depth)
- --depth;
- else
- done = true; // We are done with this compile unit!
- } else if (die.HasChildren())
- ++depth;
- }
- }
-
- // Make sure the offset returned is valid, and if not stop parsing.
- // Returning DW_INVALID_OFFSET from this callback is a good way to end
- // all parsing
- if (!dwarf2Data->get_debug_info_data().ValidOffset(offset))
- break;
-
- // Make sure we start on a proper
- offset = next_cu_offset;
- }
- }
-}
-
-typedef struct DumpInfo {
- DumpInfo(Stream *init_strm, uint32_t off, uint32_t depth)
- : strm(init_strm), die_offset(off), recurse_depth(depth),
- found_depth(UINT32_MAX), found_die(false), ancestors() {}
- Stream *strm;
- const uint32_t die_offset;
- const uint32_t recurse_depth;
- uint32_t found_depth;
- bool found_die;
- std::vector<DWARFDebugInfoEntry> ancestors;
-
- DISALLOW_COPY_AND_ASSIGN(DumpInfo);
-} DumpInfo;
-
-//----------------------------------------------------------------------
-// DumpCallback
-//
-// A callback function for the static DWARFDebugInfo::Parse() function
-// that gets called each time a compile unit header or debug information
-// entry is successfully parsed.
-//
-// This function dump DWARF information and obey recurse depth and
-// whether a single DIE is to be dumped (or all of the data).
-//----------------------------------------------------------------------
-static dw_offset_t DumpCallback(SymbolFileDWARF *dwarf2Data,
- DWARFCompileUnit *cu, DWARFDebugInfoEntry *die,
- const dw_offset_t next_offset,
- const uint32_t curr_depth, void *userData) {
- DumpInfo *dumpInfo = (DumpInfo *)userData;
- Stream *s = dumpInfo->strm;
- bool show_parents =
- s->GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowAncestors);
-
- if (die) {
- // Are we dumping everything?
- if (dumpInfo->die_offset == DW_INVALID_OFFSET) {
- // Yes we are dumping everything. Obey our recurse level though
- if (curr_depth < dumpInfo->recurse_depth)
- die->Dump(dwarf2Data, cu, *s, 0);
- } else {
- // We are dumping a specific DIE entry by offset
- if (dumpInfo->die_offset == die->GetOffset()) {
- // We found the DIE we were looking for, dump it!
- if (show_parents) {
- s->SetIndentLevel(0);
- const uint32_t num_ancestors = dumpInfo->ancestors.size();
- if (num_ancestors > 0) {
- for (uint32_t i = 0; i < num_ancestors - 1; ++i) {
- dumpInfo->ancestors[i].Dump(dwarf2Data, cu, *s, 0);
- s->IndentMore();
- }
- }
- }
-
- dumpInfo->found_depth = curr_depth;
-
- die->Dump(dwarf2Data, cu, *s, 0);
-
- // Note that we found the DIE we were looking for
- dumpInfo->found_die = true;
-
- // Since we are dumping a single DIE, if there are no children we are
- // done!
- if (!die->HasChildren() || dumpInfo->recurse_depth == 0)
- return DW_INVALID_OFFSET; // Return an invalid address to end parsing
- } else if (dumpInfo->found_die) {
- // Are we done with all the children?
- if (curr_depth <= dumpInfo->found_depth)
- return DW_INVALID_OFFSET;
-
- // We have already found our DIE and are printing it's children. Obey
- // our recurse depth and return an invalid offset if we get done
- // dumping all of the children
- if (dumpInfo->recurse_depth == UINT32_MAX ||
- curr_depth <= dumpInfo->found_depth + dumpInfo->recurse_depth)
- die->Dump(dwarf2Data, cu, *s, 0);
- } else if (dumpInfo->die_offset > die->GetOffset()) {
- if (show_parents)
- dumpInfo->ancestors.back() = *die;
- }
- }
-
- // Keep up with our indent level
- if (die->IsNULL()) {
- if (show_parents)
- dumpInfo->ancestors.pop_back();
-
- if (curr_depth <= 1)
- return cu->GetNextCompileUnitOffset();
- else
- s->IndentLess();
- } else if (die->HasChildren()) {
- if (show_parents) {
- DWARFDebugInfoEntry null_die;
- dumpInfo->ancestors.push_back(null_die);
- }
- s->IndentMore();
- }
- } else {
- if (cu == NULL)
- s->PutCString("NULL - cu");
- // We have a compile unit, reset our indent level to zero just in case
- s->SetIndentLevel(0);
-
- // See if we are dumping everything?
- if (dumpInfo->die_offset == DW_INVALID_OFFSET) {
- // We are dumping everything
- if (cu) {
- cu->Dump(s);
- return cu->GetFirstDIEOffset(); // Return true to parse all DIEs in this
- // Compile Unit
- } else {
- return DW_INVALID_OFFSET;
- }
- } else {
- if (show_parents) {
- dumpInfo->ancestors.clear();
- dumpInfo->ancestors.resize(1);
- }
-
- // We are dumping only a single DIE possibly with it's children and
- // we must find it's compile unit before we can dump it properly
- if (cu && dumpInfo->die_offset < cu->GetFirstDIEOffset()) {
- // Not found, maybe the DIE offset provided wasn't correct?
- // *ostrm_ptr << "DIE at offset " << HEX32 << dumpInfo->die_offset << "
- // was not found." << endl;
- return DW_INVALID_OFFSET;
- } else {
- // See if the DIE is in this compile unit?
- if (cu && dumpInfo->die_offset < cu->GetNextCompileUnitOffset()) {
- return next_offset;
- // // We found our compile unit that contains our DIE, just skip to
- // dumping the requested DIE...
- // return dumpInfo->die_offset;
- } else {
- // Skip to the next compile unit as the DIE isn't in the current one!
- if (cu) {
- return cu->GetNextCompileUnitOffset();
- } else {
- return DW_INVALID_OFFSET;
- }
- }
- }
- }
- }
-
- // Just return the current offset to parse the next CU or DIE entry
- return next_offset;
-}
-
-//----------------------------------------------------------------------
-// Dump
-//
-// Dump the information in the .debug_info section to the specified
-// ostream. If die_offset is valid, a single DIE will be dumped. If the
-// die_offset is invalid, all the DWARF information will be dumped. Both
-// cases will obey a "recurse_depth" or how deep to traverse into the
-// children of each DIE entry. A recurse_depth of zero will dump all
-// compile unit headers. A recurse_depth of 1 will dump all compile unit
-// headers and the DW_TAG_compile unit tags. A depth of 2 will also
-// dump all types and functions.
-//----------------------------------------------------------------------
-void DWARFDebugInfo::Dump(Stream *s, SymbolFileDWARF *dwarf2Data,
- const uint32_t die_offset,
- const uint32_t recurse_depth) {
- DumpInfo dumpInfo(s, die_offset, recurse_depth);
- s->PutCString(".debug_info contents");
- if (dwarf2Data->get_debug_info_data().GetByteSize() > 0) {
- if (die_offset == DW_INVALID_OFFSET)
- s->PutCString(":\n");
- else {
- s->Printf(" for DIE entry at .debug_info[0x%8.8x]", die_offset);
- if (recurse_depth != UINT32_MAX)
- s->Printf(" recursing %u levels deep.", recurse_depth);
- s->EOL();
- }
- } else {
- s->PutCString(": < EMPTY >\n");
- return;
- }
- DWARFDebugInfo::Parse(dwarf2Data, DumpCallback, &dumpInfo);
-}
-
-//----------------------------------------------------------------------
-// Dump
-//
-// Dump the contents of this DWARFDebugInfo object as has been parsed
-// and/or modified after it has been parsed.
-//----------------------------------------------------------------------
-void DWARFDebugInfo::Dump(Stream *s, const uint32_t die_offset,
- const uint32_t recurse_depth) {
- DumpInfo dumpInfo(s, die_offset, recurse_depth);
-
- s->PutCString("Dumping .debug_info section from internal representation\n");
-
- CompileUnitColl::const_iterator pos;
- uint32_t curr_depth = 0;
- ParseCompileUnitHeadersIfNeeded();
- for (pos = m_compile_units.begin(); pos != m_compile_units.end(); ++pos) {
- DWARFCompileUnit *cu = pos->get();
- DumpCallback(m_dwarf2Data, cu, NULL, 0, curr_depth, &dumpInfo);
-
- const DWARFDIE die = cu->DIE();
- if (die)
- die.Dump(s, recurse_depth);
- }
-}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
index 14c7d767d05b..fc6085f99a21 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
@@ -13,6 +13,7 @@
#include <map>
#include <vector>
+#include "DWARFUnit.h"
#include "DWARFDIE.h"
#include "SymbolFileDWARF.h"
#include "lldb/Core/STLUtils.h"
@@ -26,7 +27,7 @@ typedef CStringToDIEMap::const_iterator CStringToDIEMapConstIter;
class DWARFDebugInfo {
public:
typedef dw_offset_t (*Callback)(SymbolFileDWARF *dwarf2Data,
- DWARFCompileUnit *cu,
+ DWARFUnit *cu,
DWARFDebugInfoEntry *die,
const dw_offset_t next_offset,
const uint32_t depth, void *userData);
@@ -35,22 +36,14 @@ public:
void SetDwarfData(SymbolFileDWARF *dwarf2Data);
size_t GetNumCompileUnits();
- bool ContainsCompileUnit(const DWARFCompileUnit *cu) const;
- DWARFCompileUnit *GetCompileUnitAtIndex(uint32_t idx);
- DWARFCompileUnit *GetCompileUnit(dw_offset_t cu_offset,
- uint32_t *idx_ptr = NULL);
- DWARFCompileUnit *GetCompileUnitContainingDIEOffset(dw_offset_t die_offset);
- DWARFCompileUnit *GetCompileUnit(const DIERef &die_ref);
+ bool ContainsCompileUnit(const DWARFUnit *cu) const;
+ DWARFUnit *GetCompileUnitAtIndex(uint32_t idx);
+ DWARFUnit *GetCompileUnit(dw_offset_t cu_offset, uint32_t *idx_ptr = NULL);
+ DWARFUnit *GetCompileUnitContainingDIEOffset(dw_offset_t die_offset);
+ DWARFUnit *GetCompileUnit(const DIERef &die_ref);
DWARFDIE GetDIEForDIEOffset(dw_offset_t die_offset);
DWARFDIE GetDIE(const DIERef &die_ref);
- void Dump(lldb_private::Stream *s, const uint32_t die_offset,
- const uint32_t recurse_depth);
- static void Parse(SymbolFileDWARF *parser, Callback callback, void *userData);
- static void Verify(lldb_private::Stream *s, SymbolFileDWARF *dwarf2Data);
- static void Dump(lldb_private::Stream *s, SymbolFileDWARF *dwarf2Data,
- const uint32_t die_offset, const uint32_t recurse_depth);
-
enum {
eDumpFlag_Verbose = (1 << 0), // Verbose dumping
eDumpFlag_ShowForm = (1 << 1), // Show the DW_form type
@@ -62,9 +55,9 @@ public:
protected:
static bool OffsetLessThanCompileUnitOffset(dw_offset_t offset,
- const DWARFCompileUnitSP &cu_sp);
+ const DWARFUnitSP &cu_sp);
- typedef std::vector<DWARFCompileUnitSP> CompileUnitColl;
+ typedef std::vector<DWARFUnitSP> CompileUnitColl;
//----------------------------------------------------------------------
// Member variables
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index f595bd83d846..d32aef6e162c 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -18,7 +18,7 @@
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/Stream.h"
-#include "DWARFCompileUnit.h"
+#include "DWARFUnit.h"
#include "DWARFDIECollection.h"
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugAranges.h"
@@ -34,7 +34,7 @@ using namespace std;
extern int g_verbose;
bool DWARFDebugInfoEntry::FastExtract(
- const DWARFDataExtractor &debug_info_data, const DWARFCompileUnit *cu,
+ const DWARFDataExtractor &debug_info_data, const DWARFUnit *cu,
const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
lldb::offset_t *offset_ptr) {
m_offset = *offset_ptr;
@@ -189,14 +189,14 @@ bool DWARFDebugInfoEntry::FastExtract(
//----------------------------------------------------------------------
// Extract
//
-// Extract a debug info entry for a given compile unit from the
-// .debug_info and .debug_abbrev data within the SymbolFileDWARF class
-// starting at the given offset
+// Extract a debug info entry for a given compile unit from the .debug_info and
+// .debug_abbrev data within the SymbolFileDWARF class starting at the given
+// offset
//----------------------------------------------------------------------
bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data,
- const DWARFCompileUnit *cu,
+ const DWARFUnit *cu,
lldb::offset_t *offset_ptr) {
- const DWARFDataExtractor &debug_info_data = dwarf2Data->get_debug_info_data();
+ const DWARFDataExtractor &debug_info_data = cu->GetData();
// const DWARFDataExtractor& debug_str_data =
// dwarf2Data->get_debug_str_data();
const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset();
@@ -218,9 +218,10 @@ bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data,
m_tag = abbrevDecl->Tag();
m_has_children = abbrevDecl->HasChildren();
- bool isCompileUnitTag = m_tag == DW_TAG_compile_unit;
+ bool isCompileUnitTag = (m_tag == DW_TAG_compile_unit ||
+ m_tag == DW_TAG_partial_unit);
if (cu && isCompileUnitTag)
- const_cast<DWARFCompileUnit *>(cu)->SetBaseAddress(0);
+ const_cast<DWARFUnit *>(cu)->SetBaseAddress(0);
// Skip all data in the .debug_info for the attributes
const uint32_t numAttributes = abbrevDecl->NumAttributes();
@@ -235,7 +236,7 @@ bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data,
DWARFFormValue form_value(cu, form);
if (form_value.ExtractValue(debug_info_data, &offset)) {
if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc)
- const_cast<DWARFCompileUnit *>(cu)->SetBaseAddress(
+ const_cast<DWARFUnit *>(cu)->SetBaseAddress(
form_value.Address());
}
} else {
@@ -245,8 +246,7 @@ bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data,
uint32_t form_size = 0;
switch (form) {
// Blocks if inlined data that have a length field and the data
- // bytes
- // inlined in the .debug_info
+ // bytes inlined in the .debug_info
case DW_FORM_exprloc:
case DW_FORM_block:
form_size = debug_info_data.GetULEB128(&offset);
@@ -356,11 +356,11 @@ bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data,
//----------------------------------------------------------------------
// DumpAncestry
//
-// Dumps all of a debug information entries parents up until oldest and
-// all of it's attributes to the specified stream.
+// Dumps all of a debug information entries parents up until oldest and all of
+// it's attributes to the specified stream.
//----------------------------------------------------------------------
void DWARFDebugInfoEntry::DumpAncestry(SymbolFileDWARF *dwarf2Data,
- const DWARFCompileUnit *cu,
+ const DWARFUnit *cu,
const DWARFDebugInfoEntry *oldest,
Stream &s,
uint32_t recurse_depth) const {
@@ -374,11 +374,10 @@ void DWARFDebugInfoEntry::DumpAncestry(SymbolFileDWARF *dwarf2Data,
// GetDIENamesAndRanges
//
// Gets the valid address ranges for a given DIE by looking for a
-// DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges
-// attributes.
+// DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges attributes.
//----------------------------------------------------------------------
bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
- SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, const char *&name,
+ SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, const char *&name,
const char *&mangled, DWARFRangeList &ranges, int &decl_file,
int &decl_line, int &decl_column, int &call_file, int &call_line,
int &call_column, DWARFExpression *frame_base) const {
@@ -404,8 +403,7 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
lldb::ModuleSP module = dwarf2Data->GetObjectFile()->GetModule();
if (abbrevDecl) {
- const DWARFDataExtractor &debug_info_data =
- dwarf2Data->get_debug_info_data();
+ const DWARFDataExtractor &debug_info_data = cu->GetData();
if (!debug_info_data.ValidOffset(offset))
return false;
@@ -451,9 +449,9 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
const DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges();
if (debug_ranges) {
debug_ranges->FindRanges(cu->GetRangesBase(), form_value.Unsigned(), ranges);
- // All DW_AT_ranges are relative to the base address of the
- // compile unit. We add the compile unit base address to make
- // sure all the addresses are properly fixed up.
+ // All DW_AT_ranges are relative to the base address of the compile
+ // unit. We add the compile unit base address to make sure all the
+ // addresses are properly fixed up.
ranges.Slide(cu->GetBaseAddress());
} else {
cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError(
@@ -582,13 +580,13 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
//----------------------------------------------------------------------
// Dump
//
-// Dumps a debug information entry and all of it's attributes to the
-// specified stream.
+// Dumps a debug information entry and all of it's attributes to the specified
+// stream.
//----------------------------------------------------------------------
void DWARFDebugInfoEntry::Dump(SymbolFileDWARF *dwarf2Data,
- const DWARFCompileUnit *cu, Stream &s,
+ const DWARFUnit *cu, Stream &s,
uint32_t recurse_depth) const {
- const DWARFDataExtractor &debug_info_data = dwarf2Data->get_debug_info_data();
+ const DWARFDataExtractor &debug_info_data = cu->GetData();
lldb::offset_t offset = m_offset;
if (debug_info_data.ValidOffset(offset)) {
@@ -639,8 +637,8 @@ void DWARFDebugInfoEntry::Dump(SymbolFileDWARF *dwarf2Data,
}
void DWARFDebugInfoEntry::DumpLocation(SymbolFileDWARF *dwarf2Data,
- DWARFCompileUnit *cu, Stream &s) const {
- const DWARFDIE cu_die = cu->GetCompileUnitDIEOnly();
+ DWARFUnit *cu, Stream &s) const {
+ const DWARFBaseDIE cu_die = cu->GetUnitDIEOnly();
const char *cu_name = NULL;
if (cu_die)
cu_name = cu_die.GetName();
@@ -658,12 +656,12 @@ void DWARFDebugInfoEntry::DumpLocation(SymbolFileDWARF *dwarf2Data,
//----------------------------------------------------------------------
// DumpAttribute
//
-// Dumps a debug information entry attribute along with it's form. Any
-// special display of attributes is done (disassemble location lists,
-// show enumeration values for attributes, etc).
+// Dumps a debug information entry attribute along with it's form. Any special
+// display of attributes is done (disassemble location lists, show enumeration
+// values for attributes, etc).
//----------------------------------------------------------------------
void DWARFDebugInfoEntry::DumpAttribute(
- SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
const DWARFDataExtractor &debug_info_data, lldb::offset_t *offset_ptr,
Stream &s, dw_attr_t attr, dw_form_t form) {
bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm);
@@ -714,11 +712,10 @@ void DWARFDebugInfoEntry::DumpAttribute(
(*offset_ptr) - form_value.Unsigned(),
form_value.Unsigned());
DWARFExpression::PrintDWARFExpression(
- s, locationData, DWARFCompileUnit::GetAddressByteSize(cu), 4, false);
+ s, locationData, DWARFUnit::GetAddressByteSize(cu), 4, false);
} else {
- // We have a location list offset as the value that is
- // the offset into the .debug_loc section that describes
- // the value over it's lifetime
+ // We have a location list offset as the value that is the offset into
+ // the .debug_loc section that describes the value over it's lifetime
uint64_t debug_loc_offset = form_value.Unsigned();
if (dwarf2Data) {
DWARFExpression::PrintDWARFLocationList(
@@ -759,18 +756,18 @@ void DWARFDebugInfoEntry::DumpAttribute(
//----------------------------------------------------------------------
// Get all attribute values for a given DIE, including following any
-// specification or abstract origin attributes and including those in
-// the results. Any duplicate attributes will have the first instance
-// take precedence (this can happen for declaration attributes).
+// specification or abstract origin attributes and including those in the
+// results. Any duplicate attributes will have the first instance take
+// precedence (this can happen for declaration attributes).
//----------------------------------------------------------------------
size_t DWARFDebugInfoEntry::GetAttributes(
- const DWARFCompileUnit *cu, DWARFFormValue::FixedFormSizes fixed_form_sizes,
+ const DWARFUnit *cu, DWARFFormValue::FixedFormSizes fixed_form_sizes,
DWARFAttributes &attributes, uint32_t curr_depth) const {
SymbolFileDWARF *dwarf2Data = nullptr;
const DWARFAbbreviationDeclaration *abbrevDecl = nullptr;
lldb::offset_t offset = 0;
if (cu) {
- if (m_tag != DW_TAG_compile_unit) {
+ if (m_tag != DW_TAG_compile_unit && m_tag != DW_TAG_partial_unit) {
SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
if (dwo_symbol_file)
return GetAttributes(dwo_symbol_file->GetCompileUnit(),
@@ -782,8 +779,7 @@ size_t DWARFDebugInfoEntry::GetAttributes(
}
if (abbrevDecl) {
- const DWARFDataExtractor &debug_info_data =
- dwarf2Data->get_debug_info_data();
+ const DWARFDataExtractor &debug_info_data = cu->GetData();
if (fixed_form_sizes.Empty())
fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(
@@ -803,9 +799,9 @@ size_t DWARFDebugInfoEntry::GetAttributes(
case DW_AT_sibling:
case DW_AT_declaration:
if (curr_depth > 0) {
- // This attribute doesn't make sense when combined with
- // the DIE that references this DIE. We know a DIE is
- // referencing this DIE because curr_depth is not zero
+ // This attribute doesn't make sense when combined with the DIE that
+ // references this DIE. We know a DIE is referencing this DIE because
+ // curr_depth is not zero
break;
}
LLVM_FALLTHROUGH;
@@ -819,7 +815,7 @@ size_t DWARFDebugInfoEntry::GetAttributes(
if (form_value.ExtractValue(debug_info_data, &offset)) {
dw_offset_t die_offset = form_value.Reference();
DWARFDIE spec_die =
- const_cast<DWARFCompileUnit *>(cu)->GetDIE(die_offset);
+ const_cast<DWARFUnit *>(cu)->GetDIE(die_offset);
if (spec_die)
spec_die.GetAttributes(attributes, curr_depth + 1);
}
@@ -841,17 +837,18 @@ size_t DWARFDebugInfoEntry::GetAttributes(
// GetAttributeValue
//
// Get the value of an attribute and return the .debug_info offset of the
-// attribute if it was properly extracted into form_value, or zero
-// if we fail since an offset of zero is invalid for an attribute (it
-// would be a compile unit header).
+// attribute if it was properly extracted into form_value, or zero if we fail
+// since an offset of zero is invalid for an attribute (it would be a compile
+// unit header).
//----------------------------------------------------------------------
dw_offset_t DWARFDebugInfoEntry::GetAttributeValue(
- SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
const dw_attr_t attr, DWARFFormValue &form_value,
dw_offset_t *end_attr_offset_ptr,
bool check_specification_or_abstract_origin) const {
SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
- if (dwo_symbol_file && m_tag != DW_TAG_compile_unit)
+ if (dwo_symbol_file && m_tag != DW_TAG_compile_unit &&
+ m_tag != DW_TAG_partial_unit)
return GetAttributeValue(dwo_symbol_file, dwo_symbol_file->GetCompileUnit(),
attr, form_value, end_attr_offset_ptr,
check_specification_or_abstract_origin);
@@ -864,8 +861,7 @@ dw_offset_t DWARFDebugInfoEntry::GetAttributeValue(
uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr);
if (attr_idx != DW_INVALID_INDEX) {
- const DWARFDataExtractor &debug_info_data =
- dwarf2Data->get_debug_info_data();
+ const DWARFDataExtractor &debug_info_data = cu->GetData();
uint32_t idx = 0;
while (idx < attr_idx)
@@ -886,7 +882,7 @@ dw_offset_t DWARFDebugInfoEntry::GetAttributeValue(
if (check_specification_or_abstract_origin) {
if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value)) {
DWARFDIE die =
- const_cast<DWARFCompileUnit *>(cu)->GetDIE(form_value.Reference());
+ const_cast<DWARFUnit *>(cu)->GetDIE(form_value.Reference());
if (die) {
dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
die.GetDWARF(), die.GetCU(), attr, form_value, end_attr_offset_ptr,
@@ -898,7 +894,7 @@ dw_offset_t DWARFDebugInfoEntry::GetAttributeValue(
if (GetAttributeValue(dwarf2Data, cu, DW_AT_abstract_origin, form_value)) {
DWARFDIE die =
- const_cast<DWARFCompileUnit *>(cu)->GetDIE(form_value.Reference());
+ const_cast<DWARFUnit *>(cu)->GetDIE(form_value.Reference());
if (die) {
dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
die.GetDWARF(), die.GetCU(), attr, form_value, end_attr_offset_ptr,
@@ -912,11 +908,11 @@ dw_offset_t DWARFDebugInfoEntry::GetAttributeValue(
if (!dwo_symbol_file)
return 0;
- DWARFCompileUnit *dwo_cu = dwo_symbol_file->GetCompileUnit();
+ DWARFUnit *dwo_cu = dwo_symbol_file->GetCompileUnit();
if (!dwo_cu)
return 0;
- DWARFDIE dwo_cu_die = dwo_cu->GetCompileUnitDIEOnly();
+ DWARFBaseDIE dwo_cu_die = dwo_cu->GetUnitDIEOnly();
if (!dwo_cu_die.IsValid())
return 0;
@@ -928,13 +924,13 @@ dw_offset_t DWARFDebugInfoEntry::GetAttributeValue(
//----------------------------------------------------------------------
// GetAttributeValueAsString
//
-// Get the value of an attribute as a string return it. The resulting
-// pointer to the string data exists within the supplied SymbolFileDWARF
-// and will only be available as long as the SymbolFileDWARF is still around
-// and it's content doesn't change.
+// Get the value of an attribute as a string return it. The resulting pointer
+// to the string data exists within the supplied SymbolFileDWARF and will only
+// be available as long as the SymbolFileDWARF is still around and it's content
+// doesn't change.
//----------------------------------------------------------------------
const char *DWARFDebugInfoEntry::GetAttributeValueAsString(
- SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
const dw_attr_t attr, const char *fail_value,
bool check_specification_or_abstract_origin) const {
DWARFFormValue form_value;
@@ -950,7 +946,7 @@ const char *DWARFDebugInfoEntry::GetAttributeValueAsString(
// Get the value of an attribute as unsigned and return it.
//----------------------------------------------------------------------
uint64_t DWARFDebugInfoEntry::GetAttributeValueAsUnsigned(
- SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
const dw_attr_t attr, uint64_t fail_value,
bool check_specification_or_abstract_origin) const {
DWARFFormValue form_value;
@@ -966,7 +962,7 @@ uint64_t DWARFDebugInfoEntry::GetAttributeValueAsUnsigned(
// Get the value of an attribute a signed value and return it.
//----------------------------------------------------------------------
int64_t DWARFDebugInfoEntry::GetAttributeValueAsSigned(
- SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
const dw_attr_t attr, int64_t fail_value,
bool check_specification_or_abstract_origin) const {
DWARFFormValue form_value;
@@ -979,11 +975,11 @@ int64_t DWARFDebugInfoEntry::GetAttributeValueAsSigned(
//----------------------------------------------------------------------
// GetAttributeValueAsReference
//
-// Get the value of an attribute as reference and fix up and compile
-// unit relative offsets as needed.
+// Get the value of an attribute as reference and fix up and compile unit
+// relative offsets as needed.
//----------------------------------------------------------------------
uint64_t DWARFDebugInfoEntry::GetAttributeValueAsReference(
- SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
const dw_attr_t attr, uint64_t fail_value,
bool check_specification_or_abstract_origin) const {
DWARFFormValue form_value;
@@ -994,7 +990,7 @@ uint64_t DWARFDebugInfoEntry::GetAttributeValueAsReference(
}
uint64_t DWARFDebugInfoEntry::GetAttributeValueAsAddress(
- SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
const dw_attr_t attr, uint64_t fail_value,
bool check_specification_or_abstract_origin) const {
DWARFFormValue form_value;
@@ -1007,13 +1003,13 @@ uint64_t DWARFDebugInfoEntry::GetAttributeValueAsAddress(
//----------------------------------------------------------------------
// GetAttributeHighPC
//
-// Get the hi_pc, adding hi_pc to lo_pc when specified
-// as an <offset-from-low-pc>.
+// Get the hi_pc, adding hi_pc to lo_pc when specified as an <offset-from-low-
+// pc>.
//
// Returns the hi_pc or fail_value.
//----------------------------------------------------------------------
dw_addr_t DWARFDebugInfoEntry::GetAttributeHighPC(
- SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, dw_addr_t lo_pc,
+ SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, dw_addr_t lo_pc,
uint64_t fail_value, bool check_specification_or_abstract_origin) const {
DWARFFormValue form_value;
if (GetAttributeValue(dwarf2Data, cu, DW_AT_high_pc, form_value, nullptr,
@@ -1031,13 +1027,13 @@ dw_addr_t DWARFDebugInfoEntry::GetAttributeHighPC(
//----------------------------------------------------------------------
// GetAttributeAddressRange
//
-// Get the lo_pc and hi_pc, adding hi_pc to lo_pc when specified
-// as an <offset-from-low-pc>.
+// Get the lo_pc and hi_pc, adding hi_pc to lo_pc when specified as an <offset-
+// from-low-pc>.
//
// Returns true or sets lo_pc and hi_pc to fail_value.
//----------------------------------------------------------------------
bool DWARFDebugInfoEntry::GetAttributeAddressRange(
- SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, dw_addr_t &lo_pc,
+ SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, dw_addr_t &lo_pc,
dw_addr_t &hi_pc, uint64_t fail_value,
bool check_specification_or_abstract_origin) const {
lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc, fail_value,
@@ -1054,7 +1050,7 @@ bool DWARFDebugInfoEntry::GetAttributeAddressRange(
}
size_t DWARFDebugInfoEntry::GetAttributeAddressRanges(
- SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
DWARFRangeList &ranges, bool check_hi_lo_pc,
bool check_specification_or_abstract_origin) const {
ranges.Clear();
@@ -1083,23 +1079,23 @@ size_t DWARFDebugInfoEntry::GetAttributeAddressRanges(
//----------------------------------------------------------------------
// GetName
//
-// Get value of the DW_AT_name attribute and return it if one exists,
-// else return NULL.
+// Get value of the DW_AT_name attribute and return it if one exists, else
+// return NULL.
//----------------------------------------------------------------------
const char *DWARFDebugInfoEntry::GetName(SymbolFileDWARF *dwarf2Data,
- const DWARFCompileUnit *cu) const {
+ const DWARFUnit *cu) const {
return GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
}
//----------------------------------------------------------------------
// GetMangledName
//
-// Get value of the DW_AT_MIPS_linkage_name attribute and return it if
-// one exists, else return the value of the DW_AT_name attribute
+// Get value of the DW_AT_MIPS_linkage_name attribute and return it if one
+// exists, else return the value of the DW_AT_name attribute
//----------------------------------------------------------------------
const char *
DWARFDebugInfoEntry::GetMangledName(SymbolFileDWARF *dwarf2Data,
- const DWARFCompileUnit *cu,
+ const DWARFUnit *cu,
bool substitute_name_allowed) const {
const char *name = nullptr;
@@ -1123,11 +1119,11 @@ DWARFDebugInfoEntry::GetMangledName(SymbolFileDWARF *dwarf2Data,
//----------------------------------------------------------------------
// GetPubname
//
-// Get value the name for a DIE as it should appear for a
-// .debug_pubnames or .debug_pubtypes section.
+// Get value the name for a DIE as it should appear for a .debug_pubnames or
+// .debug_pubtypes section.
//----------------------------------------------------------------------
const char *DWARFDebugInfoEntry::GetPubname(SymbolFileDWARF *dwarf2Data,
- const DWARFCompileUnit *cu) const {
+ const DWARFUnit *cu) const {
const char *name = nullptr;
if (!dwarf2Data)
return name;
@@ -1149,14 +1145,13 @@ const char *DWARFDebugInfoEntry::GetPubname(SymbolFileDWARF *dwarf2Data,
//----------------------------------------------------------------------
// GetName
//
-// Get value of the DW_AT_name attribute for a debug information entry
-// that exists at offset "die_offset" and place that value into the
-// supplied stream object. If the DIE is a NULL object "NULL" is placed
-// into the stream, and if no DW_AT_name attribute exists for the DIE
-// then nothing is printed.
+// Get value of the DW_AT_name attribute for a debug information entry that
+// exists at offset "die_offset" and place that value into the supplied stream
+// object. If the DIE is a NULL object "NULL" is placed into the stream, and if
+// no DW_AT_name attribute exists for the DIE then nothing is printed.
//----------------------------------------------------------------------
bool DWARFDebugInfoEntry::GetName(SymbolFileDWARF *dwarf2Data,
- const DWARFCompileUnit *cu,
+ const DWARFUnit *cu,
const dw_offset_t die_offset, Stream &s) {
if (dwarf2Data == NULL) {
s.PutCString("NULL");
@@ -1184,13 +1179,12 @@ bool DWARFDebugInfoEntry::GetName(SymbolFileDWARF *dwarf2Data,
//----------------------------------------------------------------------
// AppendTypeName
//
-// Follows the type name definition down through all needed tags to
-// end up with a fully qualified type name and dump the results to
-// the supplied stream. This is used to show the name of types given
-// a type identifier.
+// Follows the type name definition down through all needed tags to end up with
+// a fully qualified type name and dump the results to the supplied stream.
+// This is used to show the name of types given a type identifier.
//----------------------------------------------------------------------
bool DWARFDebugInfoEntry::AppendTypeName(SymbolFileDWARF *dwarf2Data,
- const DWARFCompileUnit *cu,
+ const DWARFUnit *cu,
const dw_offset_t die_offset,
Stream &s) {
if (dwarf2Data == NULL) {
@@ -1318,7 +1312,7 @@ bool DWARFDebugInfoEntry::AppendTypeName(SymbolFileDWARF *dwarf2Data,
// BuildAddressRangeTable
//----------------------------------------------------------------------
void DWARFDebugInfoEntry::BuildAddressRangeTable(
- SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
DWARFDebugAranges *debug_aranges) const {
if (m_tag) {
if (m_tag == DW_TAG_subprogram) {
@@ -1343,13 +1337,13 @@ void DWARFDebugInfoEntry::BuildAddressRangeTable(
//----------------------------------------------------------------------
// BuildFunctionAddressRangeTable
//
-// This function is very similar to the BuildAddressRangeTable function
-// except that the actual DIE offset for the function is placed in the
-// table instead of the compile unit offset (which is the way the
-// standard .debug_aranges section does it).
+// This function is very similar to the BuildAddressRangeTable function except
+// that the actual DIE offset for the function is placed in the table instead
+// of the compile unit offset (which is the way the standard .debug_aranges
+// section does it).
//----------------------------------------------------------------------
void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable(
- SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
DWARFDebugAranges *debug_aranges) const {
if (m_tag) {
if (m_tag == DW_TAG_subprogram) {
@@ -1372,21 +1366,22 @@ void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable(
}
void DWARFDebugInfoEntry::GetDeclContextDIEs(
- DWARFCompileUnit *cu, DWARFDIECollection &decl_context_dies) const {
+ DWARFUnit *cu, DWARFDIECollection &decl_context_dies) const {
DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this));
die.GetDeclContextDIEs(decl_context_dies);
}
void DWARFDebugInfoEntry::GetDWARFDeclContext(
- SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
+ SymbolFileDWARF *dwarf2Data, DWARFUnit *cu,
DWARFDeclContext &dwarf_decl_ctx) const {
const dw_tag_t tag = Tag();
- if (tag != DW_TAG_compile_unit) {
+ if (tag != DW_TAG_compile_unit && tag != DW_TAG_partial_unit) {
dwarf_decl_ctx.AppendDeclContext(tag, GetName(dwarf2Data, cu));
DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(dwarf2Data, cu);
if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != this) {
- if (parent_decl_ctx_die.Tag() != DW_TAG_compile_unit)
+ if (parent_decl_ctx_die.Tag() != DW_TAG_compile_unit &&
+ parent_decl_ctx_die.Tag() != DW_TAG_partial_unit)
parent_decl_ctx_die.GetDIE()->GetDWARFDeclContext(
parent_decl_ctx_die.GetDWARF(), parent_decl_ctx_die.GetCU(),
dwarf_decl_ctx);
@@ -1395,7 +1390,7 @@ void DWARFDebugInfoEntry::GetDWARFDeclContext(
}
bool DWARFDebugInfoEntry::MatchesDWARFDeclContext(
- SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
+ SymbolFileDWARF *dwarf2Data, DWARFUnit *cu,
const DWARFDeclContext &dwarf_decl_ctx) const {
DWARFDeclContext this_dwarf_decl_ctx;
@@ -1405,7 +1400,7 @@ bool DWARFDebugInfoEntry::MatchesDWARFDeclContext(
DWARFDIE
DWARFDebugInfoEntry::GetParentDeclContextDIE(SymbolFileDWARF *dwarf2Data,
- DWARFCompileUnit *cu) const {
+ DWARFUnit *cu) const {
DWARFAttributes attributes;
GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes);
return GetParentDeclContextDIE(dwarf2Data, cu, attributes);
@@ -1413,17 +1408,18 @@ DWARFDebugInfoEntry::GetParentDeclContextDIE(SymbolFileDWARF *dwarf2Data,
DWARFDIE
DWARFDebugInfoEntry::GetParentDeclContextDIE(
- SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
+ SymbolFileDWARF *dwarf2Data, DWARFUnit *cu,
const DWARFAttributes &attributes) const {
DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this));
while (die) {
- // If this is the original DIE that we are searching for a declaration
- // for, then don't look in the cache as we don't want our own decl
- // context to be our decl context...
+ // If this is the original DIE that we are searching for a declaration for,
+ // then don't look in the cache as we don't want our own decl context to be
+ // our decl context...
if (die.GetDIE() != this) {
switch (die.Tag()) {
case DW_TAG_compile_unit:
+ case DW_TAG_partial_unit:
case DW_TAG_namespace:
case DW_TAG_structure_type:
case DW_TAG_union_type:
@@ -1465,7 +1461,7 @@ DWARFDebugInfoEntry::GetParentDeclContextDIE(
}
const char *DWARFDebugInfoEntry::GetQualifiedName(SymbolFileDWARF *dwarf2Data,
- DWARFCompileUnit *cu,
+ DWARFUnit *cu,
std::string &storage) const {
DWARFAttributes attributes;
GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes);
@@ -1473,7 +1469,7 @@ const char *DWARFDebugInfoEntry::GetQualifiedName(SymbolFileDWARF *dwarf2Data,
}
const char *DWARFDebugInfoEntry::GetQualifiedName(
- SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
+ SymbolFileDWARF *dwarf2Data, DWARFUnit *cu,
const DWARFAttributes &attributes, std::string &storage) const {
const char *name = GetName(dwarf2Data, cu);
@@ -1529,7 +1525,7 @@ const char *DWARFDebugInfoEntry::GetQualifiedName(
//----------------------------------------------------------------------
bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
SymbolFileDWARF *dwarf2Data,
- const DWARFCompileUnit *cu,
+ const DWARFUnit *cu,
DWARFDebugInfoEntry **function_die,
DWARFDebugInfoEntry **block_die) {
bool found_address = false;
@@ -1661,6 +1657,7 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
case DW_TAG_unspecified_type:
break;
case DW_TAG_partial_unit:
+ match_addr_range = true;
break;
case DW_TAG_imported_unit:
break;
@@ -1684,6 +1681,7 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
// puts("***MATCH***");
switch (m_tag) {
case DW_TAG_compile_unit: // File
+ case DW_TAG_partial_unit: // File
check_children = ((function_die != NULL) || (block_die != NULL));
break;
@@ -1706,10 +1704,12 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
break;
}
}
- } else { // compile units may not have a valid high/low pc when there
+ } else {
+ // Compile units may not have a valid high/low pc when there
// are address gaps in subroutines so we must always search
- // if there is no valid high and low PC
- check_children = (m_tag == DW_TAG_compile_unit) &&
+ // if there is no valid high and low PC.
+ check_children = (m_tag == DW_TAG_compile_unit ||
+ m_tag == DW_TAG_partial_unit) &&
((function_die != NULL) || (block_die != NULL));
}
} else {
@@ -1719,15 +1719,16 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
DWARFRangeList ranges;
DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges();
debug_ranges->FindRanges(cu->GetRangesBase(), debug_ranges_offset, ranges);
- // All DW_AT_ranges are relative to the base address of the
- // compile unit. We add the compile unit base address to make
- // sure all the addresses are properly fixed up.
+ // All DW_AT_ranges are relative to the base address of the compile
+ // unit. We add the compile unit base address to make sure all the
+ // addresses are properly fixed up.
ranges.Slide(cu->GetBaseAddress());
if (ranges.FindEntryThatContains(address)) {
found_address = true;
// puts("***MATCH***");
switch (m_tag) {
case DW_TAG_compile_unit: // File
+ case DW_TAG_partial_unit: // File
check_children = ((function_die != NULL) || (block_die != NULL));
break;
@@ -1772,7 +1773,7 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
const DWARFAbbreviationDeclaration *
DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(
- SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
lldb::offset_t &offset) const {
if (dwarf2Data) {
offset = GetOffset();
@@ -1782,11 +1783,10 @@ DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(
const DWARFAbbreviationDeclaration *abbrev_decl =
abbrev_set->GetAbbreviationDeclaration(m_abbr_idx);
if (abbrev_decl) {
- // Make sure the abbreviation code still matches. If it doesn't and
- // the DWARF data was mmap'ed, the backing file might have been modified
+ // Make sure the abbreviation code still matches. If it doesn't and the
+ // DWARF data was mmap'ed, the backing file might have been modified
// which is bad news.
- const uint64_t abbrev_code =
- dwarf2Data->get_debug_info_data().GetULEB128(&offset);
+ const uint64_t abbrev_code = cu->GetData().GetULEB128(&offset);
if (abbrev_decl->Code() == abbrev_code)
return abbrev_decl;
@@ -1825,3 +1825,15 @@ void DWARFDebugInfoEntry::DumpDIECollection(
die_ref.HasChildren() ? " *" : "");
}
}
+
+bool DWARFDebugInfoEntry::operator==(const DWARFDebugInfoEntry &rhs) const {
+ return m_offset == rhs.m_offset && m_parent_idx == rhs.m_parent_idx &&
+ m_sibling_idx == rhs.m_sibling_idx &&
+ m_empty_children == rhs.m_empty_children &&
+ m_abbr_idx == rhs.m_abbr_idx && m_has_children == rhs.m_has_children &&
+ m_tag == rhs.m_tag;
+}
+
+bool DWARFDebugInfoEntry::operator!=(const DWARFDebugInfoEntry &rhs) const {
+ return !(*this == rhs);
+}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
index 89450d327adf..97cb3046eb3e 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -60,128 +60,132 @@ public:
m_empty_children(false), m_abbr_idx(0), m_has_children(false),
m_tag(0) {}
+ explicit operator bool() const { return m_offset != DW_INVALID_OFFSET; }
+ bool operator==(const DWARFDebugInfoEntry &rhs) const;
+ bool operator!=(const DWARFDebugInfoEntry &rhs) const;
+
void BuildAddressRangeTable(SymbolFileDWARF *dwarf2Data,
- const DWARFCompileUnit *cu,
+ const DWARFUnit *cu,
DWARFDebugAranges *debug_aranges) const;
void BuildFunctionAddressRangeTable(SymbolFileDWARF *dwarf2Data,
- const DWARFCompileUnit *cu,
+ const DWARFUnit *cu,
DWARFDebugAranges *debug_aranges) const;
bool FastExtract(const lldb_private::DWARFDataExtractor &debug_info_data,
- const DWARFCompileUnit *cu,
+ const DWARFUnit *cu,
const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
lldb::offset_t *offset_ptr);
- bool Extract(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ bool Extract(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
lldb::offset_t *offset_ptr);
bool LookupAddress(const dw_addr_t address, SymbolFileDWARF *dwarf2Data,
- const DWARFCompileUnit *cu,
+ const DWARFUnit *cu,
DWARFDebugInfoEntry **function_die,
DWARFDebugInfoEntry **block_die);
- size_t GetAttributes(const DWARFCompileUnit *cu,
+ size_t GetAttributes(const DWARFUnit *cu,
DWARFFormValue::FixedFormSizes fixed_form_sizes,
DWARFAttributes &attrs,
uint32_t curr_depth = 0)
const; // "curr_depth" for internal use only, don't set this yourself!!!
dw_offset_t
- GetAttributeValue(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ GetAttributeValue(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
const dw_attr_t attr, DWARFFormValue &formValue,
dw_offset_t *end_attr_offset_ptr = nullptr,
bool check_specification_or_abstract_origin = false) const;
const char *GetAttributeValueAsString(
- SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
const dw_attr_t attr, const char *fail_value,
bool check_specification_or_abstract_origin = false) const;
uint64_t GetAttributeValueAsUnsigned(
- SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
const dw_attr_t attr, uint64_t fail_value,
bool check_specification_or_abstract_origin = false) const;
uint64_t GetAttributeValueAsReference(
- SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
const dw_attr_t attr, uint64_t fail_value,
bool check_specification_or_abstract_origin = false) const;
int64_t GetAttributeValueAsSigned(
- SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
const dw_attr_t attr, int64_t fail_value,
bool check_specification_or_abstract_origin = false) const;
uint64_t GetAttributeValueAsAddress(
- SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
const dw_attr_t attr, uint64_t fail_value,
bool check_specification_or_abstract_origin = false) const;
dw_addr_t
- GetAttributeHighPC(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ GetAttributeHighPC(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
dw_addr_t lo_pc, uint64_t fail_value,
bool check_specification_or_abstract_origin = false) const;
bool GetAttributeAddressRange(
- SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, dw_addr_t &lo_pc,
+ SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, dw_addr_t &lo_pc,
dw_addr_t &hi_pc, uint64_t fail_value,
bool check_specification_or_abstract_origin = false) const;
size_t GetAttributeAddressRanges(
- SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
DWARFRangeList &ranges, bool check_hi_lo_pc,
bool check_specification_or_abstract_origin = false) const;
const char *GetName(SymbolFileDWARF *dwarf2Data,
- const DWARFCompileUnit *cu) const;
+ const DWARFUnit *cu) const;
const char *GetMangledName(SymbolFileDWARF *dwarf2Data,
- const DWARFCompileUnit *cu,
+ const DWARFUnit *cu,
bool substitute_name_allowed = true) const;
const char *GetPubname(SymbolFileDWARF *dwarf2Data,
- const DWARFCompileUnit *cu) const;
+ const DWARFUnit *cu) const;
- static bool GetName(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ static bool GetName(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
const dw_offset_t die_offset, lldb_private::Stream &s);
static bool AppendTypeName(SymbolFileDWARF *dwarf2Data,
- const DWARFCompileUnit *cu,
+ const DWARFUnit *cu,
const dw_offset_t die_offset,
lldb_private::Stream &s);
const char *GetQualifiedName(SymbolFileDWARF *dwarf2Data,
- DWARFCompileUnit *cu,
+ DWARFUnit *cu,
std::string &storage) const;
const char *GetQualifiedName(SymbolFileDWARF *dwarf2Data,
- DWARFCompileUnit *cu,
+ DWARFUnit *cu,
const DWARFAttributes &attributes,
std::string &storage) const;
static bool OffsetLessThan(const DWARFDebugInfoEntry &a,
const DWARFDebugInfoEntry &b);
- void Dump(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ void Dump(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
lldb_private::Stream &s, uint32_t recurse_depth) const;
- void DumpAncestry(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ void DumpAncestry(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
const DWARFDebugInfoEntry *oldest, lldb_private::Stream &s,
uint32_t recurse_depth) const;
static void
- DumpAttribute(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ DumpAttribute(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
const lldb_private::DWARFDataExtractor &debug_info_data,
lldb::offset_t *offset_ptr, lldb_private::Stream &s,
dw_attr_t attr, dw_form_t form);
// This one dumps the comp unit name, objfile name and die offset for this die
// so the stream S.
- void DumpLocation(SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
+ void DumpLocation(SymbolFileDWARF *dwarf2Data, DWARFUnit *cu,
lldb_private::Stream &s) const;
bool
- GetDIENamesAndRanges(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ GetDIENamesAndRanges(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
const char *&name, const char *&mangled,
DWARFRangeList &rangeList, int &decl_file,
int &decl_line, int &decl_column, int &call_file,
@@ -190,7 +194,7 @@ public:
const DWARFAbbreviationDeclaration *
GetAbbreviationDeclarationPtr(SymbolFileDWARF *dwarf2Data,
- const DWARFCompileUnit *cu,
+ const DWARFUnit *cu,
lldb::offset_t &offset) const;
dw_tag_t Tag() const { return m_tag; }
@@ -229,20 +233,20 @@ public:
return (HasChildren() && !m_empty_children) ? this + 1 : NULL;
}
- void GetDeclContextDIEs(DWARFCompileUnit *cu,
+ void GetDeclContextDIEs(DWARFUnit *cu,
DWARFDIECollection &decl_context_dies) const;
- void GetDWARFDeclContext(SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
+ void GetDWARFDeclContext(SymbolFileDWARF *dwarf2Data, DWARFUnit *cu,
DWARFDeclContext &dwarf_decl_ctx) const;
bool MatchesDWARFDeclContext(SymbolFileDWARF *dwarf2Data,
- DWARFCompileUnit *cu,
+ DWARFUnit *cu,
const DWARFDeclContext &dwarf_decl_ctx) const;
DWARFDIE GetParentDeclContextDIE(SymbolFileDWARF *dwarf2Data,
- DWARFCompileUnit *cu) const;
+ DWARFUnit *cu) const;
DWARFDIE GetParentDeclContextDIE(SymbolFileDWARF *dwarf2Data,
- DWARFCompileUnit *cu,
+ DWARFUnit *cu,
const DWARFAttributes &attributes) const;
void SetParent(DWARFDebugInfoEntry *parent) {
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
index 694d34fc211c..317ea4c22c66 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
@@ -242,8 +242,8 @@ dw_offset_t DWARFDebugLine::DumpStatementOpcodes(
log->Printf("0x%8.8x: DW_LNE_??? (%2.2x) - Skipping unknown upcode",
op_offset, opcode);
// Length doesn't include the zero opcode byte or the length itself,
- // but
- // it does include the sub_opcode, so we have to adjust for that below
+ // but it does include the sub_opcode, so we have to adjust for that
+ // below
offset += arg_size;
break;
}
@@ -324,9 +324,9 @@ dw_offset_t DWARFDebugLine::DumpStatementOpcodes(
// Special Opcodes
default:
if (opcode < prologue.opcode_base) {
- // We have an opcode that this parser doesn't know about, skip
- // the number of ULEB128 numbers that is says to skip in the
- // prologue's standard_opcode_lengths array
+ // We have an opcode that this parser doesn't know about, skip the
+ // number of ULEB128 numbers that is says to skip in the prologue's
+ // standard_opcode_lengths array
uint8_t n = prologue.standard_opcode_lengths[opcode - 1];
log->Printf("0x%8.8x: Special : Unknown skipping %u ULEB128 values.",
op_offset, n);
@@ -357,9 +357,9 @@ dw_offset_t DWARFDebugLine::DumpStatementOpcodes(
//----------------------------------------------------------------------
// Parse
//
-// Parse the entire line table contents calling callback each time a
-// new prologue is parsed and every time a new row is to be added to
-// the line table.
+// Parse the entire line table contents calling callback each time a new
+// prologue is parsed and every time a new row is to be added to the line
+// table.
//----------------------------------------------------------------------
void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data,
DWARFDebugLine::State::Callback callback,
@@ -444,7 +444,7 @@ bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data,
bool DWARFDebugLine::ParseSupportFiles(
const lldb::ModuleSP &module_sp, const DWARFDataExtractor &debug_line_data,
- const char *cu_comp_dir, dw_offset_t stmt_list,
+ const lldb_private::FileSpec &cu_comp_dir, dw_offset_t stmt_list,
FileSpecList &support_files) {
lldb::offset_t offset = stmt_list;
@@ -463,7 +463,7 @@ bool DWARFDebugLine::ParseSupportFiles(
for (uint32_t file_idx = 1;
prologue.GetFile(file_idx, cu_comp_dir, file_spec); ++file_idx) {
if (module_sp->RemapSourceFile(file_spec.GetPath(), remapped_file))
- file_spec.SetFile(remapped_file, false);
+ file_spec.SetFile(remapped_file, false, FileSpec::Style::native);
support_files.Append(file_spec);
}
return true;
@@ -472,9 +472,9 @@ bool DWARFDebugLine::ParseSupportFiles(
//----------------------------------------------------------------------
// ParseStatementTable
//
-// Parse a single line table (prologue and all rows) and call the
-// callback function once for the prologue (row in state will be zero)
-// and each time a row is to be added to the line table.
+// Parse a single line table (prologue and all rows) and call the callback
+// function once for the prologue (row in state will be zero) and each time a
+// row is to be added to the line table.
//----------------------------------------------------------------------
bool DWARFDebugLine::ParseStatementTable(
const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
@@ -511,8 +511,8 @@ bool DWARFDebugLine::ParseStatementTable(
uint8_t opcode = debug_line_data.GetU8(offset_ptr);
if (opcode == 0) {
- // Extended Opcodes always start with a zero opcode followed by
- // a uleb128 length so you can skip ones you don't know about
+ // Extended Opcodes always start with a zero opcode followed by a uleb128
+ // length so you can skip ones you don't know about
lldb::offset_t ext_offset = *offset_ptr;
dw_uleb128_t len = debug_line_data.GetULEB128(offset_ptr);
dw_offset_t arg_size = len - (*offset_ptr - ext_offset);
@@ -522,12 +522,12 @@ bool DWARFDebugLine::ParseStatementTable(
switch (sub_opcode) {
case DW_LNE_end_sequence:
// Set the end_sequence register of the state machine to true and
- // append a row to the matrix using the current values of the
- // state-machine registers. Then reset the registers to the initial
- // values specified above. Every statement program sequence must end
- // with a DW_LNE_end_sequence instruction which creates a row whose
- // address is that of the byte after the last target machine instruction
- // of the sequence.
+ // append a row to the matrix using the current values of the state-
+ // machine registers. Then reset the registers to the initial values
+ // specified above. Every statement program sequence must end with a
+ // DW_LNE_end_sequence instruction which creates a row whose address is
+ // that of the byte after the last target machine instruction of the
+ // sequence.
state.end_sequence = true;
state.AppendRowToMatrix(*offset_ptr);
state.Reset();
@@ -537,8 +537,8 @@ bool DWARFDebugLine::ParseStatementTable(
// Takes a single relocatable address as an operand. The size of the
// operand is the size appropriate to hold an address on the target
// machine. Set the address register to the value given by the
- // relocatable address. All of the other statement program opcodes
- // that affect the address register add a delta to it. This instruction
+ // relocatable address. All of the other statement program opcodes that
+ // affect the address register add a delta to it. This instruction
// stores a relocatable value into it instead.
if (arg_size == 4)
state.address = debug_line_data.GetU32(offset_ptr);
@@ -549,24 +549,24 @@ bool DWARFDebugLine::ParseStatementTable(
case DW_LNE_define_file:
// Takes 4 arguments. The first is a null terminated string containing
// a source file name. The second is an unsigned LEB128 number
- // representing
- // the directory index of the directory in which the file was found. The
- // third is an unsigned LEB128 number representing the time of last
- // modification of the file. The fourth is an unsigned LEB128 number
- // representing the length in bytes of the file. The time and length
- // fields may contain LEB128(0) if the information is not available.
+ // representing the directory index of the directory in which the file
+ // was found. The third is an unsigned LEB128 number representing the
+ // time of last modification of the file. The fourth is an unsigned
+ // LEB128 number representing the length in bytes of the file. The time
+ // and length fields may contain LEB128(0) if the information is not
+ // available.
//
// The directory index represents an entry in the include_directories
- // section of the statement program prologue. The index is LEB128(0)
- // if the file was found in the current directory of the compilation,
+ // section of the statement program prologue. The index is LEB128(0) if
+ // the file was found in the current directory of the compilation,
// LEB128(1) if it was found in the first directory in the
// include_directories section, and so on. The directory index is
// ignored for file names that represent full path names.
//
// The files are numbered, starting at 1, in the order in which they
- // appear; the names in the prologue come before names defined by
- // the DW_LNE_define_file instruction. These numbers are used in the
- // file register of the state machine.
+ // appear; the names in the prologue come before names defined by the
+ // DW_LNE_define_file instruction. These numbers are used in the file
+ // register of the state machine.
{
FileNameEntry fileEntry;
fileEntry.name = debug_line_data.GetCStr(offset_ptr);
@@ -578,8 +578,9 @@ bool DWARFDebugLine::ParseStatementTable(
break;
default:
- // Length doesn't include the zero opcode byte or the length itself, but
- // it does include the sub_opcode, so we have to adjust for that below
+ // Length doesn't include the zero opcode byte or the length itself,
+ // but it does include the sub_opcode, so we have to adjust for that
+ // below
(*offset_ptr) += arg_size;
break;
}
@@ -587,23 +588,23 @@ bool DWARFDebugLine::ParseStatementTable(
switch (opcode) {
// Standard Opcodes
case DW_LNS_copy:
- // Takes no arguments. Append a row to the matrix using the
- // current values of the state-machine registers. Then set
- // the basic_block register to false.
+ // Takes no arguments. Append a row to the matrix using the current
+ // values of the state-machine registers. Then set the basic_block
+ // register to false.
state.AppendRowToMatrix(*offset_ptr);
break;
case DW_LNS_advance_pc:
// Takes a single unsigned LEB128 operand, multiplies it by the
- // min_inst_length field of the prologue, and adds the
- // result to the address register of the state machine.
+ // min_inst_length field of the prologue, and adds the result to the
+ // address register of the state machine.
state.address +=
debug_line_data.GetULEB128(offset_ptr) * prologue->min_inst_length;
break;
case DW_LNS_advance_line:
- // Takes a single signed LEB128 operand and adds that value to
- // the line register of the state machine.
+ // Takes a single signed LEB128 operand and adds that value to the line
+ // register of the state machine.
state.line += debug_line_data.GetSLEB128(offset_ptr);
break;
@@ -614,35 +615,35 @@ bool DWARFDebugLine::ParseStatementTable(
break;
case DW_LNS_set_column:
- // Takes a single unsigned LEB128 operand and stores it in the
- // column register of the state machine.
+ // Takes a single unsigned LEB128 operand and stores it in the column
+ // register of the state machine.
state.column = debug_line_data.GetULEB128(offset_ptr);
break;
case DW_LNS_negate_stmt:
- // Takes no arguments. Set the is_stmt register of the state
- // machine to the logical negation of its current value.
+ // Takes no arguments. Set the is_stmt register of the state machine to
+ // the logical negation of its current value.
state.is_stmt = !state.is_stmt;
break;
case DW_LNS_set_basic_block:
- // Takes no arguments. Set the basic_block register of the
- // state machine to true
+ // Takes no arguments. Set the basic_block register of the state
+ // machine to true
state.basic_block = true;
break;
case DW_LNS_const_add_pc:
- // Takes no arguments. Add to the address register of the state
- // machine the address increment value corresponding to special
- // opcode 255. The motivation for DW_LNS_const_add_pc is this:
- // when the statement program needs to advance the address by a
- // small amount, it can use a single special opcode, which occupies
- // a single byte. When it needs to advance the address by up to
- // twice the range of the last special opcode, it can use
- // DW_LNS_const_add_pc followed by a special opcode, for a total
- // of two bytes. Only if it needs to advance the address by more
- // than twice that range will it need to use both DW_LNS_advance_pc
- // and a special opcode, requiring three or more bytes.
+ // Takes no arguments. Add to the address register of the state machine
+ // the address increment value corresponding to special opcode 255. The
+ // motivation for DW_LNS_const_add_pc is this: when the statement
+ // program needs to advance the address by a small amount, it can use a
+ // single special opcode, which occupies a single byte. When it needs
+ // to advance the address by up to twice the range of the last special
+ // opcode, it can use DW_LNS_const_add_pc followed by a special opcode,
+ // for a total of two bytes. Only if it needs to advance the address by
+ // more than twice that range will it need to use both
+ // DW_LNS_advance_pc and a special opcode, requiring three or more
+ // bytes.
{
uint8_t adjust_opcode = 255 - prologue->opcode_base;
dw_addr_t addr_offset = (adjust_opcode / prologue->line_range) *
@@ -652,40 +653,40 @@ bool DWARFDebugLine::ParseStatementTable(
break;
case DW_LNS_fixed_advance_pc:
- // Takes a single uhalf operand. Add to the address register of
- // the state machine the value of the (unencoded) operand. This
- // is the only extended opcode that takes an argument that is not
- // a variable length number. The motivation for DW_LNS_fixed_advance_pc
- // is this: existing assemblers cannot emit DW_LNS_advance_pc or
- // special opcodes because they cannot encode LEB128 numbers or
- // judge when the computation of a special opcode overflows and
- // requires the use of DW_LNS_advance_pc. Such assemblers, however,
- // can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
+ // Takes a single uhalf operand. Add to the address register of the
+ // state machine the value of the (unencoded) operand. This is the only
+ // extended opcode that takes an argument that is not a variable length
+ // number. The motivation for DW_LNS_fixed_advance_pc is this: existing
+ // assemblers cannot emit DW_LNS_advance_pc or special opcodes because
+ // they cannot encode LEB128 numbers or judge when the computation of a
+ // special opcode overflows and requires the use of DW_LNS_advance_pc.
+ // Such assemblers, however, can use DW_LNS_fixed_advance_pc instead,
+ // sacrificing compression.
state.address += debug_line_data.GetU16(offset_ptr);
break;
case DW_LNS_set_prologue_end:
- // Takes no arguments. Set the prologue_end register of the
- // state machine to true
+ // Takes no arguments. Set the prologue_end register of the state
+ // machine to true
state.prologue_end = true;
break;
case DW_LNS_set_epilogue_begin:
- // Takes no arguments. Set the basic_block register of the
- // state machine to true
+ // Takes no arguments. Set the basic_block register of the state
+ // machine to true
state.epilogue_begin = true;
break;
case DW_LNS_set_isa:
- // Takes a single unsigned LEB128 operand and stores it in the
- // column register of the state machine.
+ // Takes a single unsigned LEB128 operand and stores it in the column
+ // register of the state machine.
state.isa = debug_line_data.GetULEB128(offset_ptr);
break;
default:
- // Handle any unknown standard opcodes here. We know the lengths
- // of such opcodes because they are specified in the prologue
- // as a multiple of LEB128 operands for each opcode.
+ // Handle any unknown standard opcodes here. We know the lengths of
+ // such opcodes because they are specified in the prologue as a
+ // multiple of LEB128 operands for each opcode.
{
uint8_t i;
assert(static_cast<size_t>(opcode - 1) <
@@ -702,32 +703,32 @@ bool DWARFDebugLine::ParseStatementTable(
// A special opcode value is chosen based on the amount that needs
// to be added to the line and address registers. The maximum line
- // increment for a special opcode is the value of the line_base
- // field in the header, plus the value of the line_range field,
- // minus 1 (line base + line range - 1). If the desired line
- // increment is greater than the maximum line increment, a standard
- // opcode must be used instead of a special opcode. The "address
- // advance" is calculated by dividing the desired address increment
- // by the minimum_instruction_length field from the header. The
- // special opcode is then calculated using the following formula:
+ // increment for a special opcode is the value of the line_base field in
+ // the header, plus the value of the line_range field, minus 1 (line base
+ // + line range - 1). If the desired line increment is greater than the
+ // maximum line increment, a standard opcode must be used instead of a
+ // special opcode. The "address advance" is calculated by dividing the
+ // desired address increment by the minimum_instruction_length field from
+ // the header. The special opcode is then calculated using the following
+ // formula:
//
// opcode = (desired line increment - line_base) + (line_range * address
// advance) + opcode_base
//
- // If the resulting opcode is greater than 255, a standard opcode
- // must be used instead.
+ // If the resulting opcode is greater than 255, a standard opcode must be
+ // used instead.
//
- // To decode a special opcode, subtract the opcode_base from the
- // opcode itself to give the adjusted opcode. The amount to
- // increment the address register is the result of the adjusted
- // opcode divided by the line_range multiplied by the
- // minimum_instruction_length field from the header. That is:
+ // To decode a special opcode, subtract the opcode_base from the opcode
+ // itself to give the adjusted opcode. The amount to increment the
+ // address register is the result of the adjusted opcode divided by the
+ // line_range multiplied by the minimum_instruction_length field from the
+ // header. That is:
//
// address increment = (adjusted opcode / line_range) *
// minimum_instruction_length
//
- // The amount to increment the line register is the line_base plus
- // the result of the adjusted opcode modulo the line_range. That is:
+ // The amount to increment the line register is the line_base plus the
+ // result of the adjusted opcode modulo the line_range. That is:
//
// line increment = line_base + (adjusted opcode % line_range)
@@ -755,8 +756,8 @@ static void ParseStatementTableCallback(dw_offset_t offset,
void *userData) {
DWARFDebugLine::LineTable *line_table = (DWARFDebugLine::LineTable *)userData;
if (state.row == DWARFDebugLine::State::StartParsingLineTable) {
- // Just started parsing the line table, so lets keep a reference to
- // the prologue using the supplied shared pointer
+ // Just started parsing the line table, so lets keep a reference to the
+ // prologue using the supplied shared pointer
line_table->prologue = state.prologue;
} else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) {
// Done parsing line table, nothing to do for the cleanup
@@ -769,8 +770,8 @@ static void ParseStatementTableCallback(dw_offset_t offset,
//----------------------------------------------------------------------
// ParseStatementTable
//
-// Parse a line table at offset and populate the LineTable class with
-// the prologue and all rows.
+// Parse a line table at offset and populate the LineTable class with the
+// prologue and all rows.
//----------------------------------------------------------------------
bool DWARFDebugLine::ParseStatementTable(
const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
@@ -861,11 +862,11 @@ void DWARFDebugLine::Prologue::Dump(Log *log) {
// buff.Append8(0); // Terminate the file names section with empty string
//}
-bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx, const char *comp_dir,
- FileSpec &file) const {
+bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx,
+ const lldb_private::FileSpec &comp_dir, FileSpec &file) const {
uint32_t idx = file_idx - 1; // File indexes are 1 based...
if (idx < file_names.size()) {
- file.SetFile(file_names[idx].name, false);
+ file.SetFile(file_names[idx].name, false, FileSpec::Style::native);
if (file.IsRelative()) {
if (file_names[idx].dir_idx > 0) {
const uint32_t dir_idx = file_names[idx].dir_idx - 1;
@@ -876,7 +877,7 @@ bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx, const char *comp_dir,
}
}
- if (comp_dir && comp_dir[0])
+ if (comp_dir)
file.PrependPathComponent(comp_dir);
}
return true;
@@ -936,11 +937,10 @@ uint32_t DWARFDebugLine::LineTable::LookupAddress(dw_addr_t address,
if (address < cu_high_pc)
return rows.size() - 1;
} else {
- // Rely on fact that we are using a std::vector and we can do
- // pointer arithmetic to find the row index (which will be one less
- // that what we found since it will find the first position after
- // the current address) since std::vector iterators are just
- // pointers to the container type.
+ // Rely on fact that we are using a std::vector and we can do pointer
+ // arithmetic to find the row index (which will be one less that what we
+ // found since it will find the first position after the current address)
+ // since std::vector iterators are just pointers to the container type.
index = pos - begin_pos;
if (pos->address > address) {
if (index > 0)
@@ -1005,9 +1005,9 @@ static bool AddressLessThan(const DWARFDebugLine::Row &a,
return a.address < b.address;
}
-// Insert a row at the correct address if the addresses can be out of
-// order which can only happen when we are linking a line table that
-// may have had it's contents rearranged.
+// Insert a row at the correct address if the addresses can be out of order
+// which can only happen when we are linking a line table that may have had
+// it's contents rearranged.
void DWARFDebugLine::Row::Insert(Row::collection &state_coll,
const Row &state) {
// If we don't have anything yet, or if the address of the last state in our
@@ -1020,12 +1020,12 @@ void DWARFDebugLine::Row::Insert(Row::collection &state_coll,
state_coll.begin(), state_coll.end(), state, AddressLessThan));
// If the addresses are equal, we can safely replace the previous entry
- // with the current one if the one it is replacing is an end_sequence entry.
- // We currently always place an extra end sequence when ever we exit a valid
- // address range for a function in case the functions get rearranged by
- // optimizations or by order specifications. These extra end sequences will
- // disappear by getting replaced with valid consecutive entries within a
- // compile unit if there are no gaps.
+ // with the current one if the one it is replacing is an end_sequence
+ // entry. We currently always place an extra end sequence when ever we exit
+ // a valid address range for a function in case the functions get
+ // rearranged by optimizations or by order specifications. These extra end
+ // sequences will disappear by getting replaced with valid consecutive
+ // entries within a compile unit if there are no gaps.
if (range.first == range.second) {
state_coll.insert(range.first, state);
} else {
@@ -1065,10 +1065,9 @@ void DWARFDebugLine::State::Reset() { Row::Reset(prologue->default_is_stmt); }
// DWARFDebugLine::State::AppendRowToMatrix
//----------------------------------------------------------------------
void DWARFDebugLine::State::AppendRowToMatrix(dw_offset_t offset) {
- // Each time we are to add an entry into the line table matrix
- // call the callback function so that someone can do something with
- // the current state of the state machine (like build a line table
- // or dump the line table!)
+ // Each time we are to add an entry into the line table matrix call the
+ // callback function so that someone can do something with the current state
+ // of the state machine (like build a line table or dump the line table!)
if (log) {
if (row == 0) {
log->PutCString("Address Line Column File ISA Flags");
@@ -1088,8 +1087,8 @@ void DWARFDebugLine::State::AppendRowToMatrix(dw_offset_t offset) {
// DWARFDebugLine::State::Finalize
//----------------------------------------------------------------------
void DWARFDebugLine::State::Finalize(dw_offset_t offset) {
- // Call the callback with a special row state when we are done parsing a
- // line table
+ // Call the callback with a special row state when we are done parsing a line
+ // table
row = DoneParsingLineTable;
if (callback)
callback(offset, *this, callbackUserData);
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
index ea02cfed6e01..3ab15ac59028 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
@@ -90,7 +90,7 @@ public:
include_directories.clear();
file_names.clear();
}
- bool GetFile(uint32_t file_idx, const char *comp_dir,
+ bool GetFile(uint32_t file_idx, const lldb_private::FileSpec &cu_comp_dir,
lldb_private::FileSpec &file) const;
};
@@ -199,7 +199,8 @@ public:
static bool
ParseSupportFiles(const lldb::ModuleSP &module_sp,
const lldb_private::DWARFDataExtractor &debug_line_data,
- const char *cu_comp_dir, dw_offset_t stmt_list,
+ const lldb_private::FileSpec &cu_comp_dir,
+ dw_offset_t stmt_list,
lldb_private::FileSpecList &support_files);
static bool
ParsePrologue(const lldb_private::DWARFDataExtractor &debug_line_data,
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp
deleted file mode 100644
index 766899c497b0..000000000000
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-//===-- DWARFDebugPubnames.cpp ----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DWARFDebugPubnames.h"
-
-#include "lldb/Utility/Stream.h"
-#include "lldb/Utility/Timer.h"
-
-#include "DWARFCompileUnit.h"
-#include "DWARFDIECollection.h"
-#include "DWARFDebugInfo.h"
-#include "DWARFFormValue.h"
-#include "LogChannelDWARF.h"
-#include "SymbolFileDWARF.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-DWARFDebugPubnames::DWARFDebugPubnames() : m_sets() {}
-
-bool DWARFDebugPubnames::Extract(const DWARFDataExtractor &data) {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat,
- "DWARFDebugPubnames::Extract (byte_size = %" PRIu64 ")",
- (uint64_t)data.GetByteSize());
- Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES));
- if (log)
- log->Printf("DWARFDebugPubnames::Extract (byte_size = %" PRIu64 ")",
- (uint64_t)data.GetByteSize());
-
- if (data.ValidOffset(0)) {
- lldb::offset_t offset = 0;
-
- DWARFDebugPubnamesSet set;
- while (data.ValidOffset(offset)) {
- if (set.Extract(data, &offset)) {
- m_sets.push_back(set);
- offset = set.GetOffsetOfNextEntry();
- } else
- break;
- }
- if (log)
- Dump(log);
- return true;
- }
- return false;
-}
-
-bool DWARFDebugPubnames::GeneratePubnames(SymbolFileDWARF *dwarf2Data) {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat,
- "DWARFDebugPubnames::GeneratePubnames (data = %p)",
- static_cast<void *>(dwarf2Data));
-
- Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES));
- if (log)
- log->Printf("DWARFDebugPubnames::GeneratePubnames (data = %p)",
- static_cast<void *>(dwarf2Data));
-
- m_sets.clear();
- DWARFDebugInfo *debug_info = dwarf2Data->DebugInfo();
- if (debug_info) {
- uint32_t cu_idx = 0;
- const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits();
- for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
-
- DWARFCompileUnit *cu = debug_info->GetCompileUnitAtIndex(cu_idx);
-
- DWARFFormValue::FixedFormSizes fixed_form_sizes =
- DWARFFormValue::GetFixedFormSizesForAddressSize(
- cu->GetAddressByteSize(), cu->IsDWARF64());
-
- bool clear_dies = cu->ExtractDIEsIfNeeded(false) > 1;
-
- DWARFDIECollection dies;
- const size_t die_count = cu->AppendDIEsWithTag(DW_TAG_subprogram, dies) +
- cu->AppendDIEsWithTag(DW_TAG_variable, dies);
-
- dw_offset_t cu_offset = cu->GetOffset();
- DWARFDebugPubnamesSet pubnames_set(DW_INVALID_OFFSET, cu_offset,
- cu->GetNextCompileUnitOffset() -
- cu_offset);
-
- size_t die_idx;
- for (die_idx = 0; die_idx < die_count; ++die_idx) {
- DWARFDIE die = dies.GetDIEAtIndex(die_idx);
- DWARFAttributes attributes;
- const char *name = NULL;
- const char *mangled = NULL;
- bool add_die = false;
- const size_t num_attributes = die.GetDIE()->GetAttributes(
- die.GetCU(), fixed_form_sizes, attributes);
- if (num_attributes > 0) {
- uint32_t i;
-
- dw_tag_t tag = die.Tag();
-
- for (i = 0; i < num_attributes; ++i) {
- dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
- switch (attr) {
- case DW_AT_name:
- if (attributes.ExtractFormValueAtIndex(i, form_value))
- name = form_value.AsCString();
- break;
-
- case DW_AT_MIPS_linkage_name:
- case DW_AT_linkage_name:
- if (attributes.ExtractFormValueAtIndex(i, form_value))
- mangled = form_value.AsCString();
- break;
-
- case DW_AT_low_pc:
- case DW_AT_ranges:
- case DW_AT_entry_pc:
- if (tag == DW_TAG_subprogram)
- add_die = true;
- break;
-
- case DW_AT_location:
- if (tag == DW_TAG_variable) {
- DWARFDIE parent_die = die.GetParent();
- while (parent_die) {
- switch (parent_die.Tag()) {
- case DW_TAG_subprogram:
- case DW_TAG_lexical_block:
- case DW_TAG_inlined_subroutine:
- // Even if this is a function level static, we don't add it.
- // We could theoretically
- // add these if we wanted to by introspecting into the
- // DW_AT_location and seeing
- // if the location describes a hard coded address, but we
- // don't want the performance
- // penalty of that right now.
- add_die = false;
- parent_die.Clear(); // Terminate the while loop.
- break;
-
- case DW_TAG_compile_unit:
- add_die = true;
- parent_die.Clear(); // Terminate the while loop.
- break;
-
- default:
- parent_die =
- parent_die.GetParent(); // Keep going in the while loop.
- break;
- }
- }
- }
- break;
- }
- }
- }
-
- if (add_die && (name || mangled)) {
- pubnames_set.AddDescriptor(die.GetCompileUnitRelativeOffset(),
- mangled ? mangled : name);
- }
- }
-
- if (pubnames_set.NumDescriptors() > 0) {
- m_sets.push_back(pubnames_set);
- }
-
- // Keep memory down by clearing DIEs if this generate function
- // caused them to be parsed
- if (clear_dies)
- cu->ClearDIEs(true);
- }
- }
- if (m_sets.empty())
- return false;
- if (log)
- Dump(log);
- return true;
-}
-
-bool DWARFDebugPubnames::GeneratePubBaseTypes(SymbolFileDWARF *dwarf2Data) {
- m_sets.clear();
- DWARFDebugInfo *debug_info = dwarf2Data->DebugInfo();
- if (debug_info) {
- uint32_t cu_idx = 0;
- const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits();
- for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
- DWARFCompileUnit *cu = debug_info->GetCompileUnitAtIndex(cu_idx);
- DWARFDIECollection dies;
- const size_t die_count = cu->AppendDIEsWithTag(DW_TAG_base_type, dies);
- dw_offset_t cu_offset = cu->GetOffset();
- DWARFDebugPubnamesSet pubnames_set(DW_INVALID_OFFSET, cu_offset,
- cu->GetNextCompileUnitOffset() -
- cu_offset);
-
- size_t die_idx;
- for (die_idx = 0; die_idx < die_count; ++die_idx) {
- DWARFDIE die = dies.GetDIEAtIndex(die_idx);
- const char *name = die.GetName();
-
- if (name)
- pubnames_set.AddDescriptor(die.GetCompileUnitRelativeOffset(), name);
- }
-
- if (pubnames_set.NumDescriptors() > 0) {
- m_sets.push_back(pubnames_set);
- }
- }
- }
- return !m_sets.empty();
-}
-
-void DWARFDebugPubnames::Dump(Log *s) const {
- if (m_sets.empty())
- s->PutCString("< EMPTY >\n");
- else {
- const_iterator pos;
- const_iterator end = m_sets.end();
-
- for (pos = m_sets.begin(); pos != end; ++pos)
- (*pos).Dump(s);
- }
-}
-
-bool DWARFDebugPubnames::Find(const char *name, bool ignore_case,
- std::vector<dw_offset_t> &die_offsets) const {
- const_iterator pos;
- const_iterator end = m_sets.end();
-
- die_offsets.clear();
-
- for (pos = m_sets.begin(); pos != end; ++pos) {
- (*pos).Find(name, ignore_case, die_offsets);
- }
-
- return !die_offsets.empty();
-}
-
-bool DWARFDebugPubnames::Find(const RegularExpression &regex,
- std::vector<dw_offset_t> &die_offsets) const {
- const_iterator pos;
- const_iterator end = m_sets.end();
-
- die_offsets.clear();
-
- for (pos = m_sets.begin(); pos != end; ++pos) {
- (*pos).Find(regex, die_offsets);
- }
-
- return !die_offsets.empty();
-}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h
deleted file mode 100644
index 57dabade012c..000000000000
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h
+++ /dev/null
@@ -1,40 +0,0 @@
-//===-- DWARFDebugPubnames.h ------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SymbolFileDWARF_DWARFDebugPubnames_h_
-#define SymbolFileDWARF_DWARFDebugPubnames_h_
-
-#include "SymbolFileDWARF.h"
-
-#include <list>
-
-#include "DWARFDebugPubnamesSet.h"
-
-class DWARFDebugPubnames {
-public:
- DWARFDebugPubnames();
- bool Extract(const lldb_private::DWARFDataExtractor &data);
- bool GeneratePubnames(SymbolFileDWARF *dwarf2Data);
- bool GeneratePubBaseTypes(SymbolFileDWARF *dwarf2Data);
-
- void Dump(lldb_private::Log *s) const;
- bool Find(const char *name, bool ignore_case,
- std::vector<dw_offset_t> &die_offset_coll) const;
- bool Find(const lldb_private::RegularExpression &regex,
- std::vector<dw_offset_t> &die_offsets) const;
-
-protected:
- typedef std::list<DWARFDebugPubnamesSet> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
-
- collection m_sets;
-};
-
-#endif // SymbolFileDWARF_DWARFDebugPubnames_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp
deleted file mode 100644
index 21e2482783a1..000000000000
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-//===-- DWARFDebugPubnamesSet.cpp -------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DWARFDebugPubnamesSet.h"
-
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/RegularExpression.h"
-
-#include "SymbolFileDWARF.h"
-
-using namespace lldb_private;
-
-DWARFDebugPubnamesSet::DWARFDebugPubnamesSet()
- : m_offset(DW_INVALID_OFFSET), m_header(), m_descriptors(),
- m_name_to_descriptor_index() {}
-
-DWARFDebugPubnamesSet::DWARFDebugPubnamesSet(dw_offset_t debug_aranges_offset,
- dw_offset_t cu_die_offset,
- dw_offset_t cu_die_length)
- : m_offset(debug_aranges_offset), m_header(), m_descriptors(),
- m_name_to_descriptor_index() {
- m_header.length =
- 10; // set the length to only include the header right for now
- m_header.version = 2; // The DWARF version number
- m_header.die_offset = cu_die_offset; // compile unit .debug_info offset
- m_header.die_length = cu_die_length; // compile unit .debug_info length
-}
-
-void DWARFDebugPubnamesSet::AddDescriptor(dw_offset_t cu_rel_offset,
- const char *name) {
- if (name && name[0]) {
- // Adjust our header length
- m_header.length += strlen(name) + 1 + sizeof(dw_offset_t);
- Descriptor pubnameDesc(cu_rel_offset, name);
- m_descriptors.push_back(pubnameDesc);
- }
-}
-
-void DWARFDebugPubnamesSet::Clear() {
- m_offset = DW_INVALID_OFFSET;
- m_header.length = 10;
- m_header.version = 2;
- m_header.die_offset = DW_INVALID_OFFSET;
- m_header.die_length = 0;
- m_descriptors.clear();
-}
-
-//----------------------------------------------------------------------
-// InitNameIndexes
-//----------------------------------------------------------------------
-void DWARFDebugPubnamesSet::InitNameIndexes() const {
- // Create the name index vector to be able to quickly search by name
- const size_t count = m_descriptors.size();
- for (uint32_t idx = 0; idx < count; ++idx) {
- const char *name = m_descriptors[idx].name.c_str();
- if (name && name[0])
- m_name_to_descriptor_index.insert(
- cstr_to_index_mmap::value_type(name, idx));
- }
-}
-
-bool DWARFDebugPubnamesSet::Extract(const DWARFDataExtractor &data,
- lldb::offset_t *offset_ptr) {
- if (data.ValidOffset(*offset_ptr)) {
- m_descriptors.clear();
- m_offset = *offset_ptr;
- m_header.length = data.GetDWARFInitialLength(offset_ptr);
- m_header.version = data.GetU16(offset_ptr);
- m_header.die_offset = data.GetDWARFOffset(offset_ptr);
- m_header.die_length = data.GetDWARFOffset(offset_ptr);
-
- Descriptor pubnameDesc;
- while (data.ValidOffset(*offset_ptr)) {
- pubnameDesc.offset = data.GetDWARFOffset(offset_ptr);
-
- if (pubnameDesc.offset) {
- const char *name = data.GetCStr(offset_ptr);
- if (name && name[0]) {
- pubnameDesc.name = name;
- m_descriptors.push_back(pubnameDesc);
- }
- } else
- break; // We are done if we get a zero 4 byte offset
- }
-
- return !m_descriptors.empty();
- }
- return false;
-}
-
-dw_offset_t DWARFDebugPubnamesSet::GetOffsetOfNextEntry() const {
- return m_offset + m_header.length + 4;
-}
-
-void DWARFDebugPubnamesSet::Dump(Log *log) const {
- log->Printf("Pubnames Header: length = 0x%8.8x, version = 0x%4.4x, "
- "die_offset = 0x%8.8x, die_length = 0x%8.8x",
- m_header.length, m_header.version, m_header.die_offset,
- m_header.die_length);
-
- bool verbose = log->GetVerbose();
-
- DescriptorConstIter pos;
- DescriptorConstIter end = m_descriptors.end();
- for (pos = m_descriptors.begin(); pos != end; ++pos) {
- if (verbose)
- log->Printf("0x%8.8x + 0x%8.8x = 0x%8.8x: %s", pos->offset,
- m_header.die_offset, pos->offset + m_header.die_offset,
- pos->name.c_str());
- else
- log->Printf("0x%8.8x: %s", pos->offset + m_header.die_offset,
- pos->name.c_str());
- }
-}
-
-void DWARFDebugPubnamesSet::Find(
- const char *name, bool ignore_case,
- std::vector<dw_offset_t> &die_offset_coll) const {
- if (!m_descriptors.empty() && m_name_to_descriptor_index.empty())
- InitNameIndexes();
-
- std::pair<cstr_to_index_mmap::const_iterator,
- cstr_to_index_mmap::const_iterator>
- range(m_name_to_descriptor_index.equal_range(name));
- for (cstr_to_index_mmap::const_iterator pos = range.first;
- pos != range.second; ++pos)
- die_offset_coll.push_back(m_header.die_offset +
- m_descriptors[(*pos).second].offset);
-}
-
-void DWARFDebugPubnamesSet::Find(
- const RegularExpression &regex,
- std::vector<dw_offset_t> &die_offset_coll) const {
- DescriptorConstIter pos;
- DescriptorConstIter end = m_descriptors.end();
- for (pos = m_descriptors.begin(); pos != end; ++pos) {
- if (regex.Execute(pos->name))
- die_offset_coll.push_back(m_header.die_offset + pos->offset);
- }
-}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h
deleted file mode 100644
index 6e7d3f38aa85..000000000000
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h
+++ /dev/null
@@ -1,95 +0,0 @@
-//===-- DWARFDebugPubnamesSet.h ---------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SymbolFileDWARF_DWARFDebugPubnamesSet_h_
-#define SymbolFileDWARF_DWARFDebugPubnamesSet_h_
-
-#include "SymbolFileDWARF.h"
-#include <map>
-#include <string>
-#include <vector>
-#if __cplusplus >= 201103L || defined(_MSC_VER)
-#include <unordered_map>
-#else
-#include <ext/hash_map>
-#endif
-
-#include "lldb/Core/STLUtils.h"
-
-class DWARFDebugPubnamesSet {
-public:
- struct Header {
- uint32_t length; // length of the set of entries for this compilation unit,
- // not including the length field itself
- uint16_t version; // The DWARF version number
- uint32_t die_offset; // compile unit .debug_info offset
- uint32_t die_length; // compile unit .debug_info length
- Header()
- : length(10), version(2), die_offset(DW_INVALID_OFFSET), die_length(0) {
- }
- };
-
- struct Descriptor {
- Descriptor() : offset(), name() {}
-
- Descriptor(dw_offset_t the_offset, const char *the_name)
- : offset(the_offset), name(the_name ? the_name : "") {}
-
- dw_offset_t offset;
- std::string name;
- };
-
- DWARFDebugPubnamesSet();
- DWARFDebugPubnamesSet(dw_offset_t debug_aranges_offset,
- dw_offset_t cu_die_offset, dw_offset_t die_length);
- dw_offset_t GetOffset() const { return m_offset; }
- void SetOffset(dw_offset_t offset) { m_offset = offset; }
- DWARFDebugPubnamesSet::Header &GetHeader() { return m_header; }
- const DWARFDebugPubnamesSet::Header &GetHeader() const { return m_header; }
- const DWARFDebugPubnamesSet::Descriptor *GetDescriptor(uint32_t i) const {
- if (i < m_descriptors.size())
- return &m_descriptors[i];
- return NULL;
- }
- uint32_t NumDescriptors() const { return m_descriptors.size(); }
- void AddDescriptor(dw_offset_t cu_rel_offset, const char *name);
- void Clear();
- bool Extract(const lldb_private::DWARFDataExtractor &debug_pubnames_data,
- lldb::offset_t *offset_ptr);
- void Dump(lldb_private::Log *s) const;
- void InitNameIndexes() const;
- void Find(const char *name, bool ignore_case,
- std::vector<dw_offset_t> &die_offset_coll) const;
- void Find(const lldb_private::RegularExpression &regex,
- std::vector<dw_offset_t> &die_offsets) const;
- dw_offset_t GetOffsetOfNextEntry() const;
-
-protected:
- typedef std::vector<Descriptor> DescriptorColl;
- typedef DescriptorColl::iterator DescriptorIter;
- typedef DescriptorColl::const_iterator DescriptorConstIter;
-
- dw_offset_t m_offset;
- Header m_header;
-#if __cplusplus >= 201103L || defined(_MSC_VER)
- typedef std::unordered_multimap<const char *, uint32_t,
- std::hash<const char *>,
- CStringEqualBinaryPredicate>
- cstr_to_index_mmap;
-#else
- typedef __gnu_cxx::hash_multimap<const char *, uint32_t,
- __gnu_cxx::hash<const char *>,
- CStringEqualBinaryPredicate>
- cstr_to_index_mmap;
-#endif
- DescriptorColl m_descriptors;
- mutable cstr_to_index_mmap m_name_to_descriptor_index;
-};
-
-#endif // SymbolFileDWARF_DWARFDebugPubnamesSet_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
index a8c48b7f2f84..89e27efb3cc2 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
@@ -89,8 +89,8 @@ void DWARFDebugRanges::Dump(Stream &s,
debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) {
dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
- // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits
- // of ones
+ // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits of
+ // ones
if (begin == 0xFFFFFFFFull && addr_size == 4)
begin = LLDB_INVALID_ADDRESS;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp
index 79f2f221696b..dbaf0b0ed127 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp
@@ -67,8 +67,8 @@ bool DWARFDeclContext::operator==(const DWARFDeclContext &rhs) const {
// First compare the tags before we do expensive name compares
for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos) {
if (pos->tag != rhs_pos->tag) {
- // Check for DW_TAG_structure_type and DW_TAG_class_type as they are often
- // used interchangeably in GCC
+ // Check for DW_TAG_structure_type and DW_TAG_class_type as they are
+ // often used interchangeably in GCC
if (pos->tag == DW_TAG_structure_type &&
rhs_pos->tag == DW_TAG_class_type)
continue;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
index 2ff0fe3aac41..1d927ba3bca3 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
@@ -473,16 +473,6 @@ const char *DW_ORD_value_to_name(uint32_t val) {
return llvmstr.data();
}
-const char *DW_DSC_value_to_name(uint32_t val) {
- static char invalid[100];
- llvm::StringRef llvmstr = llvm::dwarf::DiscriminantString(val);
- if (llvmstr.empty()) {
- snprintf(invalid, sizeof(invalid), "Unknown DW_DSC constant: 0x%x", val);
- return invalid;
- }
- return llvmstr.data();
-}
-
const char *DW_LNS_value_to_name(uint32_t val) {
static char invalid[100];
llvm::StringRef llvmstr = llvm::dwarf::LNStandardString(val);
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDefines.h b/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
index 038f5706c060..926f83b3564a 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
@@ -58,8 +58,6 @@ const char *DW_INL_value_to_name(uint32_t val);
const char *DW_ORD_value_to_name(uint32_t val);
-const char *DW_DSC_value_to_name(uint32_t val);
-
const char *DW_LNS_value_to_name(uint32_t val);
const char *DW_LNE_value_to_name(uint32_t val);
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
index a21e313c2f81..4fde5748d3f3 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -12,10 +12,10 @@
#include "lldb/Core/dwarf.h"
#include "lldb/Utility/Stream.h"
-#include "DWARFCompileUnit.h"
+#include "DWARFUnit.h"
#include "DWARFFormValue.h"
-class DWARFCompileUnit;
+class DWARFUnit;
using namespace lldb_private;
@@ -154,7 +154,7 @@ DWARFFormValue::GetFixedFormSizesForAddressSize(uint8_t addr_size,
DWARFFormValue::DWARFFormValue() : m_cu(NULL), m_form(0), m_value() {}
-DWARFFormValue::DWARFFormValue(const DWARFCompileUnit *cu, dw_form_t form)
+DWARFFormValue::DWARFFormValue(const DWARFUnit *cu, dw_form_t form)
: m_cu(cu), m_form(form), m_value() {}
void DWARFFormValue::Clear() {
@@ -177,7 +177,7 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
case DW_FORM_addr:
assert(m_cu);
m_value.value.uval = data.GetMaxU64(
- offset_ptr, DWARFCompileUnit::GetAddressByteSize(m_cu));
+ offset_ptr, DWARFUnit::GetAddressByteSize(m_cu));
break;
case DW_FORM_block2:
m_value.value.uval = data.GetU16(offset_ptr);
@@ -220,7 +220,7 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
case DW_FORM_strp:
assert(m_cu);
m_value.value.uval =
- data.GetMaxU64(offset_ptr, DWARFCompileUnit::IsDWARF64(m_cu) ? 8 : 4);
+ data.GetMaxU64(offset_ptr, DWARFUnit::IsDWARF64(m_cu) ? 8 : 4);
break;
// case DW_FORM_APPLE_db_str:
case DW_FORM_udata:
@@ -258,7 +258,7 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
case DW_FORM_sec_offset:
assert(m_cu);
m_value.value.uval =
- data.GetMaxU64(offset_ptr, DWARFCompileUnit::IsDWARF64(m_cu) ? 8 : 4);
+ data.GetMaxU64(offset_ptr, DWARFUnit::IsDWARF64(m_cu) ? 8 : 4);
break;
case DW_FORM_flag_present:
m_value.value.uval = 1;
@@ -296,11 +296,11 @@ bool DWARFFormValue::SkipValue(const DWARFDataExtractor &debug_info_data,
bool DWARFFormValue::SkipValue(dw_form_t form,
const DWARFDataExtractor &debug_info_data,
lldb::offset_t *offset_ptr,
- const DWARFCompileUnit *cu) {
+ const DWARFUnit *cu) {
uint8_t ref_addr_size;
switch (form) {
- // Blocks if inlined data that have a length field and the data bytes
- // inlined in the .debug_info
+ // Blocks if inlined data that have a length field and the data bytes inlined
+ // in the .debug_info
case DW_FORM_exprloc:
case DW_FORM_block: {
dw_uleb128_t size = debug_info_data.GetULEB128(offset_ptr);
@@ -330,7 +330,7 @@ bool DWARFFormValue::SkipValue(dw_form_t form,
// Compile unit address sized values
case DW_FORM_addr:
- *offset_ptr += DWARFCompileUnit::GetAddressByteSize(cu);
+ *offset_ptr += DWARFUnit::GetAddressByteSize(cu);
return true;
case DW_FORM_ref_addr:
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
index 2aa7460c4910..ef1a693b37c9 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
@@ -13,7 +13,7 @@
#include "DWARFDataExtractor.h"
#include <stddef.h> // for NULL
-class DWARFCompileUnit;
+class DWARFUnit;
class DWARFFormValue {
public:
@@ -55,9 +55,9 @@ public:
};
DWARFFormValue();
- DWARFFormValue(const DWARFCompileUnit *cu, dw_form_t form);
- const DWARFCompileUnit *GetCompileUnit() const { return m_cu; }
- void SetCompileUnit(const DWARFCompileUnit *cu) { m_cu = cu; }
+ DWARFFormValue(const DWARFUnit *cu, dw_form_t form);
+ const DWARFUnit *GetCompileUnit() const { return m_cu; }
+ void SetCompileUnit(const DWARFUnit *cu) { m_cu = cu; }
dw_form_t Form() const { return m_form; }
void SetForm(dw_form_t form) { m_form = form; }
const ValueType &Value() const { return m_value; }
@@ -79,7 +79,7 @@ public:
lldb::offset_t *offset_ptr) const;
static bool SkipValue(const dw_form_t form,
const lldb_private::DWARFDataExtractor &debug_info_data,
- lldb::offset_t *offset_ptr, const DWARFCompileUnit *cu);
+ lldb::offset_t *offset_ptr, const DWARFUnit *cu);
static bool IsBlockForm(const dw_form_t form);
static bool IsDataForm(const dw_form_t form);
static FixedFormSizes GetFixedFormSizesForAddressSize(uint8_t addr_size,
@@ -89,7 +89,7 @@ public:
static bool FormIsSupported(dw_form_t form);
protected:
- const DWARFCompileUnit *m_cu; // Compile unit for this form
+ const DWARFUnit *m_cu; // Compile unit for this form
dw_form_t m_form; // Form for this value
ValueType m_value; // Contains all data for the form
};
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp b/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
new file mode 100644
index 000000000000..4577f0557a1d
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
@@ -0,0 +1,68 @@
+//===-- DWARFIndex.cpp -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/SymbolFile/DWARF/DWARFIndex.h"
+#include "Plugins/SymbolFile/DWARF/DWARFDIE.h"
+#include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
+
+#include "Plugins/Language/ObjC/ObjCLanguage.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+DWARFIndex::~DWARFIndex() = default;
+
+void DWARFIndex::ProcessFunctionDIE(llvm::StringRef name, DIERef ref,
+ DWARFDebugInfo &info,
+ const CompilerDeclContext &parent_decl_ctx,
+ uint32_t name_type_mask,
+ std::vector<DWARFDIE> &dies) {
+ DWARFDIE die = info.GetDIE(ref);
+ if (!die) {
+ ReportInvalidDIEOffset(ref.die_offset, name);
+ return;
+ }
+
+ // Exit early if we're searching exclusively for methods or selectors and
+ // we have a context specified (no methods in namespaces).
+ uint32_t looking_for_nonmethods =
+ name_type_mask & ~(eFunctionNameTypeMethod | eFunctionNameTypeSelector);
+ if (!looking_for_nonmethods && parent_decl_ctx.IsValid())
+ return;
+
+ // Otherwise, we need to also check that the context matches. If it does not
+ // match, we do nothing.
+ if (!SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die))
+ return;
+
+ // In case of a full match, we just insert everything we find.
+ if (name_type_mask & eFunctionNameTypeFull) {
+ dies.push_back(die);
+ return;
+ }
+
+ // If looking for ObjC selectors, we need to also check if the name is a
+ // possible selector.
+ if (name_type_mask & eFunctionNameTypeSelector &&
+ ObjCLanguage::IsPossibleObjCMethodName(die.GetName())) {
+ dies.push_back(die);
+ return;
+ }
+
+ bool looking_for_methods = name_type_mask & lldb::eFunctionNameTypeMethod;
+ bool looking_for_functions = name_type_mask & lldb::eFunctionNameTypeBase;
+ if (looking_for_methods || looking_for_functions) {
+ // If we're looking for either methods or functions, we definitely want this
+ // die. Otherwise, only keep it if the die type matches what we are
+ // searching for.
+ if ((looking_for_methods && looking_for_functions) ||
+ looking_for_methods == die.IsMethod())
+ dies.push_back(die);
+ }
+}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFIndex.h b/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
new file mode 100644
index 000000000000..77af67b8e60f
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
@@ -0,0 +1,69 @@
+//===-- DWARFIndex.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_DWARFINDEX_H
+#define LLDB_DWARFINDEX_H
+
+#include "Plugins/SymbolFile/DWARF/DIERef.h"
+#include "Plugins/SymbolFile/DWARF/DWARFDIE.h"
+#include "Plugins/SymbolFile/DWARF/DWARFFormValue.h"
+
+class DWARFDebugInfo;
+class DWARFDeclContext;
+class DWARFDIE;
+
+namespace lldb_private {
+class DWARFIndex {
+public:
+ DWARFIndex(Module &module) : m_module(module) {}
+ virtual ~DWARFIndex();
+
+ virtual void Preload() = 0;
+
+ /// Finds global variables with the given base name. Any additional filtering
+ /// (e.g., to only retrieve variables from a given context) should be done by
+ /// the consumer.
+ virtual void GetGlobalVariables(ConstString basename, DIEArray &offsets) = 0;
+
+ virtual void GetGlobalVariables(const RegularExpression &regex,
+ DIEArray &offsets) = 0;
+ virtual void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) = 0;
+ virtual void GetObjCMethods(ConstString class_name, DIEArray &offsets) = 0;
+ virtual void GetCompleteObjCClass(ConstString class_name,
+ bool must_be_implementation,
+ DIEArray &offsets) = 0;
+ virtual void GetTypes(ConstString name, DIEArray &offsets) = 0;
+ virtual void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) = 0;
+ virtual void GetNamespaces(ConstString name, DIEArray &offsets) = 0;
+ virtual void GetFunctions(ConstString name, DWARFDebugInfo &info,
+ const CompilerDeclContext &parent_decl_ctx,
+ uint32_t name_type_mask,
+ std::vector<DWARFDIE> &dies) = 0;
+ virtual void GetFunctions(const RegularExpression &regex,
+ DIEArray &offsets) = 0;
+
+ virtual void ReportInvalidDIEOffset(dw_offset_t offset,
+ llvm::StringRef name) = 0;
+ virtual void Dump(Stream &s) = 0;
+
+protected:
+ Module &m_module;
+
+ /// Helper function implementing common logic for processing function dies. If
+ /// the function given by "ref" matches search criteria given by
+ /// "parent_decl_ctx" and "name_type_mask", it is inserted into the "dies"
+ /// vector.
+ void ProcessFunctionDIE(llvm::StringRef name, DIERef ref,
+ DWARFDebugInfo &info,
+ const CompilerDeclContext &parent_decl_ctx,
+ uint32_t name_type_mask, std::vector<DWARFDIE> &dies);
+};
+} // namespace lldb_private
+
+#endif // LLDB_DWARFINDEX_H
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
new file mode 100644
index 000000000000..f44b2bb97b2b
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -0,0 +1,755 @@
+//===-- DWARFUnit.cpp -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFUnit.h"
+
+#include "lldb/Core/Module.h"
+#include "lldb/Host/StringConvert.h"
+#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/LineTable.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/Utility/StreamString.h"
+#include "lldb/Utility/Timer.h"
+
+#include "DWARFDIECollection.h"
+#include "DWARFDebugAranges.h"
+#include "DWARFDebugInfo.h"
+#include "LogChannelDWARF.h"
+#include "SymbolFileDWARFDebugMap.h"
+#include "SymbolFileDWARFDwo.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace std;
+
+extern int g_verbose;
+
+DWARFUnit::DWARFUnit(SymbolFileDWARF *dwarf)
+ : m_dwarf(dwarf), m_cancel_scopes(false) {}
+
+DWARFUnit::~DWARFUnit() {}
+
+//----------------------------------------------------------------------
+// Parses first DIE of a compile unit.
+//----------------------------------------------------------------------
+void DWARFUnit::ExtractUnitDIEIfNeeded() {
+ {
+ llvm::sys::ScopedReader lock(m_first_die_mutex);
+ if (m_first_die)
+ return; // Already parsed
+ }
+ llvm::sys::ScopedWriter lock(m_first_die_mutex);
+ if (m_first_die)
+ return; // Already parsed
+
+ static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
+ Timer scoped_timer(
+ func_cat, "%8.8x: DWARFUnit::ExtractUnitDIEIfNeeded()", m_offset);
+
+ // Set the offset to that of the first DIE and calculate the start of the
+ // next compilation unit header.
+ lldb::offset_t offset = GetFirstDIEOffset();
+
+ // We are in our compile unit, parse starting at the offset we were told to
+ // parse
+ const DWARFDataExtractor &data = GetData();
+ DWARFFormValue::FixedFormSizes fixed_form_sizes =
+ DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(),
+ IsDWARF64());
+ if (offset < GetNextCompileUnitOffset() &&
+ m_first_die.FastExtract(data, this, fixed_form_sizes, &offset)) {
+ AddUnitDIE(m_first_die);
+ return;
+ }
+
+ ExtractDIEsEndCheck(offset);
+}
+
+//----------------------------------------------------------------------
+// Parses a compile unit and indexes its DIEs if it hasn't already been done.
+// It will leave this compile unit extracted forever.
+//----------------------------------------------------------------------
+void DWARFUnit::ExtractDIEsIfNeeded() {
+ m_cancel_scopes = true;
+
+ {
+ llvm::sys::ScopedReader lock(m_die_array_mutex);
+ if (!m_die_array.empty())
+ return; // Already parsed
+ }
+ llvm::sys::ScopedWriter lock(m_die_array_mutex);
+ if (!m_die_array.empty())
+ return; // Already parsed
+
+ ExtractDIEsRWLocked();
+}
+
+//----------------------------------------------------------------------
+// Parses a compile unit and indexes its DIEs if it hasn't already been done.
+// It will clear this compile unit after returned instance gets out of scope,
+// no other ScopedExtractDIEs instance is running for this compile unit
+// and no ExtractDIEsIfNeeded() has been executed during this ScopedExtractDIEs
+// lifetime.
+//----------------------------------------------------------------------
+DWARFUnit::ScopedExtractDIEs DWARFUnit::ExtractDIEsScoped() {
+ ScopedExtractDIEs scoped(this);
+
+ {
+ llvm::sys::ScopedReader lock(m_die_array_mutex);
+ if (!m_die_array.empty())
+ return scoped; // Already parsed
+ }
+ llvm::sys::ScopedWriter lock(m_die_array_mutex);
+ if (!m_die_array.empty())
+ return scoped; // Already parsed
+
+ // Otherwise m_die_array would be already populated.
+ lldbassert(!m_cancel_scopes);
+
+ ExtractDIEsRWLocked();
+ scoped.m_clear_dies = true;
+ return scoped;
+}
+
+DWARFUnit::ScopedExtractDIEs::ScopedExtractDIEs(DWARFUnit *cu) : m_cu(cu) {
+ lldbassert(m_cu);
+ m_cu->m_die_array_scoped_mutex.lock_shared();
+}
+
+DWARFUnit::ScopedExtractDIEs::~ScopedExtractDIEs() {
+ if (!m_cu)
+ return;
+ m_cu->m_die_array_scoped_mutex.unlock_shared();
+ if (!m_clear_dies || m_cu->m_cancel_scopes)
+ return;
+ // Be sure no other ScopedExtractDIEs is running anymore.
+ llvm::sys::ScopedWriter lock_scoped(m_cu->m_die_array_scoped_mutex);
+ llvm::sys::ScopedWriter lock(m_cu->m_die_array_mutex);
+ if (m_cu->m_cancel_scopes)
+ return;
+ m_cu->ClearDIEsRWLocked();
+}
+
+DWARFUnit::ScopedExtractDIEs::ScopedExtractDIEs(ScopedExtractDIEs &&rhs)
+ : m_cu(rhs.m_cu), m_clear_dies(rhs.m_clear_dies) {
+ rhs.m_cu = nullptr;
+}
+
+DWARFUnit::ScopedExtractDIEs &DWARFUnit::ScopedExtractDIEs::operator=(
+ DWARFUnit::ScopedExtractDIEs &&rhs) {
+ m_cu = rhs.m_cu;
+ rhs.m_cu = nullptr;
+ m_clear_dies = rhs.m_clear_dies;
+ return *this;
+}
+
+//----------------------------------------------------------------------
+// Parses a compile unit and indexes its DIEs, m_die_array_mutex must be
+// held R/W and m_die_array must be empty.
+//----------------------------------------------------------------------
+void DWARFUnit::ExtractDIEsRWLocked() {
+ llvm::sys::ScopedWriter first_die_lock(m_first_die_mutex);
+
+ static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
+ Timer scoped_timer(
+ func_cat, "%8.8x: DWARFUnit::ExtractDIEsIfNeeded()", m_offset);
+
+ // Set the offset to that of the first DIE and calculate the start of the
+ // next compilation unit header.
+ lldb::offset_t offset = GetFirstDIEOffset();
+ lldb::offset_t next_cu_offset = GetNextCompileUnitOffset();
+
+ DWARFDebugInfoEntry die;
+ // Keep a flat array of the DIE for binary lookup by DIE offset
+ Log *log(
+ LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_LOOKUPS));
+ if (log) {
+ m_dwarf->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
+ log,
+ "DWARFUnit::ExtractDIEsIfNeeded () for compile unit at "
+ ".debug_info[0x%8.8x]",
+ GetOffset());
+ }
+
+ uint32_t depth = 0;
+ // We are in our compile unit, parse starting at the offset we were told to
+ // parse
+ const DWARFDataExtractor &data = GetData();
+ std::vector<uint32_t> die_index_stack;
+ die_index_stack.reserve(32);
+ die_index_stack.push_back(0);
+ bool prev_die_had_children = false;
+ DWARFFormValue::FixedFormSizes fixed_form_sizes =
+ DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(),
+ IsDWARF64());
+ while (offset < next_cu_offset &&
+ die.FastExtract(data, this, fixed_form_sizes, &offset)) {
+ // if (log)
+ // log->Printf("0x%8.8x: %*.*s%s%s",
+ // die.GetOffset(),
+ // depth * 2, depth * 2, "",
+ // DW_TAG_value_to_name (die.Tag()),
+ // die.HasChildren() ? " *" : "");
+
+ const bool null_die = die.IsNULL();
+ if (depth == 0) {
+ assert(m_die_array.empty() && "Compile unit DIE already added");
+
+ // The average bytes per DIE entry has been seen to be around 14-20 so
+ // lets pre-reserve half of that since we are now stripping the NULL
+ // tags.
+
+ // Only reserve the memory if we are adding children of the main
+ // compile unit DIE. The compile unit DIE is always the first entry, so
+ // if our size is 1, then we are adding the first compile unit child
+ // DIE and should reserve the memory.
+ m_die_array.reserve(GetDebugInfoSize() / 24);
+ m_die_array.push_back(die);
+
+ if (!m_first_die)
+ AddUnitDIE(m_die_array.front());
+ } else {
+ if (null_die) {
+ if (prev_die_had_children) {
+ // This will only happen if a DIE says is has children but all it
+ // contains is a NULL tag. Since we are removing the NULL DIEs from
+ // the list (saves up to 25% in C++ code), we need a way to let the
+ // DIE know that it actually doesn't have children.
+ if (!m_die_array.empty())
+ m_die_array.back().SetEmptyChildren(true);
+ }
+ } else {
+ die.SetParentIndex(m_die_array.size() - die_index_stack[depth - 1]);
+
+ if (die_index_stack.back())
+ m_die_array[die_index_stack.back()].SetSiblingIndex(
+ m_die_array.size() - die_index_stack.back());
+
+ // Only push the DIE if it isn't a NULL DIE
+ m_die_array.push_back(die);
+ }
+ }
+
+ if (null_die) {
+ // NULL DIE.
+ if (!die_index_stack.empty())
+ die_index_stack.pop_back();
+
+ if (depth > 0)
+ --depth;
+ if (depth == 0)
+ break; // We are done with this compile unit!
+
+ prev_die_had_children = false;
+ } else {
+ die_index_stack.back() = m_die_array.size() - 1;
+ // Normal DIE
+ const bool die_has_children = die.HasChildren();
+ if (die_has_children) {
+ die_index_stack.push_back(0);
+ ++depth;
+ }
+ prev_die_had_children = die_has_children;
+ }
+ }
+
+ if (!m_die_array.empty()) {
+ lldbassert(!m_first_die || m_first_die == m_die_array.front());
+ m_first_die = m_die_array.front();
+ }
+
+ m_die_array.shrink_to_fit();
+
+ ExtractDIEsEndCheck(offset);
+
+ if (m_dwo_symbol_file) {
+ DWARFUnit *dwo_cu = m_dwo_symbol_file->GetCompileUnit();
+ dwo_cu->ExtractDIEsIfNeeded();
+ }
+}
+
+//--------------------------------------------------------------------------
+// Final checks for both ExtractUnitDIEIfNeeded() and ExtractDIEsIfNeeded().
+//--------------------------------------------------------------------------
+void DWARFUnit::ExtractDIEsEndCheck(lldb::offset_t offset) const {
+ // Give a little bit of info if we encounter corrupt DWARF (our offset should
+ // always terminate at or before the start of the next compilation unit
+ // header).
+ if (offset > GetNextCompileUnitOffset()) {
+ m_dwarf->GetObjectFile()->GetModule()->ReportWarning(
+ "DWARF compile unit extends beyond its bounds cu 0x%8.8x at "
+ "0x%8.8" PRIx64 "\n",
+ GetOffset(), offset);
+ }
+
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
+ if (log && log->GetVerbose()) {
+ StreamString strm;
+ Dump(&strm);
+ if (m_die_array.empty())
+ strm.Printf("error: no DIE for compile unit");
+ else
+ m_die_array[0].Dump(m_dwarf, this, strm, UINT32_MAX);
+ log->PutString(strm.GetString());
+ }
+}
+
+// m_die_array_mutex must be already held as read/write.
+void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
+ uint64_t base_addr = cu_die.GetAttributeValueAsAddress(
+ m_dwarf, this, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
+ if (base_addr == LLDB_INVALID_ADDRESS)
+ base_addr = cu_die.GetAttributeValueAsAddress(
+ m_dwarf, this, DW_AT_entry_pc, 0);
+ SetBaseAddress(base_addr);
+
+ std::unique_ptr<SymbolFileDWARFDwo> dwo_symbol_file =
+ m_dwarf->GetDwoSymbolFileForCompileUnit(*this, cu_die);
+ if (!dwo_symbol_file)
+ return;
+
+ DWARFUnit *dwo_cu = dwo_symbol_file->GetCompileUnit();
+ if (!dwo_cu)
+ return; // Can't fetch the compile unit from the dwo file.
+
+ DWARFBaseDIE dwo_cu_die = dwo_cu->GetUnitDIEOnly();
+ if (!dwo_cu_die.IsValid())
+ return; // Can't fetch the compile unit DIE from the dwo file.
+
+ uint64_t main_dwo_id =
+ cu_die.GetAttributeValueAsUnsigned(m_dwarf, this, DW_AT_GNU_dwo_id, 0);
+ uint64_t sub_dwo_id =
+ dwo_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_dwo_id, 0);
+ if (main_dwo_id != sub_dwo_id)
+ return; // The 2 dwo ID isn't match. Don't use the dwo file as it belongs to
+ // a differectn compilation.
+
+ m_dwo_symbol_file = std::move(dwo_symbol_file);
+
+ dw_addr_t addr_base =
+ cu_die.GetAttributeValueAsUnsigned(m_dwarf, this, DW_AT_GNU_addr_base, 0);
+ dw_addr_t ranges_base = cu_die.GetAttributeValueAsUnsigned(
+ m_dwarf, this, DW_AT_GNU_ranges_base, 0);
+ dwo_cu->SetAddrBase(addr_base, ranges_base, m_offset);
+}
+
+DWARFDIE DWARFUnit::LookupAddress(const dw_addr_t address) {
+ if (DIE()) {
+ const DWARFDebugAranges &func_aranges = GetFunctionAranges();
+
+ // Re-check the aranges auto pointer contents in case it was created above
+ if (!func_aranges.IsEmpty())
+ return GetDIE(func_aranges.FindAddress(address));
+ }
+ return DWARFDIE();
+}
+
+size_t DWARFUnit::AppendDIEsWithTag(const dw_tag_t tag,
+ DWARFDIECollection &dies,
+ uint32_t depth) const {
+ size_t old_size = dies.Size();
+ {
+ llvm::sys::ScopedReader lock(m_die_array_mutex);
+ DWARFDebugInfoEntry::const_iterator pos;
+ DWARFDebugInfoEntry::const_iterator end = m_die_array.end();
+ for (pos = m_die_array.begin(); pos != end; ++pos) {
+ if (pos->Tag() == tag)
+ dies.Append(DWARFDIE(this, &(*pos)));
+ }
+ }
+
+ // Return the number of DIEs added to the collection
+ return dies.Size() - old_size;
+}
+
+
+lldb::user_id_t DWARFUnit::GetID() const {
+ dw_offset_t local_id =
+ m_base_obj_offset != DW_INVALID_OFFSET ? m_base_obj_offset : m_offset;
+ if (m_dwarf)
+ return DIERef(local_id, local_id).GetUID(m_dwarf);
+ else
+ return local_id;
+}
+
+dw_offset_t DWARFUnit::GetNextCompileUnitOffset() const {
+ return m_offset + GetLengthByteSize() + GetLength();
+}
+
+size_t DWARFUnit::GetDebugInfoSize() const {
+ return GetLengthByteSize() + GetLength() - GetHeaderByteSize();
+}
+
+const DWARFAbbreviationDeclarationSet *DWARFUnit::GetAbbreviations() const {
+ return m_abbrevs;
+}
+
+dw_offset_t DWARFUnit::GetAbbrevOffset() const {
+ return m_abbrevs ? m_abbrevs->GetOffset() : DW_INVALID_OFFSET;
+}
+
+void DWARFUnit::SetAddrBase(dw_addr_t addr_base,
+ dw_addr_t ranges_base,
+ dw_offset_t base_obj_offset) {
+ m_addr_base = addr_base;
+ m_ranges_base = ranges_base;
+ m_base_obj_offset = base_obj_offset;
+}
+
+// It may be called only with m_die_array_mutex held R/W.
+void DWARFUnit::ClearDIEsRWLocked() {
+ m_die_array.clear();
+ m_die_array.shrink_to_fit();
+
+ if (m_dwo_symbol_file)
+ m_dwo_symbol_file->GetCompileUnit()->ClearDIEsRWLocked();
+}
+
+void DWARFUnit::BuildAddressRangeTable(SymbolFileDWARF *dwarf,
+ DWARFDebugAranges *debug_aranges) {
+ // This function is usually called if there in no .debug_aranges section in
+ // order to produce a compile unit level set of address ranges that is
+ // accurate.
+
+ size_t num_debug_aranges = debug_aranges->GetNumRanges();
+
+ // First get the compile unit DIE only and check if it has a DW_AT_ranges
+ const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
+
+ const dw_offset_t cu_offset = GetOffset();
+ if (die) {
+ DWARFRangeList ranges;
+ const size_t num_ranges =
+ die->GetAttributeAddressRanges(dwarf, this, ranges, false);
+ if (num_ranges > 0) {
+ // This compile unit has DW_AT_ranges, assume this is correct if it is
+ // present since clang no longer makes .debug_aranges by default and it
+ // emits DW_AT_ranges for DW_TAG_compile_units. GCC also does this with
+ // recent GCC builds.
+ for (size_t i = 0; i < num_ranges; ++i) {
+ const DWARFRangeList::Entry &range = ranges.GetEntryRef(i);
+ debug_aranges->AppendRange(cu_offset, range.GetRangeBase(),
+ range.GetRangeEnd());
+ }
+
+ return; // We got all of our ranges from the DW_AT_ranges attribute
+ }
+ }
+ // We don't have a DW_AT_ranges attribute, so we need to parse the DWARF
+
+ // If the DIEs weren't parsed, then we don't want all dies for all compile
+ // units to stay loaded when they weren't needed. So we can end up parsing
+ // the DWARF and then throwing them all away to keep memory usage down.
+ ScopedExtractDIEs clear_dies(ExtractDIEsScoped());
+
+ die = DIEPtr();
+ if (die)
+ die->BuildAddressRangeTable(dwarf, this, debug_aranges);
+
+ if (debug_aranges->GetNumRanges() == num_debug_aranges) {
+ // We got nothing from the functions, maybe we have a line tables only
+ // situation. Check the line tables and build the arange table from this.
+ SymbolContext sc;
+ sc.comp_unit = dwarf->GetCompUnitForDWARFCompUnit(this);
+ if (sc.comp_unit) {
+ SymbolFileDWARFDebugMap *debug_map_sym_file =
+ m_dwarf->GetDebugMapSymfile();
+ if (debug_map_sym_file == NULL) {
+ LineTable *line_table = sc.comp_unit->GetLineTable();
+
+ if (line_table) {
+ LineTable::FileAddressRanges file_ranges;
+ const bool append = true;
+ const size_t num_ranges =
+ line_table->GetContiguousFileAddressRanges(file_ranges, append);
+ for (uint32_t idx = 0; idx < num_ranges; ++idx) {
+ const LineTable::FileAddressRanges::Entry &range =
+ file_ranges.GetEntryRef(idx);
+ debug_aranges->AppendRange(cu_offset, range.GetRangeBase(),
+ range.GetRangeEnd());
+ }
+ }
+ } else
+ debug_map_sym_file->AddOSOARanges(dwarf, debug_aranges);
+ }
+ }
+
+ if (debug_aranges->GetNumRanges() == num_debug_aranges) {
+ // We got nothing from the functions, maybe we have a line tables only
+ // situation. Check the line tables and build the arange table from this.
+ SymbolContext sc;
+ sc.comp_unit = dwarf->GetCompUnitForDWARFCompUnit(this);
+ if (sc.comp_unit) {
+ LineTable *line_table = sc.comp_unit->GetLineTable();
+
+ if (line_table) {
+ LineTable::FileAddressRanges file_ranges;
+ const bool append = true;
+ const size_t num_ranges =
+ line_table->GetContiguousFileAddressRanges(file_ranges, append);
+ for (uint32_t idx = 0; idx < num_ranges; ++idx) {
+ const LineTable::FileAddressRanges::Entry &range =
+ file_ranges.GetEntryRef(idx);
+ debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(),
+ range.GetRangeEnd());
+ }
+ }
+ }
+ }
+}
+
+lldb::ByteOrder DWARFUnit::GetByteOrder() const {
+ return m_dwarf->GetObjectFile()->GetByteOrder();
+}
+
+TypeSystem *DWARFUnit::GetTypeSystem() {
+ if (m_dwarf)
+ return m_dwarf->GetTypeSystemForLanguage(GetLanguageType());
+ else
+ return nullptr;
+}
+
+DWARFFormValue::FixedFormSizes DWARFUnit::GetFixedFormSizes() {
+ return DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(),
+ IsDWARF64());
+}
+
+void DWARFUnit::SetBaseAddress(dw_addr_t base_addr) { m_base_addr = base_addr; }
+
+//----------------------------------------------------------------------
+// Compare function DWARFDebugAranges::Range structures
+//----------------------------------------------------------------------
+static bool CompareDIEOffset(const DWARFDebugInfoEntry &die,
+ const dw_offset_t die_offset) {
+ return die.GetOffset() < die_offset;
+}
+
+//----------------------------------------------------------------------
+// GetDIE()
+//
+// Get the DIE (Debug Information Entry) with the specified offset by first
+// checking if the DIE is contained within this compile unit and grabbing the
+// DIE from this compile unit. Otherwise we grab the DIE from the DWARF file.
+//----------------------------------------------------------------------
+DWARFDIE
+DWARFUnit::GetDIE(dw_offset_t die_offset) {
+ if (die_offset != DW_INVALID_OFFSET) {
+ if (GetDwoSymbolFile())
+ return GetDwoSymbolFile()->GetCompileUnit()->GetDIE(die_offset);
+
+ if (ContainsDIEOffset(die_offset)) {
+ ExtractDIEsIfNeeded();
+ DWARFDebugInfoEntry::const_iterator end = m_die_array.cend();
+ DWARFDebugInfoEntry::const_iterator pos =
+ lower_bound(m_die_array.cbegin(), end, die_offset, CompareDIEOffset);
+ if (pos != end) {
+ if (die_offset == (*pos).GetOffset())
+ return DWARFDIE(this, &(*pos));
+ }
+ } else {
+ // Don't specify the compile unit offset as we don't know it because the
+ // DIE belongs to
+ // a different compile unit in the same symbol file.
+ return m_dwarf->DebugInfo()->GetDIEForDIEOffset(die_offset);
+ }
+ }
+ return DWARFDIE(); // Not found
+}
+
+uint8_t DWARFUnit::GetAddressByteSize(const DWARFUnit *cu) {
+ if (cu)
+ return cu->GetAddressByteSize();
+ return DWARFUnit::GetDefaultAddressSize();
+}
+
+bool DWARFUnit::IsDWARF64(const DWARFUnit *cu) {
+ if (cu)
+ return cu->IsDWARF64();
+ return false;
+}
+
+uint8_t DWARFUnit::GetDefaultAddressSize() { return 4; }
+
+void *DWARFUnit::GetUserData() const { return m_user_data; }
+
+void DWARFUnit::SetUserData(void *d) {
+ m_user_data = d;
+ if (m_dwo_symbol_file)
+ m_dwo_symbol_file->GetCompileUnit()->SetUserData(d);
+}
+
+bool DWARFUnit::Supports_DW_AT_APPLE_objc_complete_type() {
+ if (GetProducer() == eProducerLLVMGCC)
+ return false;
+ return true;
+}
+
+bool DWARFUnit::DW_AT_decl_file_attributes_are_invalid() {
+ // llvm-gcc makes completely invalid decl file attributes and won't ever be
+ // fixed, so we need to know to ignore these.
+ return GetProducer() == eProducerLLVMGCC;
+}
+
+bool DWARFUnit::Supports_unnamed_objc_bitfields() {
+ if (GetProducer() == eProducerClang) {
+ const uint32_t major_version = GetProducerVersionMajor();
+ if (major_version > 425 ||
+ (major_version == 425 && GetProducerVersionUpdate() >= 13))
+ return true;
+ else
+ return false;
+ }
+ return true; // Assume all other compilers didn't have incorrect ObjC bitfield
+ // info
+}
+
+SymbolFileDWARF *DWARFUnit::GetSymbolFileDWARF() const { return m_dwarf; }
+
+void DWARFUnit::ParseProducerInfo() {
+ m_producer_version_major = UINT32_MAX;
+ m_producer_version_minor = UINT32_MAX;
+ m_producer_version_update = UINT32_MAX;
+
+ const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
+ if (die) {
+
+ const char *producer_cstr =
+ die->GetAttributeValueAsString(m_dwarf, this, DW_AT_producer, NULL);
+ if (producer_cstr) {
+ RegularExpression llvm_gcc_regex(
+ llvm::StringRef("^4\\.[012]\\.[01] \\(Based on Apple "
+ "Inc\\. build [0-9]+\\) \\(LLVM build "
+ "[\\.0-9]+\\)$"));
+ if (llvm_gcc_regex.Execute(llvm::StringRef(producer_cstr))) {
+ m_producer = eProducerLLVMGCC;
+ } else if (strstr(producer_cstr, "clang")) {
+ static RegularExpression g_clang_version_regex(
+ llvm::StringRef("clang-([0-9]+)\\.([0-9]+)\\.([0-9]+)"));
+ RegularExpression::Match regex_match(3);
+ if (g_clang_version_regex.Execute(llvm::StringRef(producer_cstr),
+ &regex_match)) {
+ std::string str;
+ if (regex_match.GetMatchAtIndex(producer_cstr, 1, str))
+ m_producer_version_major =
+ StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
+ if (regex_match.GetMatchAtIndex(producer_cstr, 2, str))
+ m_producer_version_minor =
+ StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
+ if (regex_match.GetMatchAtIndex(producer_cstr, 3, str))
+ m_producer_version_update =
+ StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
+ }
+ m_producer = eProducerClang;
+ } else if (strstr(producer_cstr, "GNU"))
+ m_producer = eProducerGCC;
+ }
+ }
+ if (m_producer == eProducerInvalid)
+ m_producer = eProcucerOther;
+}
+
+DWARFProducer DWARFUnit::GetProducer() {
+ if (m_producer == eProducerInvalid)
+ ParseProducerInfo();
+ return m_producer;
+}
+
+uint32_t DWARFUnit::GetProducerVersionMajor() {
+ if (m_producer_version_major == 0)
+ ParseProducerInfo();
+ return m_producer_version_major;
+}
+
+uint32_t DWARFUnit::GetProducerVersionMinor() {
+ if (m_producer_version_minor == 0)
+ ParseProducerInfo();
+ return m_producer_version_minor;
+}
+
+uint32_t DWARFUnit::GetProducerVersionUpdate() {
+ if (m_producer_version_update == 0)
+ ParseProducerInfo();
+ return m_producer_version_update;
+}
+LanguageType DWARFUnit::LanguageTypeFromDWARF(uint64_t val) {
+ // Note: user languages between lo_user and hi_user must be handled
+ // explicitly here.
+ switch (val) {
+ case DW_LANG_Mips_Assembler:
+ return eLanguageTypeMipsAssembler;
+ case DW_LANG_GOOGLE_RenderScript:
+ return eLanguageTypeExtRenderScript;
+ default:
+ return static_cast<LanguageType>(val);
+ }
+}
+
+LanguageType DWARFUnit::GetLanguageType() {
+ if (m_language_type != eLanguageTypeUnknown)
+ return m_language_type;
+
+ const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
+ if (die)
+ m_language_type = LanguageTypeFromDWARF(
+ die->GetAttributeValueAsUnsigned(m_dwarf, this, DW_AT_language, 0));
+ return m_language_type;
+}
+
+bool DWARFUnit::GetIsOptimized() {
+ if (m_is_optimized == eLazyBoolCalculate) {
+ const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
+ if (die) {
+ m_is_optimized = eLazyBoolNo;
+ if (die->GetAttributeValueAsUnsigned(m_dwarf, this, DW_AT_APPLE_optimized,
+ 0) == 1) {
+ m_is_optimized = eLazyBoolYes;
+ }
+ }
+ }
+ return m_is_optimized == eLazyBoolYes;
+}
+
+SymbolFileDWARFDwo *DWARFUnit::GetDwoSymbolFile() const {
+ return m_dwo_symbol_file.get();
+}
+
+dw_offset_t DWARFUnit::GetBaseObjOffset() const { return m_base_obj_offset; }
+
+const DWARFDebugAranges &DWARFUnit::GetFunctionAranges() {
+ if (m_func_aranges_ap.get() == NULL) {
+ m_func_aranges_ap.reset(new DWARFDebugAranges());
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES));
+
+ if (log) {
+ m_dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "DWARFUnit::GetFunctionAranges() for compile unit at "
+ ".debug_info[0x%8.8x]",
+ GetOffset());
+ }
+ const DWARFDebugInfoEntry *die = DIEPtr();
+ if (die)
+ die->BuildFunctionAddressRangeTable(m_dwarf, this,
+ m_func_aranges_ap.get());
+
+ if (m_dwo_symbol_file) {
+ DWARFUnit *dwo_cu = m_dwo_symbol_file->GetCompileUnit();
+ const DWARFDebugInfoEntry *dwo_die = dwo_cu->DIEPtr();
+ if (dwo_die)
+ dwo_die->BuildFunctionAddressRangeTable(m_dwo_symbol_file.get(), dwo_cu,
+ m_func_aranges_ap.get());
+ }
+
+ const bool minimize = false;
+ m_func_aranges_ap->Sort(minimize);
+ }
+ return *m_func_aranges_ap.get();
+}
+
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
new file mode 100644
index 000000000000..c9e48c538bc1
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -0,0 +1,252 @@
+//===-- DWARFUnit.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SymbolFileDWARF_DWARFUnit_h_
+#define SymbolFileDWARF_DWARFUnit_h_
+
+#include "DWARFDIE.h"
+#include "DWARFDebugInfoEntry.h"
+#include "lldb/lldb-enumerations.h"
+#include "llvm/Support/RWMutex.h"
+#include <atomic>
+
+class DWARFUnit;
+class DWARFCompileUnit;
+class NameToDIE;
+class SymbolFileDWARF;
+class SymbolFileDWARFDwo;
+
+typedef std::shared_ptr<DWARFUnit> DWARFUnitSP;
+
+enum DWARFProducer {
+ eProducerInvalid = 0,
+ eProducerClang,
+ eProducerGCC,
+ eProducerLLVMGCC,
+ eProcucerOther
+};
+
+class DWARFUnit {
+ friend class DWARFCompileUnit;
+
+ using die_iterator_range =
+ llvm::iterator_range<DWARFDebugInfoEntry::collection::iterator>;
+
+public:
+ virtual ~DWARFUnit();
+
+ void ExtractUnitDIEIfNeeded();
+ void ExtractDIEsIfNeeded();
+
+ class ScopedExtractDIEs {
+ DWARFUnit *m_cu;
+ public:
+ bool m_clear_dies = false;
+ ScopedExtractDIEs(DWARFUnit *cu);
+ ~ScopedExtractDIEs();
+ DISALLOW_COPY_AND_ASSIGN(ScopedExtractDIEs);
+ ScopedExtractDIEs(ScopedExtractDIEs &&rhs);
+ ScopedExtractDIEs &operator=(ScopedExtractDIEs &&rhs);
+ };
+ ScopedExtractDIEs ExtractDIEsScoped();
+
+ DWARFDIE LookupAddress(const dw_addr_t address);
+ size_t AppendDIEsWithTag(const dw_tag_t tag,
+ DWARFDIECollection &matching_dies,
+ uint32_t depth = UINT32_MAX) const;
+ bool Verify(lldb_private::Stream *s) const;
+ virtual void Dump(lldb_private::Stream *s) const = 0;
+ //------------------------------------------------------------------
+ /// Get the data that contains the DIE information for this unit.
+ ///
+ /// This will return the correct bytes that contain the data for
+ /// this DWARFUnit. It could be .debug_info or .debug_types
+ /// depending on where the data for this unit originates.
+ ///
+ /// @return
+ /// The correct data for the DIE information in this unit.
+ //------------------------------------------------------------------
+ virtual const lldb_private::DWARFDataExtractor &GetData() const = 0;
+ //------------------------------------------------------------------
+ /// Get the size in bytes of the compile unit header.
+ ///
+ /// @return
+ /// Byte size of the compile unit header
+ //------------------------------------------------------------------
+ virtual uint32_t GetHeaderByteSize() const = 0;
+ // Offset of the initial length field.
+ dw_offset_t GetOffset() const { return m_offset; }
+ lldb::user_id_t GetID() const;
+ //------------------------------------------------------------------
+ /// Get the size in bytes of the length field in the header.
+ ///
+ /// In DWARF32 this is just 4 bytes, and DWARF64 it is 12 where 4
+ /// are 0xFFFFFFFF followed by the actual 64 bit length.
+ ///
+ /// @return
+ /// Byte size of the compile unit header length field
+ //------------------------------------------------------------------
+ size_t GetLengthByteSize() const { return IsDWARF64() ? 12 : 4; }
+
+ bool ContainsDIEOffset(dw_offset_t die_offset) const {
+ return die_offset >= GetFirstDIEOffset() &&
+ die_offset < GetNextCompileUnitOffset();
+ }
+ dw_offset_t GetFirstDIEOffset() const {
+ return m_offset + GetHeaderByteSize();
+ }
+ dw_offset_t GetNextCompileUnitOffset() const;
+ // Size of the CU data (without initial length and without header).
+ size_t GetDebugInfoSize() const;
+ // Size of the CU data incl. header but without initial length.
+ uint32_t GetLength() const { return m_length; }
+ uint16_t GetVersion() const { return m_version; }
+ const DWARFAbbreviationDeclarationSet *GetAbbreviations() const;
+ dw_offset_t GetAbbrevOffset() const;
+ uint8_t GetAddressByteSize() const { return m_addr_size; }
+ dw_addr_t GetBaseAddress() const { return m_base_addr; }
+ dw_addr_t GetAddrBase() const { return m_addr_base; }
+ dw_addr_t GetRangesBase() const { return m_ranges_base; }
+ void SetAddrBase(dw_addr_t addr_base, dw_addr_t ranges_base,
+ dw_offset_t base_obj_offset);
+ void BuildAddressRangeTable(SymbolFileDWARF *dwarf,
+ DWARFDebugAranges *debug_aranges);
+
+ lldb::ByteOrder GetByteOrder() const;
+
+ lldb_private::TypeSystem *GetTypeSystem();
+
+ const DWARFDebugAranges &GetFunctionAranges();
+
+ DWARFFormValue::FixedFormSizes GetFixedFormSizes();
+
+ void SetBaseAddress(dw_addr_t base_addr);
+
+ DWARFBaseDIE GetUnitDIEOnly() { return DWARFDIE(this, GetUnitDIEPtrOnly()); }
+
+ DWARFDIE DIE() { return DWARFDIE(this, DIEPtr()); }
+
+ DWARFDIE GetDIE(dw_offset_t die_offset);
+
+ static uint8_t GetAddressByteSize(const DWARFUnit *cu);
+
+ static bool IsDWARF64(const DWARFUnit *cu);
+
+ static uint8_t GetDefaultAddressSize();
+
+ void *GetUserData() const;
+
+ void SetUserData(void *d);
+
+ bool Supports_DW_AT_APPLE_objc_complete_type();
+
+ bool DW_AT_decl_file_attributes_are_invalid();
+
+ bool Supports_unnamed_objc_bitfields();
+
+ SymbolFileDWARF *GetSymbolFileDWARF() const;
+
+ DWARFProducer GetProducer();
+
+ uint32_t GetProducerVersionMajor();
+
+ uint32_t GetProducerVersionMinor();
+
+ uint32_t GetProducerVersionUpdate();
+
+ static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val);
+
+ lldb::LanguageType GetLanguageType();
+
+ bool IsDWARF64() const { return m_is_dwarf64; }
+
+ bool GetIsOptimized();
+
+ SymbolFileDWARFDwo *GetDwoSymbolFile() const;
+
+ dw_offset_t GetBaseObjOffset() const;
+
+ die_iterator_range dies() {
+ ExtractDIEsIfNeeded();
+ return die_iterator_range(m_die_array.begin(), m_die_array.end());
+ }
+
+protected:
+ DWARFUnit(SymbolFileDWARF *dwarf);
+
+ SymbolFileDWARF *m_dwarf = nullptr;
+ std::unique_ptr<SymbolFileDWARFDwo> m_dwo_symbol_file;
+ const DWARFAbbreviationDeclarationSet *m_abbrevs = nullptr;
+ void *m_user_data = nullptr;
+ // The compile unit debug information entry item
+ DWARFDebugInfoEntry::collection m_die_array;
+ mutable llvm::sys::RWMutex m_die_array_mutex;
+ // It is used for tracking of ScopedExtractDIEs instances.
+ mutable llvm::sys::RWMutex m_die_array_scoped_mutex;
+ // ScopedExtractDIEs instances should not call ClearDIEsRWLocked()
+ // as someone called ExtractDIEsIfNeeded().
+ std::atomic<bool> m_cancel_scopes;
+ // GetUnitDIEPtrOnly() needs to return pointer to the first DIE.
+ // But the first element of m_die_array after ExtractUnitDIEIfNeeded()
+ // would possibly move in memory after later ExtractDIEsIfNeeded().
+ DWARFDebugInfoEntry m_first_die;
+ llvm::sys::RWMutex m_first_die_mutex;
+ // A table similar to the .debug_aranges table, but this one points to the
+ // exact DW_TAG_subprogram DIEs
+ std::unique_ptr<DWARFDebugAranges> m_func_aranges_ap;
+ dw_addr_t m_base_addr = 0;
+ dw_offset_t m_length = 0;
+ uint16_t m_version = 0;
+ uint8_t m_addr_size = 0;
+ DWARFProducer m_producer = eProducerInvalid;
+ uint32_t m_producer_version_major = 0;
+ uint32_t m_producer_version_minor = 0;
+ uint32_t m_producer_version_update = 0;
+ lldb::LanguageType m_language_type = lldb::eLanguageTypeUnknown;
+ bool m_is_dwarf64 = false;
+ lldb_private::LazyBool m_is_optimized = lldb_private::eLazyBoolCalculate;
+ dw_addr_t m_addr_base = 0; // Value of DW_AT_addr_base
+ dw_addr_t m_ranges_base = 0; // Value of DW_AT_ranges_base
+ // If this is a dwo compile unit this is the offset of the base compile unit
+ // in the main object file
+ dw_offset_t m_base_obj_offset = DW_INVALID_OFFSET;
+
+ // Offset of the initial length field.
+ dw_offset_t m_offset;
+
+private:
+ void ParseProducerInfo();
+ void ExtractDIEsRWLocked();
+ void ClearDIEsRWLocked();
+
+ // Get the DWARF unit DWARF debug informration entry. Parse the single DIE
+ // if needed.
+ const DWARFDebugInfoEntry *GetUnitDIEPtrOnly() {
+ ExtractUnitDIEIfNeeded();
+ // m_first_die_mutex is not required as m_first_die is never cleared.
+ if (!m_first_die)
+ return NULL;
+ return &m_first_die;
+ }
+
+ // Get all DWARF debug informration entries. Parse all DIEs if needed.
+ const DWARFDebugInfoEntry *DIEPtr() {
+ ExtractDIEsIfNeeded();
+ if (m_die_array.empty())
+ return NULL;
+ return &m_die_array[0];
+ }
+
+ void AddUnitDIE(const DWARFDebugInfoEntry &cu_die);
+ void ExtractDIEsEndCheck(lldb::offset_t offset) const;
+
+ DISALLOW_COPY_AND_ASSIGN(DWARFUnit);
+};
+
+#endif // SymbolFileDWARF_DWARFUnit_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
new file mode 100644
index 000000000000..614ff470d161
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
@@ -0,0 +1,272 @@
+//===-- DebugNamesDWARFIndex.cpp -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h"
+#include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
+#include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h"
+#include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h"
+#include "lldb/Utility/RegularExpression.h"
+#include "lldb/Utility/Stream.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+static llvm::DWARFDataExtractor ToLLVM(const DWARFDataExtractor &data) {
+ return llvm::DWARFDataExtractor(
+ llvm::StringRef(reinterpret_cast<const char *>(data.GetDataStart()),
+ data.GetByteSize()),
+ data.GetByteOrder() == eByteOrderLittle, data.GetAddressByteSize());
+}
+
+llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>>
+DebugNamesDWARFIndex::Create(Module &module, DWARFDataExtractor debug_names,
+ DWARFDataExtractor debug_str,
+ DWARFDebugInfo *debug_info) {
+ if (!debug_info) {
+ return llvm::make_error<llvm::StringError>("debug info null",
+ llvm::inconvertibleErrorCode());
+ }
+ auto index_up =
+ llvm::make_unique<DebugNames>(ToLLVM(debug_names), ToLLVM(debug_str));
+ if (llvm::Error E = index_up->extract())
+ return std::move(E);
+
+ return std::unique_ptr<DebugNamesDWARFIndex>(new DebugNamesDWARFIndex(
+ module, std::move(index_up), debug_names, debug_str, *debug_info));
+}
+
+llvm::DenseSet<dw_offset_t>
+DebugNamesDWARFIndex::GetUnits(const DebugNames &debug_names) {
+ llvm::DenseSet<dw_offset_t> result;
+ for (const DebugNames::NameIndex &ni : debug_names) {
+ for (uint32_t cu = 0; cu < ni.getCUCount(); ++cu)
+ result.insert(ni.getCUOffset(cu));
+ }
+ return result;
+}
+
+DIERef DebugNamesDWARFIndex::ToDIERef(const DebugNames::Entry &entry) {
+ llvm::Optional<uint64_t> cu_offset = entry.getCUOffset();
+ if (!cu_offset)
+ return DIERef();
+
+ DWARFUnit *cu = m_debug_info.GetCompileUnit(*cu_offset);
+ if (!cu)
+ return DIERef();
+
+ // This initializes the DWO symbol file. It's not possible for
+ // GetDwoSymbolFile to call this automatically because of mutual recursion
+ // between this and DWARFDebugInfoEntry::GetAttributeValue.
+ cu->ExtractUnitDIEIfNeeded();
+ uint64_t die_bias = cu->GetDwoSymbolFile() ? 0 : *cu_offset;
+
+ if (llvm::Optional<uint64_t> die_offset = entry.getDIEUnitOffset())
+ return DIERef(*cu_offset, die_bias + *die_offset);
+
+ return DIERef();
+}
+
+void DebugNamesDWARFIndex::Append(const DebugNames::Entry &entry,
+ DIEArray &offsets) {
+ if (DIERef ref = ToDIERef(entry))
+ offsets.push_back(ref);
+}
+
+void DebugNamesDWARFIndex::MaybeLogLookupError(llvm::Error error,
+ const DebugNames::NameIndex &ni,
+ llvm::StringRef name) {
+ // Ignore SentinelErrors, log everything else.
+ LLDB_LOG_ERROR(
+ LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS),
+ handleErrors(std::move(error), [](const DebugNames::SentinelError &) {}),
+ "Failed to parse index entries for index at {1:x}, name {2}: {0}",
+ ni.getUnitOffset(), name);
+}
+
+void DebugNamesDWARFIndex::GetGlobalVariables(ConstString basename,
+ DIEArray &offsets) {
+ m_fallback.GetGlobalVariables(basename, offsets);
+
+ for (const DebugNames::Entry &entry :
+ m_debug_names_up->equal_range(basename.GetStringRef())) {
+ if (entry.tag() != DW_TAG_variable)
+ continue;
+
+ Append(entry, offsets);
+ }
+}
+
+void DebugNamesDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
+ DIEArray &offsets) {
+ m_fallback.GetGlobalVariables(regex, offsets);
+
+ for (const DebugNames::NameIndex &ni: *m_debug_names_up) {
+ for (DebugNames::NameTableEntry nte: ni) {
+ if (!regex.Execute(nte.getString()))
+ continue;
+
+ uint32_t entry_offset = nte.getEntryOffset();
+ llvm::Expected<DebugNames::Entry> entry_or = ni.getEntry(&entry_offset);
+ for (; entry_or; entry_or = ni.getEntry(&entry_offset)) {
+ if (entry_or->tag() != DW_TAG_variable)
+ continue;
+
+ Append(*entry_or, offsets);
+ }
+ MaybeLogLookupError(entry_or.takeError(), ni, nte.getString());
+ }
+ }
+}
+
+void DebugNamesDWARFIndex::GetGlobalVariables(const DWARFUnit &cu,
+ DIEArray &offsets) {
+ m_fallback.GetGlobalVariables(cu, offsets);
+
+ uint64_t cu_offset = cu.GetOffset();
+ for (const DebugNames::NameIndex &ni: *m_debug_names_up) {
+ for (DebugNames::NameTableEntry nte: ni) {
+ uint32_t entry_offset = nte.getEntryOffset();
+ llvm::Expected<DebugNames::Entry> entry_or = ni.getEntry(&entry_offset);
+ for (; entry_or; entry_or = ni.getEntry(&entry_offset)) {
+ if (entry_or->tag() != DW_TAG_variable)
+ continue;
+ if (entry_or->getCUOffset() != cu_offset)
+ continue;
+
+ Append(*entry_or, offsets);
+ }
+ MaybeLogLookupError(entry_or.takeError(), ni, nte.getString());
+ }
+ }
+}
+
+void DebugNamesDWARFIndex::GetCompleteObjCClass(ConstString class_name,
+ bool must_be_implementation,
+ DIEArray &offsets) {
+ m_fallback.GetCompleteObjCClass(class_name, must_be_implementation, offsets);
+
+ // Keep a list of incomplete types as fallback for when we don't find the
+ // complete type.
+ DIEArray incomplete_types;
+
+ for (const DebugNames::Entry &entry :
+ m_debug_names_up->equal_range(class_name.GetStringRef())) {
+ if (entry.tag() != DW_TAG_structure_type &&
+ entry.tag() != DW_TAG_class_type)
+ continue;
+
+ DIERef ref = ToDIERef(entry);
+ if (!ref)
+ continue;
+
+ DWARFUnit *cu = m_debug_info.GetCompileUnit(ref.cu_offset);
+ if (!cu || !cu->Supports_DW_AT_APPLE_objc_complete_type()) {
+ incomplete_types.push_back(ref);
+ continue;
+ }
+
+ // FIXME: We should return DWARFDIEs so we don't have to resolve it twice.
+ DWARFDIE die = m_debug_info.GetDIE(ref);
+ if (!die)
+ continue;
+
+ if (die.GetAttributeValueAsUnsigned(DW_AT_APPLE_objc_complete_type, 0)) {
+ // If we find the complete version we're done.
+ offsets.push_back(ref);
+ return;
+ } else {
+ incomplete_types.push_back(ref);
+ }
+ }
+
+ offsets.insert(offsets.end(), incomplete_types.begin(),
+ incomplete_types.end());
+}
+
+void DebugNamesDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) {
+ m_fallback.GetTypes(name, offsets);
+
+ for (const DebugNames::Entry &entry :
+ m_debug_names_up->equal_range(name.GetStringRef())) {
+ if (isType(entry.tag()))
+ Append(entry, offsets);
+ }
+}
+
+void DebugNamesDWARFIndex::GetTypes(const DWARFDeclContext &context,
+ DIEArray &offsets) {
+ m_fallback.GetTypes(context, offsets);
+
+ for (const DebugNames::Entry &entry :
+ m_debug_names_up->equal_range(context[0].name)) {
+ if (entry.tag() == context[0].tag)
+ Append(entry, offsets);
+ }
+}
+
+void DebugNamesDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) {
+ m_fallback.GetNamespaces(name, offsets);
+
+ for (const DebugNames::Entry &entry :
+ m_debug_names_up->equal_range(name.GetStringRef())) {
+ if (entry.tag() == DW_TAG_namespace)
+ Append(entry, offsets);
+ }
+}
+
+void DebugNamesDWARFIndex::GetFunctions(
+ ConstString name, DWARFDebugInfo &info,
+ const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask,
+ std::vector<DWARFDIE> &dies) {
+
+ m_fallback.GetFunctions(name, info, parent_decl_ctx, name_type_mask, dies);
+
+ for (const DebugNames::Entry &entry :
+ m_debug_names_up->equal_range(name.GetStringRef())) {
+ Tag tag = entry.tag();
+ if (tag != DW_TAG_subprogram && tag != DW_TAG_inlined_subroutine)
+ continue;
+
+ if (DIERef ref = ToDIERef(entry))
+ ProcessFunctionDIE(name.GetStringRef(), ref, info, parent_decl_ctx,
+ name_type_mask, dies);
+ }
+}
+
+void DebugNamesDWARFIndex::GetFunctions(const RegularExpression &regex,
+ DIEArray &offsets) {
+ m_fallback.GetFunctions(regex, offsets);
+
+ for (const DebugNames::NameIndex &ni: *m_debug_names_up) {
+ for (DebugNames::NameTableEntry nte: ni) {
+ if (!regex.Execute(nte.getString()))
+ continue;
+
+ uint32_t entry_offset = nte.getEntryOffset();
+ llvm::Expected<DebugNames::Entry> entry_or = ni.getEntry(&entry_offset);
+ for (; entry_or; entry_or = ni.getEntry(&entry_offset)) {
+ Tag tag = entry_or->tag();
+ if (tag != DW_TAG_subprogram && tag != DW_TAG_inlined_subroutine)
+ continue;
+
+ Append(*entry_or, offsets);
+ }
+ MaybeLogLookupError(entry_or.takeError(), ni, nte.getString());
+ }
+ }
+}
+
+void DebugNamesDWARFIndex::Dump(Stream &s) {
+ m_fallback.Dump(s);
+
+ std::string data;
+ llvm::raw_string_ostream os(data);
+ m_debug_names_up->dump(os);
+ s.PutCString(os.str());
+}
diff --git a/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h b/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h
new file mode 100644
index 000000000000..30423c7ca2a2
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h
@@ -0,0 +1,83 @@
+//===-- DebugNamesDWARFIndex.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_DEBUGNAMESDWARFINDEX_H
+#define LLDB_DEBUGNAMESDWARFINDEX_H
+
+#include "Plugins/SymbolFile/DWARF/DWARFIndex.h"
+#include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h"
+#include "Plugins/SymbolFile/DWARF/ManualDWARFIndex.h"
+#include "lldb/Utility/ConstString.h"
+#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
+
+namespace lldb_private {
+class DebugNamesDWARFIndex : public DWARFIndex {
+public:
+ static llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>>
+ Create(Module &module, DWARFDataExtractor debug_names,
+ DWARFDataExtractor debug_str, DWARFDebugInfo *debug_info);
+
+ void Preload() override { m_fallback.Preload(); }
+
+ void GetGlobalVariables(ConstString basename, DIEArray &offsets) override;
+ void GetGlobalVariables(const RegularExpression &regex,
+ DIEArray &offsets) override;
+ void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) override;
+ void GetObjCMethods(ConstString class_name, DIEArray &offsets) override {}
+ void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation,
+ DIEArray &offsets) override;
+ void GetTypes(ConstString name, DIEArray &offsets) override;
+ void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) override;
+ void GetNamespaces(ConstString name, DIEArray &offsets) override;
+ void GetFunctions(ConstString name, DWARFDebugInfo &info,
+ const CompilerDeclContext &parent_decl_ctx,
+ uint32_t name_type_mask,
+ std::vector<DWARFDIE> &dies) override;
+ void GetFunctions(const RegularExpression &regex,
+ DIEArray &offsets) override;
+
+ void ReportInvalidDIEOffset(dw_offset_t offset,
+ llvm::StringRef name) override {}
+ void Dump(Stream &s) override;
+
+private:
+ DebugNamesDWARFIndex(Module &module,
+ std::unique_ptr<llvm::DWARFDebugNames> debug_names_up,
+ DWARFDataExtractor debug_names_data,
+ DWARFDataExtractor debug_str_data,
+ DWARFDebugInfo &debug_info)
+ : DWARFIndex(module), m_debug_info(debug_info),
+ m_debug_names_data(debug_names_data), m_debug_str_data(debug_str_data),
+ m_debug_names_up(std::move(debug_names_up)),
+ m_fallback(module, &debug_info, GetUnits(*m_debug_names_up)) {}
+
+ DWARFDebugInfo &m_debug_info;
+
+ // LLVM DWARFDebugNames will hold a non-owning reference to this data, so keep
+ // track of the ownership here.
+ DWARFDataExtractor m_debug_names_data;
+ DWARFDataExtractor m_debug_str_data;
+
+ using DebugNames = llvm::DWARFDebugNames;
+ std::unique_ptr<DebugNames> m_debug_names_up;
+ ManualDWARFIndex m_fallback;
+
+ DIERef ToDIERef(const DebugNames::Entry &entry);
+ void Append(const DebugNames::Entry &entry, DIEArray &offsets);
+
+ static void MaybeLogLookupError(llvm::Error error,
+ const DebugNames::NameIndex &ni,
+ llvm::StringRef name);
+
+ static llvm::DenseSet<dw_offset_t> GetUnits(const DebugNames &debug_names);
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_DEBUGNAMESDWARFINDEX_H
diff --git a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
index cb1e5c185613..36211a08557e 100644
--- a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
+++ b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
@@ -75,15 +75,14 @@ void DWARFMappedHash::ExtractClassOrStructDIEArray(
die_tag == DW_TAG_structure_type) {
if (die_info_array[i].type_flags & eTypeFlagClassIsImplementation) {
if (return_implementation_only_if_available) {
- // We found the one true definition for this class, so
- // only return that
+ // We found the one true definition for this class, so only return
+ // that
die_offsets.clear();
die_offsets.emplace_back(die_info_array[i].cu_offset,
die_info_array[i].offset);
return;
} else {
- // Put the one true definition as the first entry so it
- // matches first
+ // Put the one true definition as the first entry so it matches first
die_offsets.emplace(die_offsets.begin(), die_info_array[i].cu_offset,
die_info_array[i].offset);
}
@@ -137,9 +136,8 @@ DWARFMappedHash::DIEInfo::DIEInfo(dw_offset_t c, dw_offset_t o, dw_tag_t t,
DWARFMappedHash::Prologue::Prologue(dw_offset_t _die_base_offset)
: die_base_offset(_die_base_offset), atoms(), atom_mask(0),
min_hash_data_byte_size(0), hash_data_has_fixed_byte_size(true) {
- // Define an array of DIE offsets by first defining an array,
- // and then define the atom type for the array, in this case
- // we have an array of DIE offsets
+ // Define an array of DIE offsets by first defining an array, and then define
+ // the atom type for the array, in this case we have an array of DIE offsets
AppendAtom(eAtomTypeDIEOffset, DW_FORM_data4);
}
@@ -239,8 +237,7 @@ DWARFMappedHash::Prologue::Read(const lldb_private::DataExtractor &data,
size_t DWARFMappedHash::Prologue::GetByteSize() const {
// Add an extra count to the atoms size for the zero termination Atom that
- // gets
- // written to disk
+ // gets written to disk
return sizeof(die_base_offset) + sizeof(uint32_t) +
atoms.size() * sizeof(Atom);
}
@@ -379,17 +376,18 @@ bool DWARFMappedHash::MemoryTable::ReadHashData(uint32_t hash_data_offset,
DWARFMappedHash::MemoryTable::Result
DWARFMappedHash::MemoryTable::GetHashDataForName(
- const char *name, lldb::offset_t *hash_data_offset_ptr, Pair &pair) const {
+ llvm::StringRef name, lldb::offset_t *hash_data_offset_ptr,
+ Pair &pair) const {
pair.key = m_data.GetU32(hash_data_offset_ptr);
pair.value.clear();
- // If the key is zero, this terminates our chain of HashData objects
- // for this hash value.
+ // If the key is zero, this terminates our chain of HashData objects for this
+ // hash value.
if (pair.key == 0)
return eResultEndOfHashData;
- // There definitely should be a string for this string offset, if
- // there isn't, there is something wrong, return and error
+ // There definitely should be a string for this string offset, if there
+ // isn't, there is something wrong, return and error
const char *strp_cstr = m_string_table.PeekCStr(pair.key);
if (strp_cstr == NULL) {
*hash_data_offset_ptr = UINT32_MAX;
@@ -402,22 +400,21 @@ DWARFMappedHash::MemoryTable::GetHashDataForName(
if (count > 0 &&
m_data.ValidOffsetForDataOfSize(*hash_data_offset_ptr,
min_total_hash_data_size)) {
- // We have at least one HashData entry, and we have enough
- // data to parse at least "count" HashData entries.
+ // We have at least one HashData entry, and we have enough data to parse at
+ // least "count" HashData entries.
// First make sure the entire C string matches...
- const bool match = strcmp(name, strp_cstr) == 0;
+ const bool match = name == strp_cstr;
if (!match && m_header.header_data.HashDataHasFixedByteSize()) {
- // If the string doesn't match and we have fixed size data,
- // we can just add the total byte size of all HashData objects
- // to the hash data offset and be done...
+ // If the string doesn't match and we have fixed size data, we can just
+ // add the total byte size of all HashData objects to the hash data
+ // offset and be done...
*hash_data_offset_ptr += min_total_hash_data_size;
} else {
- // If the string does match, or we don't have fixed size data
- // then we need to read the hash data as a stream. If the
- // string matches we also append all HashData objects to the
- // value array.
+ // If the string does match, or we don't have fixed size data then we
+ // need to read the hash data as a stream. If the string matches we also
+ // append all HashData objects to the value array.
for (uint32_t i = 0; i < count; ++i) {
DIEInfo die_info;
if (m_header.Read(m_data, hash_data_offset_ptr, die_info)) {
@@ -431,16 +428,15 @@ DWARFMappedHash::MemoryTable::GetHashDataForName(
}
}
}
- // Return the correct response depending on if the string matched
- // or not...
+ // Return the correct response depending on if the string matched or not...
if (match)
return eResultKeyMatch; // The key (cstring) matches and we have lookup
// results!
else
return eResultKeyMismatch; // The key doesn't match, this function will
// get called
- // again for the next key/value or the key terminator
- // which in our case is a zero .debug_str offset.
+ // again for the next key/value or the key terminator which in our case is
+ // a zero .debug_str offset.
} else {
*hash_data_offset_ptr = UINT32_MAX;
return eResultError;
@@ -452,13 +448,13 @@ DWARFMappedHash::MemoryTable::AppendHashDataForRegularExpression(
const lldb_private::RegularExpression &regex,
lldb::offset_t *hash_data_offset_ptr, Pair &pair) const {
pair.key = m_data.GetU32(hash_data_offset_ptr);
- // If the key is zero, this terminates our chain of HashData objects
- // for this hash value.
+ // If the key is zero, this terminates our chain of HashData objects for this
+ // hash value.
if (pair.key == 0)
return eResultEndOfHashData;
- // There definitely should be a string for this string offset, if
- // there isn't, there is something wrong, return and error
+ // There definitely should be a string for this string offset, if there
+ // isn't, there is something wrong, return and error
const char *strp_cstr = m_string_table.PeekCStr(pair.key);
if (strp_cstr == NULL)
return eResultError;
@@ -472,15 +468,14 @@ DWARFMappedHash::MemoryTable::AppendHashDataForRegularExpression(
const bool match = regex.Execute(llvm::StringRef(strp_cstr));
if (!match && m_header.header_data.HashDataHasFixedByteSize()) {
- // If the regex doesn't match and we have fixed size data,
- // we can just add the total byte size of all HashData objects
- // to the hash data offset and be done...
+ // If the regex doesn't match and we have fixed size data, we can just
+ // add the total byte size of all HashData objects to the hash data
+ // offset and be done...
*hash_data_offset_ptr += min_total_hash_data_size;
} else {
- // If the string does match, or we don't have fixed size data
- // then we need to read the hash data as a stream. If the
- // string matches we also append all HashData objects to the
- // value array.
+ // If the string does match, or we don't have fixed size data then we
+ // need to read the hash data as a stream. If the string matches we also
+ // append all HashData objects to the value array.
for (uint32_t i = 0; i < count; ++i) {
DIEInfo die_info;
if (m_header.Read(m_data, hash_data_offset_ptr, die_info)) {
@@ -494,16 +489,15 @@ DWARFMappedHash::MemoryTable::AppendHashDataForRegularExpression(
}
}
}
- // Return the correct response depending on if the string matched
- // or not...
+ // Return the correct response depending on if the string matched or not...
if (match)
return eResultKeyMatch; // The key (cstring) matches and we have lookup
// results!
else
return eResultKeyMismatch; // The key doesn't match, this function will
// get called
- // again for the next key/value or the key terminator
- // which in our case is a zero .debug_str offset.
+ // again for the next key/value or the key terminator which in our case is
+ // a zero .debug_str offset.
} else {
*hash_data_offset_ptr = UINT32_MAX;
return eResultError;
@@ -528,8 +522,7 @@ size_t DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex(
switch (hash_result) {
case eResultKeyMatch:
case eResultKeyMismatch:
- // Whether we matches or not, it doesn't matter, we
- // keep looking.
+ // Whether we matches or not, it doesn't matter, we keep looking.
break;
case eResultEndOfHashData:
@@ -552,8 +545,8 @@ size_t DWARFMappedHash::MemoryTable::AppendAllDIEsInRange(
lldb::offset_t hash_data_offset = GetHashDataOffset(offset_idx);
while (!done && hash_data_offset != UINT32_MAX) {
KeyType key = m_data.GetU32(&hash_data_offset);
- // If the key is zero, this terminates our chain of HashData objects
- // for this hash value.
+ // If the key is zero, this terminates our chain of HashData objects for
+ // this hash value.
if (key == 0)
break;
@@ -573,9 +566,9 @@ size_t DWARFMappedHash::MemoryTable::AppendAllDIEsInRange(
return die_info_array.size();
}
-size_t DWARFMappedHash::MemoryTable::FindByName(const char *name,
+size_t DWARFMappedHash::MemoryTable::FindByName(llvm::StringRef name,
DIEArray &die_offsets) {
- if (!name || !name[0])
+ if (name.empty())
return 0;
DIEInfoArray die_info_array;
@@ -584,7 +577,7 @@ size_t DWARFMappedHash::MemoryTable::FindByName(const char *name,
return die_info_array.size();
}
-size_t DWARFMappedHash::MemoryTable::FindByNameAndTag(const char *name,
+size_t DWARFMappedHash::MemoryTable::FindByNameAndTag(llvm::StringRef name,
const dw_tag_t tag,
DIEArray &die_offsets) {
DIEInfoArray die_info_array;
@@ -594,8 +587,8 @@ size_t DWARFMappedHash::MemoryTable::FindByNameAndTag(const char *name,
}
size_t DWARFMappedHash::MemoryTable::FindByNameAndTagAndQualifiedNameHash(
- const char *name, const dw_tag_t tag, const uint32_t qualified_name_hash,
- DIEArray &die_offsets) {
+ llvm::StringRef name, const dw_tag_t tag,
+ const uint32_t qualified_name_hash, DIEArray &die_offsets) {
DIEInfoArray die_info_array;
if (FindByName(name, die_info_array))
DWARFMappedHash::ExtractDIEArray(die_info_array, tag, qualified_name_hash,
@@ -604,22 +597,21 @@ size_t DWARFMappedHash::MemoryTable::FindByNameAndTagAndQualifiedNameHash(
}
size_t DWARFMappedHash::MemoryTable::FindCompleteObjCClassByName(
- const char *name, DIEArray &die_offsets, bool must_be_implementation) {
+ llvm::StringRef name, DIEArray &die_offsets, bool must_be_implementation) {
DIEInfoArray die_info_array;
if (FindByName(name, die_info_array)) {
if (must_be_implementation &&
GetHeader().header_data.ContainsAtom(eAtomTypeTypeFlags)) {
- // If we have two atoms, then we have the DIE offset and
- // the type flags so we can find the objective C class
- // efficiently.
+ // If we have two atoms, then we have the DIE offset and the type flags
+ // so we can find the objective C class efficiently.
DWARFMappedHash::ExtractTypesFromDIEArray(die_info_array, UINT32_MAX,
eTypeFlagClassIsImplementation,
die_offsets);
} else {
- // We don't only want the one true definition, so try and see
- // what we can find, and only return class or struct DIEs.
- // If we do have the full implementation, then return it alone,
- // else return all possible matches.
+ // We don't only want the one true definition, so try and see what we can
+ // find, and only return class or struct DIEs. If we do have the full
+ // implementation, then return it alone, else return all possible
+ // matches.
const bool return_implementation_only_if_available = true;
DWARFMappedHash::ExtractClassOrStructDIEArray(
die_info_array, return_implementation_only_if_available, die_offsets);
@@ -628,9 +620,9 @@ size_t DWARFMappedHash::MemoryTable::FindCompleteObjCClassByName(
return die_offsets.size();
}
-size_t DWARFMappedHash::MemoryTable::FindByName(const char *name,
+size_t DWARFMappedHash::MemoryTable::FindByName(llvm::StringRef name,
DIEInfoArray &die_info_array) {
- if (!name || !name[0])
+ if (name.empty())
return 0;
Pair kv_pair;
diff --git a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
index 959517529e52..17600df2edd4 100644
--- a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
+++ b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
@@ -21,10 +21,6 @@
#include "DWARFFormValue.h"
#include "NameToDIE.h"
-class SymbolFileDWARF;
-class DWARFCompileUnit;
-class DWARFDebugInfoEntry;
-
class DWARFMappedHash {
public:
enum AtomType : uint16_t {
@@ -136,17 +132,17 @@ public:
const uint32_t die_offset_end,
DIEInfoArray &die_info_array) const;
- size_t FindByName(const char *name, DIEArray &die_offsets);
+ size_t FindByName(llvm::StringRef name, DIEArray &die_offsets);
- size_t FindByNameAndTag(const char *name, const dw_tag_t tag,
+ size_t FindByNameAndTag(llvm::StringRef name, const dw_tag_t tag,
DIEArray &die_offsets);
- size_t
- FindByNameAndTagAndQualifiedNameHash(const char *name, const dw_tag_t tag,
- const uint32_t qualified_name_hash,
- DIEArray &die_offsets);
+ size_t FindByNameAndTagAndQualifiedNameHash(
+ llvm::StringRef name, const dw_tag_t tag,
+ const uint32_t qualified_name_hash, DIEArray &die_offsets);
- size_t FindCompleteObjCClassByName(const char *name, DIEArray &die_offsets,
+ size_t FindCompleteObjCClassByName(llvm::StringRef name,
+ DIEArray &die_offsets,
bool must_be_implementation);
protected:
@@ -154,14 +150,14 @@ public:
const lldb_private::RegularExpression &regex,
lldb::offset_t *hash_data_offset_ptr, Pair &pair) const;
- size_t FindByName(const char *name, DIEInfoArray &die_info_array);
+ size_t FindByName(llvm::StringRef name, DIEInfoArray &die_info_array);
- Result GetHashDataForName(const char *name,
+ Result GetHashDataForName(llvm::StringRef name,
lldb::offset_t *hash_data_offset_ptr,
Pair &pair) const override;
- const lldb_private::DWARFDataExtractor &m_data;
- const lldb_private::DWARFDataExtractor &m_string_table;
+ lldb_private::DWARFDataExtractor m_data;
+ lldb_private::DWARFDataExtractor m_string_table;
std::string m_name;
};
diff --git a/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
new file mode 100644
index 000000000000..6438f02fe8ec
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
@@ -0,0 +1,488 @@
+//===-- ManualDWARFIndex.cpp -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/SymbolFile/DWARF/ManualDWARFIndex.h"
+#include "Plugins/Language/ObjC/ObjCLanguage.h"
+#include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
+#include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h"
+#include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h"
+#include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Host/TaskPool.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/Stream.h"
+#include "lldb/Utility/Timer.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+void ManualDWARFIndex::Index() {
+ if (!m_debug_info)
+ return;
+
+ DWARFDebugInfo &debug_info = *m_debug_info;
+ m_debug_info = nullptr;
+
+ static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
+ Timer scoped_timer(func_cat, "%p", static_cast<void *>(&debug_info));
+
+ std::vector<DWARFUnit *> units_to_index;
+ units_to_index.reserve(debug_info.GetNumCompileUnits());
+ for (size_t U = 0; U < debug_info.GetNumCompileUnits(); ++U) {
+ DWARFUnit *unit = debug_info.GetCompileUnitAtIndex(U);
+ if (unit && m_units_to_avoid.count(unit->GetOffset()) == 0)
+ units_to_index.push_back(unit);
+ }
+ if (units_to_index.empty())
+ return;
+
+ std::vector<IndexSet> sets(units_to_index.size());
+
+ //----------------------------------------------------------------------
+ // Keep memory down by clearing DIEs for any compile units if indexing
+ // caused us to load the compile unit's DIEs.
+ //----------------------------------------------------------------------
+ std::vector<llvm::Optional<DWARFUnit::ScopedExtractDIEs>> clear_cu_dies(
+ units_to_index.size());
+ auto parser_fn = [&](size_t cu_idx) {
+ IndexUnit(*units_to_index[cu_idx], sets[cu_idx]);
+ };
+
+ auto extract_fn = [&units_to_index, &clear_cu_dies](size_t cu_idx) {
+ clear_cu_dies[cu_idx] = units_to_index[cu_idx]->ExtractDIEsScoped();
+ };
+
+ // Create a task runner that extracts dies for each DWARF compile unit in a
+ // separate thread
+ //----------------------------------------------------------------------
+ // First figure out which compile units didn't have their DIEs already
+ // parsed and remember this. If no DIEs were parsed prior to this index
+ // function call, we are going to want to clear the CU dies after we are
+ // done indexing to make sure we don't pull in all DWARF dies, but we need
+ // to wait until all compile units have been indexed in case a DIE in one
+ // compile unit refers to another and the indexes accesses those DIEs.
+ //----------------------------------------------------------------------
+ TaskMapOverInt(0, units_to_index.size(), extract_fn);
+
+ // Now create a task runner that can index each DWARF compile unit in a
+ // separate thread so we can index quickly.
+
+ TaskMapOverInt(0, units_to_index.size(), parser_fn);
+
+ auto finalize_fn = [this, &sets](NameToDIE(IndexSet::*index)) {
+ NameToDIE &result = m_set.*index;
+ for (auto &set : sets)
+ result.Append(set.*index);
+ result.Finalize();
+ };
+
+ TaskPool::RunTasks([&]() { finalize_fn(&IndexSet::function_basenames); },
+ [&]() { finalize_fn(&IndexSet::function_fullnames); },
+ [&]() { finalize_fn(&IndexSet::function_methods); },
+ [&]() { finalize_fn(&IndexSet::function_selectors); },
+ [&]() { finalize_fn(&IndexSet::objc_class_selectors); },
+ [&]() { finalize_fn(&IndexSet::globals); },
+ [&]() { finalize_fn(&IndexSet::types); },
+ [&]() { finalize_fn(&IndexSet::namespaces); });
+}
+
+void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, IndexSet &set) {
+ Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS);
+
+ if (log) {
+ m_module.LogMessage(
+ log, "ManualDWARFIndex::IndexUnit for compile unit at .debug_info[0x%8.8x]",
+ unit.GetOffset());
+ }
+
+ const LanguageType cu_language = unit.GetLanguageType();
+ DWARFFormValue::FixedFormSizes fixed_form_sizes = unit.GetFixedFormSizes();
+
+ IndexUnitImpl(unit, cu_language, fixed_form_sizes, unit.GetOffset(), set);
+
+ SymbolFileDWARFDwo *dwo_symbol_file = unit.GetDwoSymbolFile();
+ if (dwo_symbol_file && dwo_symbol_file->GetCompileUnit()) {
+ IndexUnitImpl(*dwo_symbol_file->GetCompileUnit(), cu_language,
+ fixed_form_sizes, unit.GetOffset(), set);
+ }
+}
+
+void ManualDWARFIndex::IndexUnitImpl(
+ DWARFUnit &unit, const LanguageType cu_language,
+ const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
+ const dw_offset_t cu_offset, IndexSet &set) {
+ for (const DWARFDebugInfoEntry &die : unit.dies()) {
+ const dw_tag_t tag = die.Tag();
+
+ switch (tag) {
+ case DW_TAG_array_type:
+ case DW_TAG_base_type:
+ case DW_TAG_class_type:
+ case DW_TAG_constant:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_inlined_subroutine:
+ case DW_TAG_namespace:
+ case DW_TAG_string_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_subprogram:
+ case DW_TAG_subroutine_type:
+ case DW_TAG_typedef:
+ case DW_TAG_union_type:
+ case DW_TAG_unspecified_type:
+ case DW_TAG_variable:
+ break;
+
+ default:
+ continue;
+ }
+
+ DWARFAttributes attributes;
+ const char *name = NULL;
+ const char *mangled_cstr = NULL;
+ bool is_declaration = false;
+ // bool is_artificial = false;
+ bool has_address = false;
+ bool has_location_or_const_value = false;
+ bool is_global_or_static_variable = false;
+
+ DWARFFormValue specification_die_form;
+ const size_t num_attributes =
+ die.GetAttributes(&unit, fixed_form_sizes, attributes);
+ if (num_attributes > 0) {
+ for (uint32_t i = 0; i < num_attributes; ++i) {
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ DWARFFormValue form_value;
+ switch (attr) {
+ case DW_AT_name:
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ name = form_value.AsCString();
+ break;
+
+ case DW_AT_declaration:
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ is_declaration = form_value.Unsigned() != 0;
+ break;
+
+ // case DW_AT_artificial:
+ // if (attributes.ExtractFormValueAtIndex(i,
+ // form_value))
+ // is_artificial = form_value.Unsigned() != 0;
+ // break;
+
+ case DW_AT_MIPS_linkage_name:
+ case DW_AT_linkage_name:
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ mangled_cstr = form_value.AsCString();
+ break;
+
+ case DW_AT_low_pc:
+ case DW_AT_high_pc:
+ case DW_AT_ranges:
+ has_address = true;
+ break;
+
+ case DW_AT_entry_pc:
+ has_address = true;
+ break;
+
+ case DW_AT_location:
+ case DW_AT_const_value:
+ has_location_or_const_value = true;
+ if (tag == DW_TAG_variable) {
+ const DWARFDebugInfoEntry *parent_die = die.GetParent();
+ while (parent_die != NULL) {
+ switch (parent_die->Tag()) {
+ case DW_TAG_subprogram:
+ case DW_TAG_lexical_block:
+ case DW_TAG_inlined_subroutine:
+ // Even if this is a function level static, we don't add it. We
+ // could theoretically add these if we wanted to by
+ // introspecting into the DW_AT_location and seeing if the
+ // location describes a hard coded address, but we don't want
+ // the performance penalty of that right now.
+ is_global_or_static_variable = false;
+ // if (attributes.ExtractFormValueAtIndex(dwarf, i,
+ // form_value)) {
+ // // If we have valid block data, then we have location
+ // // expression bytesthat are fixed (not a location list).
+ // const uint8_t *block_data = form_value.BlockData();
+ // if (block_data) {
+ // uint32_t block_length = form_value.Unsigned();
+ // if (block_length == 1 +
+ // attributes.CompileUnitAtIndex(i)->GetAddressByteSize()) {
+ // if (block_data[0] == DW_OP_addr)
+ // add_die = true;
+ // }
+ // }
+ // }
+ parent_die = NULL; // Terminate the while loop.
+ break;
+
+ case DW_TAG_compile_unit:
+ case DW_TAG_partial_unit:
+ is_global_or_static_variable = true;
+ parent_die = NULL; // Terminate the while loop.
+ break;
+
+ default:
+ parent_die =
+ parent_die->GetParent(); // Keep going in the while loop.
+ break;
+ }
+ }
+ }
+ break;
+
+ case DW_AT_specification:
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ specification_die_form = form_value;
+ break;
+ }
+ }
+ }
+
+ switch (tag) {
+ case DW_TAG_inlined_subroutine:
+ case DW_TAG_subprogram:
+ if (has_address) {
+ if (name) {
+ ObjCLanguage::MethodName objc_method(name, true);
+ if (objc_method.IsValid(true)) {
+ ConstString objc_class_name_with_category(
+ objc_method.GetClassNameWithCategory());
+ ConstString objc_selector_name(objc_method.GetSelector());
+ ConstString objc_fullname_no_category_name(
+ objc_method.GetFullNameWithoutCategory(true));
+ ConstString objc_class_name_no_category(objc_method.GetClassName());
+ set.function_fullnames.Insert(ConstString(name),
+ DIERef(cu_offset, die.GetOffset()));
+ if (objc_class_name_with_category)
+ set.objc_class_selectors.Insert(
+ objc_class_name_with_category,
+ DIERef(cu_offset, die.GetOffset()));
+ if (objc_class_name_no_category &&
+ objc_class_name_no_category != objc_class_name_with_category)
+ set.objc_class_selectors.Insert(
+ objc_class_name_no_category,
+ DIERef(cu_offset, die.GetOffset()));
+ if (objc_selector_name)
+ set.function_selectors.Insert(objc_selector_name,
+ DIERef(cu_offset, die.GetOffset()));
+ if (objc_fullname_no_category_name)
+ set.function_fullnames.Insert(objc_fullname_no_category_name,
+ DIERef(cu_offset, die.GetOffset()));
+ }
+ // If we have a mangled name, then the DW_AT_name attribute is
+ // usually the method name without the class or any parameters
+ bool is_method = DWARFDIE(&unit, &die).IsMethod();
+
+ if (is_method)
+ set.function_methods.Insert(ConstString(name),
+ DIERef(cu_offset, die.GetOffset()));
+ else
+ set.function_basenames.Insert(ConstString(name),
+ DIERef(cu_offset, die.GetOffset()));
+
+ if (!is_method && !mangled_cstr && !objc_method.IsValid(true))
+ set.function_fullnames.Insert(ConstString(name),
+ DIERef(cu_offset, die.GetOffset()));
+ }
+ if (mangled_cstr) {
+ // Make sure our mangled name isn't the same string table entry as
+ // our name. If it starts with '_', then it is ok, else compare the
+ // string to make sure it isn't the same and we don't end up with
+ // duplicate entries
+ if (name && name != mangled_cstr &&
+ ((mangled_cstr[0] == '_') ||
+ (::strcmp(name, mangled_cstr) != 0))) {
+ set.function_fullnames.Insert(ConstString(mangled_cstr),
+ DIERef(cu_offset, die.GetOffset()));
+ }
+ }
+ }
+ break;
+
+ case DW_TAG_array_type:
+ case DW_TAG_base_type:
+ case DW_TAG_class_type:
+ case DW_TAG_constant:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_string_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_subroutine_type:
+ case DW_TAG_typedef:
+ case DW_TAG_union_type:
+ case DW_TAG_unspecified_type:
+ if (name && !is_declaration)
+ set.types.Insert(ConstString(name), DIERef(cu_offset, die.GetOffset()));
+ if (mangled_cstr && !is_declaration)
+ set.types.Insert(ConstString(mangled_cstr),
+ DIERef(cu_offset, die.GetOffset()));
+ break;
+
+ case DW_TAG_namespace:
+ if (name)
+ set.namespaces.Insert(ConstString(name),
+ DIERef(cu_offset, die.GetOffset()));
+ break;
+
+ case DW_TAG_variable:
+ if (name && has_location_or_const_value && is_global_or_static_variable) {
+ set.globals.Insert(ConstString(name),
+ DIERef(cu_offset, die.GetOffset()));
+ // Be sure to include variables by their mangled and demangled names if
+ // they have any since a variable can have a basename "i", a mangled
+ // named "_ZN12_GLOBAL__N_11iE" and a demangled mangled name
+ // "(anonymous namespace)::i"...
+
+ // Make sure our mangled name isn't the same string table entry as our
+ // name. If it starts with '_', then it is ok, else compare the string
+ // to make sure it isn't the same and we don't end up with duplicate
+ // entries
+ if (mangled_cstr && name != mangled_cstr &&
+ ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) {
+ set.globals.Insert(ConstString(mangled_cstr),
+ DIERef(cu_offset, die.GetOffset()));
+ }
+ }
+ break;
+
+ default:
+ continue;
+ }
+ }
+}
+
+void ManualDWARFIndex::GetGlobalVariables(ConstString basename, DIEArray &offsets) {
+ Index();
+ m_set.globals.Find(basename, offsets);
+}
+
+void ManualDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
+ DIEArray &offsets) {
+ Index();
+ m_set.globals.Find(regex, offsets);
+}
+
+void ManualDWARFIndex::GetGlobalVariables(const DWARFUnit &cu,
+ DIEArray &offsets) {
+ Index();
+ m_set.globals.FindAllEntriesForCompileUnit(cu.GetOffset(), offsets);
+}
+
+void ManualDWARFIndex::GetObjCMethods(ConstString class_name,
+ DIEArray &offsets) {
+ Index();
+ m_set.objc_class_selectors.Find(class_name, offsets);
+}
+
+void ManualDWARFIndex::GetCompleteObjCClass(ConstString class_name,
+ bool must_be_implementation,
+ DIEArray &offsets) {
+ Index();
+ m_set.types.Find(class_name, offsets);
+}
+
+void ManualDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) {
+ Index();
+ m_set.types.Find(name, offsets);
+}
+
+void ManualDWARFIndex::GetTypes(const DWARFDeclContext &context,
+ DIEArray &offsets) {
+ Index();
+ m_set.types.Find(ConstString(context[0].name), offsets);
+}
+
+void ManualDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) {
+ Index();
+ m_set.namespaces.Find(name, offsets);
+}
+
+void ManualDWARFIndex::GetFunctions(ConstString name, DWARFDebugInfo &info,
+ const CompilerDeclContext &parent_decl_ctx,
+ uint32_t name_type_mask,
+ std::vector<DWARFDIE> &dies) {
+ Index();
+
+ if (name_type_mask & eFunctionNameTypeFull) {
+ DIEArray offsets;
+ m_set.function_basenames.Find(name, offsets);
+ m_set.function_methods.Find(name, offsets);
+ m_set.function_fullnames.Find(name, offsets);
+ for (const DIERef &die_ref: offsets) {
+ DWARFDIE die = info.GetDIE(die_ref);
+ if (!die)
+ continue;
+ if (SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die))
+ dies.push_back(die);
+ }
+ }
+ if (name_type_mask & eFunctionNameTypeBase) {
+ DIEArray offsets;
+ m_set.function_basenames.Find(name, offsets);
+ for (const DIERef &die_ref: offsets) {
+ DWARFDIE die = info.GetDIE(die_ref);
+ if (!die)
+ continue;
+ if (SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die))
+ dies.push_back(die);
+ }
+ offsets.clear();
+ }
+
+ if (name_type_mask & eFunctionNameTypeMethod && !parent_decl_ctx.IsValid()) {
+ DIEArray offsets;
+ m_set.function_methods.Find(name, offsets);
+ for (const DIERef &die_ref: offsets) {
+ if (DWARFDIE die = info.GetDIE(die_ref))
+ dies.push_back(die);
+ }
+ }
+
+ if (name_type_mask & eFunctionNameTypeSelector &&
+ !parent_decl_ctx.IsValid()) {
+ DIEArray offsets;
+ m_set.function_selectors.Find(name, offsets);
+ for (const DIERef &die_ref: offsets) {
+ if (DWARFDIE die = info.GetDIE(die_ref))
+ dies.push_back(die);
+ }
+ }
+}
+
+void ManualDWARFIndex::GetFunctions(const RegularExpression &regex,
+ DIEArray &offsets) {
+ Index();
+
+ m_set.function_basenames.Find(regex, offsets);
+ m_set.function_fullnames.Find(regex, offsets);
+}
+
+void ManualDWARFIndex::Dump(Stream &s) {
+ s.Format("Manual DWARF index for ({0}) '{1:F}':",
+ m_module.GetArchitecture().GetArchitectureName(),
+ m_module.GetObjectFile()->GetFileSpec());
+ s.Printf("\nFunction basenames:\n");
+ m_set.function_basenames.Dump(&s);
+ s.Printf("\nFunction fullnames:\n");
+ m_set.function_fullnames.Dump(&s);
+ s.Printf("\nFunction methods:\n");
+ m_set.function_methods.Dump(&s);
+ s.Printf("\nFunction selectors:\n");
+ m_set.function_selectors.Dump(&s);
+ s.Printf("\nObjective-C class selectors:\n");
+ m_set.objc_class_selectors.Dump(&s);
+ s.Printf("\nGlobals and statics:\n");
+ m_set.globals.Dump(&s);
+ s.Printf("\nTypes:\n");
+ m_set.types.Dump(&s);
+ s.Printf("\nNamespaces:\n");
+ m_set.namespaces.Dump(&s);
+}
diff --git a/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h b/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
new file mode 100644
index 000000000000..79ab1d95b380
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
@@ -0,0 +1,75 @@
+//===-- ManulaDWARFIndex.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_MANUALDWARFINDEX_H
+#define LLDB_MANUALDWARFINDEX_H
+
+#include "Plugins/SymbolFile/DWARF/DWARFIndex.h"
+#include "Plugins/SymbolFile/DWARF/NameToDIE.h"
+#include "llvm/ADT/DenseSet.h"
+
+namespace lldb_private {
+class ManualDWARFIndex : public DWARFIndex {
+public:
+ ManualDWARFIndex(Module &module, DWARFDebugInfo *debug_info,
+ llvm::DenseSet<dw_offset_t> units_to_avoid = {})
+ : DWARFIndex(module), m_debug_info(debug_info),
+ m_units_to_avoid(std::move(units_to_avoid)) {}
+
+ void Preload() override { Index(); }
+
+ void GetGlobalVariables(ConstString basename, DIEArray &offsets) override;
+ void GetGlobalVariables(const RegularExpression &regex,
+ DIEArray &offsets) override;
+ void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) override;
+ void GetObjCMethods(ConstString class_name, DIEArray &offsets) override;
+ void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation,
+ DIEArray &offsets) override;
+ void GetTypes(ConstString name, DIEArray &offsets) override;
+ void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) override;
+ void GetNamespaces(ConstString name, DIEArray &offsets) override;
+ void GetFunctions(ConstString name, DWARFDebugInfo &info,
+ const CompilerDeclContext &parent_decl_ctx,
+ uint32_t name_type_mask,
+ std::vector<DWARFDIE> &dies) override;
+ void GetFunctions(const RegularExpression &regex, DIEArray &offsets) override;
+
+ void ReportInvalidDIEOffset(dw_offset_t offset,
+ llvm::StringRef name) override {}
+ void Dump(Stream &s) override;
+
+private:
+ struct IndexSet {
+ NameToDIE function_basenames;
+ NameToDIE function_fullnames;
+ NameToDIE function_methods;
+ NameToDIE function_selectors;
+ NameToDIE objc_class_selectors;
+ NameToDIE globals;
+ NameToDIE types;
+ NameToDIE namespaces;
+ };
+ void Index();
+ void IndexUnit(DWARFUnit &unit, IndexSet &set);
+
+ static void
+ IndexUnitImpl(DWARFUnit &unit, const lldb::LanguageType cu_language,
+ const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
+ const dw_offset_t cu_offset, IndexSet &set);
+
+ /// Non-null value means we haven't built the index yet.
+ DWARFDebugInfo *m_debug_info;
+ /// Which dwarf units should we skip while building the index.
+ llvm::DenseSet<dw_offset_t> m_units_to_avoid;
+
+ IndexSet m_set;
+};
+} // namespace lldb_private
+
+#endif // LLDB_MANUALDWARFINDEX_H
diff --git a/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp b/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
index c97680eda0fe..c8d6bba16976 100644
--- a/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
+++ b/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
@@ -14,7 +14,6 @@
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StreamString.h"
-#include "DWARFCompileUnit.h"
#include "DWARFDebugInfo.h"
#include "DWARFDebugInfoEntry.h"
#include "SymbolFileDWARF.h"
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index f149ec354f08..ac320ac52b08 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -27,6 +27,7 @@
#include "lldb/Utility/Timer.h"
#include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
+#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
@@ -49,27 +50,24 @@
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Symbol/VariableList.h"
-#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
-#include "Plugins/Language/ObjC/ObjCLanguage.h"
-
#include "lldb/Target/Language.h"
-#include "lldb/Host/TaskPool.h"
-
+#include "AppleDWARFIndex.h"
#include "DWARFASTParser.h"
#include "DWARFASTParserClang.h"
-#include "DWARFCompileUnit.h"
#include "DWARFDIECollection.h"
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugAranges.h"
#include "DWARFDebugInfo.h"
#include "DWARFDebugLine.h"
#include "DWARFDebugMacro.h"
-#include "DWARFDebugPubnames.h"
#include "DWARFDebugRanges.h"
#include "DWARFDeclContext.h"
#include "DWARFFormValue.h"
+#include "DWARFUnit.h"
+#include "DebugNamesDWARFIndex.h"
#include "LogChannelDWARF.h"
+#include "ManualDWARFIndex.h"
#include "SymbolFileDWARFDebugMap.h"
#include "SymbolFileDWARFDwo.h"
#include "SymbolFileDWARFDwp.h"
@@ -115,11 +113,20 @@ namespace {
PropertyDefinition g_properties[] = {
{"comp-dir-symlink-paths", OptionValue::eTypeFileSpecList, true, 0, nullptr,
- nullptr, "If the DW_AT_comp_dir matches any of these paths the symbolic "
- "links will be resolved at DWARF parse time."},
- {nullptr, OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr}};
+ nullptr,
+ "If the DW_AT_comp_dir matches any of these paths the symbolic "
+ "links will be resolved at DWARF parse time."},
+ {"ignore-file-indexes", OptionValue::eTypeBoolean, true, 0, nullptr,
+ nullptr,
+ "Ignore indexes present in the object files and always index DWARF "
+ "manually."},
+ {nullptr, OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr},
+};
-enum { ePropertySymLinkPaths };
+enum {
+ ePropertySymLinkPaths,
+ ePropertyIgnoreIndexes,
+};
class PluginProperties : public Properties {
public:
@@ -139,6 +146,11 @@ public:
assert(option_value);
return option_value->GetCurrentValue();
}
+
+ bool IgnoreFileIndexes() const {
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, ePropertyIgnoreIndexes, false);
+ }
};
typedef std::shared_ptr<PluginProperties> SymbolFileDWARFPropertiesSP;
@@ -165,8 +177,8 @@ static const char *removeHostnameFromPathname(const char *path_from_dwarf) {
return path_from_dwarf;
}
- // check whether we have a windows path, and so the first character
- // is a drive-letter not a hostname.
+ // check whether we have a windows path, and so the first character is a
+ // drive-letter not a hostname.
if (colon_pos == path_from_dwarf + 1 && isalpha(*path_from_dwarf) &&
strlen(path_from_dwarf) > 2 && '\\' == path_from_dwarf[2]) {
return path_from_dwarf;
@@ -175,41 +187,42 @@ static const char *removeHostnameFromPathname(const char *path_from_dwarf) {
return colon_pos + 1;
}
-static const char *resolveCompDir(const char *path_from_dwarf) {
+static FileSpec resolveCompDir(const char *path_from_dwarf) {
if (!path_from_dwarf)
- return nullptr;
+ return FileSpec();
// DWARF2/3 suggests the form hostname:pathname for compilation directory.
// Remove the host part if present.
const char *local_path = removeHostnameFromPathname(path_from_dwarf);
if (!local_path)
- return nullptr;
+ return FileSpec();
bool is_symlink = false;
- FileSpec local_path_spec(local_path, false);
+ // Always normalize our compile unit directory to get rid of redundant
+ // slashes and other path anomalies before we use it for path prepending
+ FileSpec local_spec(local_path, false);
const auto &file_specs = GetGlobalPluginProperties()->GetSymLinkPaths();
for (size_t i = 0; i < file_specs.GetSize() && !is_symlink; ++i)
is_symlink = FileSpec::Equal(file_specs.GetFileSpecAtIndex(i),
- local_path_spec, true);
+ local_spec, true);
if (!is_symlink)
- return local_path;
+ return local_spec;
namespace fs = llvm::sys::fs;
- if (fs::get_file_type(local_path_spec.GetPath(), false) !=
+ if (fs::get_file_type(local_spec.GetPath(), false) !=
fs::file_type::symlink_file)
- return local_path;
+ return local_spec;
- FileSpec resolved_local_path_spec;
- const auto error =
- FileSystem::Readlink(local_path_spec, resolved_local_path_spec);
+ FileSpec resolved_symlink;
+ const auto error = FileSystem::Readlink(local_spec, resolved_symlink);
if (error.Success())
- return resolved_local_path_spec.GetCString();
+ return resolved_symlink;
- return nullptr;
+ return local_spec;
}
-DWARFCompileUnit *SymbolFileDWARF::GetBaseCompileUnit() {
+DWARFUnit *SymbolFileDWARF::GetBaseCompileUnit() {
return nullptr;
}
@@ -334,7 +347,7 @@ size_t SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope,
TypeSet type_set;
CompileUnit *comp_unit = NULL;
- DWARFCompileUnit *dwarf_cu = NULL;
+ DWARFUnit *dwarf_cu = NULL;
if (sc_scope)
comp_unit = sc_scope->CalculateSymbolContextCompileUnit();
@@ -382,6 +395,7 @@ SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die) {
switch (tag) {
case DW_TAG_compile_unit:
+ case DW_TAG_partial_unit:
case DW_TAG_subprogram:
case DW_TAG_inlined_subroutine:
case DW_TAG_lexical_block:
@@ -392,20 +406,16 @@ SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die) {
}
SymbolFileDWARF::SymbolFileDWARF(ObjectFile *objfile)
- : SymbolFile(objfile), UserID(0), // Used by SymbolFileDWARFDebugMap to when
- // this class parses .o files to contain
- // the .o file index/ID
+ : SymbolFile(objfile), UserID(uint64_t(DW_INVALID_OFFSET)
+ << 32), // Used by SymbolFileDWARFDebugMap to
+ // when this class parses .o files to
+ // contain the .o file index/ID
m_debug_map_module_wp(), m_debug_map_symfile(NULL), m_data_debug_abbrev(),
m_data_debug_aranges(), m_data_debug_frame(), m_data_debug_info(),
m_data_debug_line(), m_data_debug_macro(), m_data_debug_loc(),
m_data_debug_ranges(), m_data_debug_str(), m_data_apple_names(),
m_data_apple_types(), m_data_apple_namespaces(), m_abbr(), m_info(),
- m_line(), m_apple_names_ap(), m_apple_types_ap(), m_apple_namespaces_ap(),
- m_apple_objc_ap(), m_function_basename_index(),
- m_function_fullname_index(), m_function_method_index(),
- m_function_selector_index(), m_objc_class_selectors_index(),
- m_global_index(), m_type_index(), m_namespace_index(), m_indexed(false),
- m_using_apple_tables(false), m_fetched_external_modules(false),
+ m_line(), m_fetched_external_modules(false),
m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate), m_ranges(),
m_unique_ast_type_map() {}
@@ -438,6 +448,7 @@ TypeSystem *SymbolFileDWARF::GetTypeSystemForLanguage(LanguageType language) {
}
void SymbolFileDWARF::InitializeObject() {
+ Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
ModuleSP module_sp(m_obj_file->GetModule());
if (module_sp) {
const SectionList *section_list = module_sp->GetSectionList();
@@ -448,45 +459,38 @@ void SymbolFileDWARF::InitializeObject() {
m_obj_file->ReadSectionData(section, m_dwarf_data);
}
- get_apple_names_data();
- if (m_data_apple_names.m_data.GetByteSize() > 0) {
- m_apple_names_ap.reset(new DWARFMappedHash::MemoryTable(
- m_data_apple_names.m_data, get_debug_str_data(), ".apple_names"));
- if (m_apple_names_ap->IsValid())
- m_using_apple_tables = true;
- else
- m_apple_names_ap.reset();
- }
- get_apple_types_data();
- if (m_data_apple_types.m_data.GetByteSize() > 0) {
- m_apple_types_ap.reset(new DWARFMappedHash::MemoryTable(
- m_data_apple_types.m_data, get_debug_str_data(), ".apple_types"));
- if (m_apple_types_ap->IsValid())
- m_using_apple_tables = true;
- else
- m_apple_types_ap.reset();
- }
+ if (!GetGlobalPluginProperties()->IgnoreFileIndexes()) {
+ DWARFDataExtractor apple_names, apple_namespaces, apple_types, apple_objc;
+ LoadSectionData(eSectionTypeDWARFAppleNames, apple_names);
+ LoadSectionData(eSectionTypeDWARFAppleNamespaces, apple_namespaces);
+ LoadSectionData(eSectionTypeDWARFAppleTypes, apple_types);
+ LoadSectionData(eSectionTypeDWARFAppleObjC, apple_objc);
- get_apple_namespaces_data();
- if (m_data_apple_namespaces.m_data.GetByteSize() > 0) {
- m_apple_namespaces_ap.reset(new DWARFMappedHash::MemoryTable(
- m_data_apple_namespaces.m_data, get_debug_str_data(),
- ".apple_namespaces"));
- if (m_apple_namespaces_ap->IsValid())
- m_using_apple_tables = true;
- else
- m_apple_namespaces_ap.reset();
- }
+ m_index = AppleDWARFIndex::Create(
+ *GetObjectFile()->GetModule(), apple_names, apple_namespaces,
+ apple_types, apple_objc, get_debug_str_data());
- get_apple_objc_data();
- if (m_data_apple_objc.m_data.GetByteSize() > 0) {
- m_apple_objc_ap.reset(new DWARFMappedHash::MemoryTable(
- m_data_apple_objc.m_data, get_debug_str_data(), ".apple_objc"));
- if (m_apple_objc_ap->IsValid())
- m_using_apple_tables = true;
- else
- m_apple_objc_ap.reset();
+ if (m_index)
+ return;
+
+ DWARFDataExtractor debug_names;
+ LoadSectionData(eSectionTypeDWARFDebugNames, debug_names);
+ if (debug_names.GetByteSize() > 0) {
+ llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>> index_or =
+ DebugNamesDWARFIndex::Create(*GetObjectFile()->GetModule(),
+ debug_names, get_debug_str_data(),
+ DebugInfo());
+ if (index_or) {
+ m_index = std::move(*index_or);
+ return;
+ }
+ LLDB_LOG_ERROR(log, index_or.takeError(),
+ "Unable to read .debug_names data: {0}");
+ }
}
+
+ m_index = llvm::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(),
+ DebugInfo());
}
bool SymbolFileDWARF::SupportedVersion(uint16_t version) {
@@ -501,15 +505,14 @@ uint32_t SymbolFileDWARF::CalculateAbilities() {
if (section_list == NULL)
return 0;
- // On non Apple platforms we might have .debug_types debug info that
- // is created by using "-fdebug-types-section". LLDB currently will try
- // to load this debug info, but it causes crashes during debugging when
- // types are missing since it doesn't know how to parse the info in
- // the .debug_types type units. This causes all complex debug info
- // types to be unresolved. Because this causes LLDB to crash and since
- // it really doesn't provide a solid debuggiung experience, we should
- // disable trying to debug this kind of DWARF until support gets
- // added or deprecated.
+ // On non Apple platforms we might have .debug_types debug info that is
+ // created by using "-fdebug-types-section". LLDB currently will try to
+ // load this debug info, but it causes crashes during debugging when types
+ // are missing since it doesn't know how to parse the info in the
+ // .debug_types type units. This causes all complex debug info types to be
+ // unresolved. Because this causes LLDB to crash and since it really
+ // doesn't provide a solid debuggiung experience, we should disable trying
+ // to debug this kind of DWARF until support gets added or deprecated.
if (section_list->FindSectionByName(ConstString(".debug_types"))) {
m_obj_file->GetModule()->ReportWarning(
"lldb doesn’t support .debug_types debug info");
@@ -561,10 +564,10 @@ uint32_t SymbolFileDWARF::CalculateAbilities() {
if (symfile_dir_cstr) {
if (strcasestr(symfile_dir_cstr, ".dsym")) {
if (m_obj_file->GetType() == ObjectFile::eTypeDebugInfo) {
- // We have a dSYM file that didn't have a any debug info.
- // If the string table has a size of 1, then it was made from
- // an executable with no debug info, or from an executable that
- // was stripped.
+ // We have a dSYM file that didn't have a any debug info. If the
+ // string table has a size of 1, then it was made from an
+ // executable with no debug info, or from an executable that was
+ // stripped.
section =
section_list->FindSectionByType(eSectionTypeDWARFDebugStr, true)
.get();
@@ -664,6 +667,10 @@ const DWARFDataExtractor &SymbolFileDWARF::get_debug_str_offsets_data() {
m_data_debug_str_offsets);
}
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_types_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugTypes, m_data_debug_types);
+}
+
const DWARFDataExtractor &SymbolFileDWARF::get_apple_names_data() {
return GetCachedSectionData(eSectionTypeDWARFAppleNames, m_data_apple_names);
}
@@ -681,6 +688,11 @@ const DWARFDataExtractor &SymbolFileDWARF::get_apple_objc_data() {
return GetCachedSectionData(eSectionTypeDWARFAppleObjC, m_data_apple_objc);
}
+const DWARFDataExtractor &SymbolFileDWARF::get_gnu_debugaltlink() {
+ return GetCachedSectionData(eSectionTypeDWARFGNUDebugAltLink,
+ m_data_gnu_debugaltlink);
+}
+
DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() {
if (m_abbr.get() == NULL) {
const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data();
@@ -716,17 +728,17 @@ const DWARFDebugInfo *SymbolFileDWARF::DebugInfo() const {
return m_info.get();
}
-DWARFCompileUnit *
+DWARFUnit *
SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) {
if (!comp_unit)
return nullptr;
DWARFDebugInfo *info = DebugInfo();
if (info) {
- // Just a normal DWARF file whose user ID for the compile unit is
- // the DWARF offset itself
+ // Just a normal DWARF file whose user ID for the compile unit is the DWARF
+ // offset itself
- DWARFCompileUnit *dwarf_cu =
+ DWARFUnit *dwarf_cu =
info->GetCompileUnit((dw_offset_t)comp_unit->GetID());
if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
dwarf_cu->SetUserData(comp_unit);
@@ -753,7 +765,7 @@ const DWARFDebugRanges *SymbolFileDWARF::DebugRanges() const {
return m_ranges.get();
}
-lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit *dwarf_cu,
+lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFUnit *dwarf_cu,
uint32_t cu_idx) {
CompUnitSP cu_sp;
if (dwarf_cu) {
@@ -772,13 +784,13 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit *dwarf_cu,
} else {
ModuleSP module_sp(m_obj_file->GetModule());
if (module_sp) {
- const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly();
+ const DWARFDIE cu_die = dwarf_cu->DIE();
if (cu_die) {
FileSpec cu_file_spec{cu_die.GetName(), false};
if (cu_file_spec) {
// If we have a full path to the compile unit, we don't need to
- // resolve
- // the file. This can be expensive e.g. when the source files are
+ // resolve the file. This can be expensive e.g. when the source
+ // files are
// NFS mounted.
if (cu_file_spec.IsRelative()) {
const char *cu_comp_dir{
@@ -789,10 +801,11 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit *dwarf_cu,
std::string remapped_file;
if (module_sp->RemapSourceFile(cu_file_spec.GetPath(),
remapped_file))
- cu_file_spec.SetFile(remapped_file, false);
+ cu_file_spec.SetFile(remapped_file, false,
+ FileSpec::Style::native);
}
- LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(
+ LanguageType cu_language = DWARFUnit::LanguageTypeFromDWARF(
cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0));
bool is_optimized = dwarf_cu->GetIsOptimized();
@@ -801,10 +814,8 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit *dwarf_cu,
cu_language, is_optimized ? eLazyBoolYes : eLazyBoolNo));
if (cu_sp) {
// If we just created a compile unit with an invalid file spec,
- // try and get the
- // first entry in the supports files from the line table as that
- // should be the
- // compile unit.
+ // try and get the first entry in the supports files from the
+ // line table as that should be the compile unit.
if (!cu_file_spec) {
cu_file_spec = cu_sp->GetSupportFiles().GetFileSpecAtIndex(1);
if (cu_file_spec) {
@@ -843,7 +854,7 @@ CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) {
CompUnitSP cu_sp;
DWARFDebugInfo *info = DebugInfo();
if (info) {
- DWARFCompileUnit *dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
+ DWARFUnit *dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
if (dwarf_cu)
cu_sp = ParseCompileUnit(dwarf_cu, cu_idx);
}
@@ -876,7 +887,7 @@ bool SymbolFileDWARF::FixupAddress(Address &addr) {
lldb::LanguageType
SymbolFileDWARF::ParseCompileUnitLanguage(const SymbolContext &sc) {
assert(sc.comp_unit);
- DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
if (dwarf_cu)
return dwarf_cu->GetLanguageType();
else
@@ -886,7 +897,7 @@ SymbolFileDWARF::ParseCompileUnitLanguage(const SymbolContext &sc) {
size_t SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc) {
assert(sc.comp_unit);
size_t functions_added = 0;
- DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
if (dwarf_cu) {
DWARFDIECollection function_dies;
const size_t num_functions =
@@ -907,12 +918,12 @@ size_t SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc) {
bool SymbolFileDWARF::ParseCompileUnitSupportFiles(
const SymbolContext &sc, FileSpecList &support_files) {
assert(sc.comp_unit);
- DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
if (dwarf_cu) {
- const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly();
+ const DWARFBaseDIE cu_die = dwarf_cu->GetUnitDIEOnly();
if (cu_die) {
- const char *cu_comp_dir = resolveCompDir(
+ FileSpec cu_comp_dir = resolveCompDir(
cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr));
const dw_offset_t stmt_list = cu_die.GetAttributeValueAsUnsigned(
DW_AT_stmt_list, DW_INVALID_OFFSET);
@@ -931,7 +942,7 @@ bool SymbolFileDWARF::ParseCompileUnitSupportFiles(
bool SymbolFileDWARF::ParseCompileUnitIsOptimized(
const lldb_private::SymbolContext &sc) {
- DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
if (dwarf_cu)
return dwarf_cu->GetIsOptimized();
return false;
@@ -941,14 +952,14 @@ bool SymbolFileDWARF::ParseImportedModules(
const lldb_private::SymbolContext &sc,
std::vector<lldb_private::ConstString> &imported_modules) {
assert(sc.comp_unit);
- DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
if (dwarf_cu) {
if (ClangModulesDeclVendor::LanguageSupportsClangModules(
sc.comp_unit->GetLanguage())) {
UpdateExternalModuleListIfNeeded();
if (sc.comp_unit) {
- const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly();
+ const DWARFDIE die = dwarf_cu->DIE();
if (die) {
for (DWARFDIE child_die = die.GetFirstChild(); child_die;
@@ -998,8 +1009,7 @@ static void ParseDWARFLineTableCallback(dw_offset_t offset,
(ParseDWARFLineTableCallbackInfo *)userData;
LineTable *line_table = info->line_table;
- // If this is our first time here, we need to create a
- // sequence container.
+ // If this is our first time here, we need to create a sequence container.
if (!info->sequence_ap.get()) {
info->sequence_ap.reset(line_table->CreateLineSequenceContainer());
assert(info->sequence_ap.get());
@@ -1022,9 +1032,9 @@ bool SymbolFileDWARF::ParseCompileUnitLineTable(const SymbolContext &sc) {
if (sc.comp_unit->GetLineTable() != NULL)
return true;
- DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
if (dwarf_cu) {
- const DWARFDIE dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
+ const DWARFBaseDIE dwarf_cu_die = dwarf_cu->GetUnitDIEOnly();
if (dwarf_cu_die) {
const dw_offset_t cu_line_offset =
dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list,
@@ -1063,10 +1073,10 @@ bool SymbolFileDWARF::ParseCompileUnitLineTable(const SymbolContext &sc) {
&info);
SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
if (debug_map_symfile) {
- // We have an object file that has a line table with addresses
- // that are not linked. We need to link the line table and convert
- // the addresses that are relative to the .o file into addresses
- // for the main executable.
+ // We have an object file that has a line table with addresses that
+ // are not linked. We need to link the line table and convert the
+ // addresses that are relative to the .o file into addresses for
+ // the main executable.
sc.comp_unit->SetLineTable(
debug_map_symfile->LinkOSOLineTable(this, line_table_ap.get()));
} else {
@@ -1105,11 +1115,11 @@ SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) {
bool SymbolFileDWARF::ParseCompileUnitDebugMacros(const SymbolContext &sc) {
assert(sc.comp_unit);
- DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
if (dwarf_cu == nullptr)
return false;
- const DWARFDIE dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
+ const DWARFBaseDIE dwarf_cu_die = dwarf_cu->GetUnitDIEOnly();
if (!dwarf_cu_die)
return false;
@@ -1142,9 +1152,9 @@ size_t SymbolFileDWARF::ParseFunctionBlocks(const SymbolContext &sc,
case DW_TAG_lexical_block: {
Block *block = NULL;
if (tag == DW_TAG_subprogram) {
- // Skip any DW_TAG_subprogram DIEs that are inside
- // of a normal or inlined functions. These will be
- // parsed on their own as separate entities.
+ // Skip any DW_TAG_subprogram DIEs that are inside of a normal or
+ // inlined functions. These will be parsed on their own as separate
+ // entities.
if (depth > 0)
break;
@@ -1172,18 +1182,14 @@ size_t SymbolFileDWARF::ParseFunctionBlocks(const SymbolContext &sc,
assert(subprogram_low_pc == LLDB_INVALID_ADDRESS);
subprogram_low_pc = ranges.GetMinRangeBase(0);
} else if (tag == DW_TAG_inlined_subroutine) {
- // We get called here for inlined subroutines in two ways.
- // The first time is when we are making the Function object
- // for this inlined concrete instance. Since we're creating a top
- // level block at
+ // We get called here for inlined subroutines in two ways. The first
+ // time is when we are making the Function object for this inlined
+ // concrete instance. Since we're creating a top level block at
// here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we
- // need to
- // adjust the containing address.
- // The second time is when we are parsing the blocks inside the
- // function that contains
- // the inlined concrete instance. Since these will be blocks inside
- // the containing "real"
- // function the offset will be for that function.
+ // need to adjust the containing address. The second time is when we
+ // are parsing the blocks inside the function that contains the
+ // inlined concrete instance. Since these will be blocks inside the
+ // containing "real" function the offset will be for that function.
if (subprogram_low_pc == LLDB_INVALID_ADDRESS) {
subprogram_low_pc = ranges.GetMinRangeBase(0);
}
@@ -1238,9 +1244,9 @@ size_t SymbolFileDWARF::ParseFunctionBlocks(const SymbolContext &sc,
break;
}
- // Only parse siblings of the block if we are not at depth zero. A depth
- // of zero indicates we are currently parsing the top level
- // DW_TAG_subprogram DIE
+ // Only parse siblings of the block if we are not at depth zero. A depth of
+ // zero indicates we are currently parsing the top level DW_TAG_subprogram
+ // DIE
if (depth == 0)
die.Clear();
@@ -1286,12 +1292,12 @@ void SymbolFileDWARF::ParseDeclsForContext(CompilerDeclContext decl_ctx) {
}
SymbolFileDWARF *SymbolFileDWARF::GetDWARFForUID(lldb::user_id_t uid) {
- // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API
- // we must make sure we use the correct DWARF file when resolving things.
- // On MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
- // SymbolFileDWARF classes, one for each .o file. We can often end up
- // with references to other DWARF objects and we must be ready to receive
- // a "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
+ // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we
+ // must make sure we use the correct DWARF file when resolving things. On
+ // MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
+ // SymbolFileDWARF classes, one for each .o file. We can often end up with
+ // references to other DWARF objects and we must be ready to receive a
+ // "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
// instance.
SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile();
if (debug_map)
@@ -1302,12 +1308,12 @@ SymbolFileDWARF *SymbolFileDWARF::GetDWARFForUID(lldb::user_id_t uid) {
DWARFDIE
SymbolFileDWARF::GetDIEFromUID(lldb::user_id_t uid) {
- // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API
- // we must make sure we use the correct DWARF file when resolving things.
- // On MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
- // SymbolFileDWARF classes, one for each .o file. We can often end up
- // with references to other DWARF objects and we must be ready to receive
- // a "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
+ // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we
+ // must make sure we use the correct DWARF file when resolving things. On
+ // MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
+ // SymbolFileDWARF classes, one for each .o file. We can often end up with
+ // references to other DWARF objects and we must be ready to receive a
+ // "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
// instance.
SymbolFileDWARF *dwarf = GetDWARFForUID(uid);
if (dwarf)
@@ -1316,9 +1322,9 @@ SymbolFileDWARF::GetDIEFromUID(lldb::user_id_t uid) {
}
CompilerDecl SymbolFileDWARF::GetDeclForUID(lldb::user_id_t type_uid) {
- // Anytime we have a lldb::user_id_t, we must get the DIE by
- // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
- // the SymbolFileDWARF::GetDIEFromUID() for details.
+ // Anytime we have a lldb::user_id_t, we must get the DIE by calling
+ // SymbolFileDWARF::GetDIEFromUID(). See comments inside the
+ // SymbolFileDWARF::GetDIEFromUID() for details.
DWARFDIE die = GetDIEFromUID(type_uid);
if (die)
return die.GetDecl();
@@ -1327,9 +1333,9 @@ CompilerDecl SymbolFileDWARF::GetDeclForUID(lldb::user_id_t type_uid) {
CompilerDeclContext
SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid) {
- // Anytime we have a lldb::user_id_t, we must get the DIE by
- // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
- // the SymbolFileDWARF::GetDIEFromUID() for details.
+ // Anytime we have a lldb::user_id_t, we must get the DIE by calling
+ // SymbolFileDWARF::GetDIEFromUID(). See comments inside the
+ // SymbolFileDWARF::GetDIEFromUID() for details.
DWARFDIE die = GetDIEFromUID(type_uid);
if (die)
return die.GetDeclContext();
@@ -1338,9 +1344,9 @@ SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid) {
CompilerDeclContext
SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
- // Anytime we have a lldb::user_id_t, we must get the DIE by
- // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
- // the SymbolFileDWARF::GetDIEFromUID() for details.
+ // Anytime we have a lldb::user_id_t, we must get the DIE by calling
+ // SymbolFileDWARF::GetDIEFromUID(). See comments inside the
+ // SymbolFileDWARF::GetDIEFromUID() for details.
DWARFDIE die = GetDIEFromUID(type_uid);
if (die)
return die.GetContainingDeclContext();
@@ -1348,9 +1354,9 @@ SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
}
Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) {
- // Anytime we have a lldb::user_id_t, we must get the DIE by
- // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
- // the SymbolFileDWARF::GetDIEFromUID() for details.
+ // Anytime we have a lldb::user_id_t, we must get the DIE by calling
+ // SymbolFileDWARF::GetDIEFromUID(). See comments inside the
+ // SymbolFileDWARF::GetDIEFromUID() for details.
DWARFDIE type_die = GetDIEFromUID(type_uid);
if (type_die)
return type_die.ResolveType();
@@ -1371,9 +1377,9 @@ Type *SymbolFileDWARF::ResolveTypeUID(const DWARFDIE &die,
log, "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s'",
die.GetOffset(), die.GetTagAsCString(), die.GetName());
- // We might be coming in in the middle of a type tree (a class
- // within a class, an enum within a class), so parse any needed
- // parent DIEs before we get to this one...
+ // We might be coming in in the middle of a type tree (a class within a
+ // class, an enum within a class), so parse any needed parent DIEs before
+ // we get to this one...
DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(die);
if (decl_ctx_die) {
if (log) {
@@ -1401,8 +1407,8 @@ Type *SymbolFileDWARF::ResolveTypeUID(const DWARFDIE &die,
}
// This function is used when SymbolFileDWARFDebugMap owns a bunch of
-// SymbolFileDWARF objects to detect if this DWARF file is the one that
-// can resolve a compiler_type.
+// SymbolFileDWARF objects to detect if this DWARF file is the one that can
+// resolve a compiler_type.
bool SymbolFileDWARF::HasForwardDeclForClangType(
const CompilerType &compiler_type) {
CompilerType compiler_type_no_qualifiers =
@@ -1448,12 +1454,10 @@ bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) {
DWARFDIE dwarf_die = GetDIE(die_it->getSecond());
if (dwarf_die) {
- // Once we start resolving this type, remove it from the forward declaration
- // map in case anyone child members or other types require this type to get
- // resolved.
- // The type will get resolved when all of the calls to
- // SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
- // are done.
+ // Once we start resolving this type, remove it from the forward
+ // declaration map in case anyone child members or other types require this
+ // type to get resolved. The type will get resolved when all of the calls
+ // to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition are done.
GetForwardDeclClangTypeToDie().erase(die_it);
Type *type = GetDIEToType().lookup(dwarf_die.GetDIE());
@@ -1494,12 +1498,12 @@ Type *SymbolFileDWARF::ResolveType(const DWARFDIE &die,
}
CompileUnit *
-SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit *dwarf_cu,
+SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFUnit *dwarf_cu,
uint32_t cu_idx) {
// Check if the symbol vendor already knows about this compile unit?
if (dwarf_cu->GetUserData() == NULL) {
- // The symbol vendor doesn't know about this compile unit, we
- // need to parse and add it to the symbol vendor object.
+ // The symbol vendor doesn't know about this compile unit, we need to parse
+ // and add it to the symbol vendor object.
return ParseCompileUnit(dwarf_cu, cu_idx).get();
}
return (CompileUnit *)dwarf_cu->GetUserData();
@@ -1508,15 +1512,7 @@ SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit *dwarf_cu,
size_t SymbolFileDWARF::GetObjCMethodDIEOffsets(ConstString class_name,
DIEArray &method_die_offsets) {
method_die_offsets.clear();
- if (m_using_apple_tables) {
- if (m_apple_objc_ap.get())
- m_apple_objc_ap->FindByName(class_name.GetCString(), method_die_offsets);
- } else {
- if (!m_indexed)
- Index();
-
- m_objc_class_selectors_index.Find(class_name, method_die_offsets);
- }
+ m_index->GetObjCMethods(class_name, method_die_offsets);
return method_die_offsets.size();
}
@@ -1560,9 +1556,9 @@ SymbolFileDWARF::GetDIE(const DIERef &die_ref) {
std::unique_ptr<SymbolFileDWARFDwo>
SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
- DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die) {
+ DWARFUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die) {
// If we are using a dSYM file, we never want the standard DWO files since
- // the -gmodule support uses the same DWO machanism to specify full debug
+ // the -gmodules support uses the same DWO machanism to specify full debug
// info files for modules.
if (GetDebugMapSymfile())
return nullptr;
@@ -1589,7 +1585,7 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
if (!comp_dir)
return nullptr;
- dwo_file.SetFile(comp_dir, true);
+ dwo_file.SetFile(comp_dir, true, FileSpec::Style::native);
dwo_file.AppendPathComponent(dwo_name);
}
@@ -1617,9 +1613,9 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
const uint32_t num_compile_units = GetNumCompileUnits();
for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
- DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+ DWARFUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
- const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly();
+ const DWARFBaseDIE die = dwarf_cu->GetUnitDIEOnly();
if (die && die.HasChildren() == false) {
const char *name = die.GetAttributeValueAsString(DW_AT_name, nullptr);
@@ -1632,35 +1628,35 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
die.GetAttributeValueAsString(DW_AT_GNU_dwo_name, nullptr);
if (dwo_path) {
ModuleSpec dwo_module_spec;
- dwo_module_spec.GetFileSpec().SetFile(dwo_path, false);
+ dwo_module_spec.GetFileSpec().SetFile(dwo_path, false,
+ FileSpec::Style::native);
if (dwo_module_spec.GetFileSpec().IsRelative()) {
const char *comp_dir =
die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr);
if (comp_dir) {
- dwo_module_spec.GetFileSpec().SetFile(comp_dir, true);
+ dwo_module_spec.GetFileSpec().SetFile(comp_dir, true,
+ FileSpec::Style::native);
dwo_module_spec.GetFileSpec().AppendPathComponent(dwo_path);
}
}
dwo_module_spec.GetArchitecture() =
m_obj_file->GetModule()->GetArchitecture();
- // When LLDB loads "external" modules it looks at the
- // presence of DW_AT_GNU_dwo_name.
- // However, when the already created module
- // (corresponding to .dwo itself) is being processed,
- // it will see the presence of DW_AT_GNU_dwo_name
- // (which contains the name of dwo file) and
- // will try to call ModuleList::GetSharedModule again.
- // In some cases (i.e. for empty files) Clang 4.0
- // generates a *.dwo file which has DW_AT_GNU_dwo_name,
- // but no DW_AT_comp_dir. In this case the method
- // ModuleList::GetSharedModule will fail and
- // the warning will be printed. However, as one can notice
- // in this case we don't actually need to try to load the already
- // loaded module (corresponding to .dwo) so we simply skip it.
+ // When LLDB loads "external" modules it looks at the presence of
+ // DW_AT_GNU_dwo_name. However, when the already created module
+ // (corresponding to .dwo itself) is being processed, it will see
+ // the presence of DW_AT_GNU_dwo_name (which contains the name of
+ // dwo file) and will try to call ModuleList::GetSharedModule
+ // again. In some cases (i.e. for empty files) Clang 4.0 generates
+ // a *.dwo file which has DW_AT_GNU_dwo_name, but no
+ // DW_AT_comp_dir. In this case the method
+ // ModuleList::GetSharedModule will fail and the warning will be
+ // printed. However, as one can notice in this case we don't
+ // actually need to try to load the already loaded module
+ // (corresponding to .dwo) so we simply skip it.
if (m_obj_file->GetFileSpec()
.GetFileNameExtension()
- .GetStringRef() == "dwo" &&
+ .GetStringRef() == ".dwo" &&
llvm::StringRef(m_obj_file->GetFileSpec().GetPath())
.endswith(dwo_module_spec.GetFileSpec().GetPath())) {
continue;
@@ -1751,13 +1747,11 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
const dw_offset_t cu_offset =
debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
if (cu_offset == DW_INVALID_OFFSET) {
- // Global variables are not in the compile unit address ranges. The only
- // way to
- // currently find global variables is to iterate over the
- // .debug_pubnames or the
- // __apple_names table and find all items in there that point to
- // DW_TAG_variable
- // DIEs and then find the address that matches.
+ // Global variables are not in the compile unit address ranges. The
+ // only way to currently find global variables is to iterate over the
+ // .debug_pubnames or the __apple_names table and find all items in
+ // there that point to DW_TAG_variable DIEs and then find the address
+ // that matches.
if (resolve_scope & eSymbolContextVariable) {
GlobalVariableMap &map = GetGlobalAranges();
const GlobalVariableMap::Entry *entry =
@@ -1774,7 +1768,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
}
} else {
uint32_t cu_idx = DW_INVALID_INDEX;
- DWARFCompileUnit *dwarf_cu =
+ DWARFUnit *dwarf_cu =
debug_info->GetCompileUnit(cu_offset, &cu_idx);
if (dwarf_cu) {
sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
@@ -1825,13 +1819,10 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
LineTable *line_table = sc.comp_unit->GetLineTable();
if (line_table != NULL) {
// And address that makes it into this function should be in
- // terms
- // of this debug file if there is no debug map, or it will be an
- // address in the .o file which needs to be fixed up to be in
- // terms
- // of the debug map executable. Either way, calling
- // FixupAddress()
- // will work for us.
+ // terms of this debug file if there is no debug map, or it
+ // will be an address in the .o file which needs to be fixed up
+ // to be in terms of the debug map executable. Either way,
+ // calling FixupAddress() will work for us.
Address exe_so_addr(so_addr);
if (FixupAddress(exe_so_addr)) {
if (line_table->FindLineEntryByAddress(exe_so_addr,
@@ -1845,11 +1836,11 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
if (force_check_line_table &&
!(resolved & eSymbolContextLineEntry)) {
// We might have had a compile unit that had discontiguous
- // address ranges where the gaps are symbols that don't have
- // any debug info. Discontiguous compile unit address ranges
- // should only happen when there aren't other functions from
- // other compile units in these gaps. This helps keep the size
- // of the aranges down.
+ // address ranges where the gaps are symbols that don't have any
+ // debug info. Discontiguous compile unit address ranges should
+ // only happen when there aren't other functions from other
+ // compile units in these gaps. This helps keep the size of the
+ // aranges down.
sc.comp_unit = NULL;
resolved &= ~eSymbolContextCompUnit;
}
@@ -1876,7 +1867,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,
DWARFDebugInfo *debug_info = DebugInfo();
if (debug_info) {
uint32_t cu_idx;
- DWARFCompileUnit *dwarf_cu = NULL;
+ DWARFUnit *dwarf_cu = NULL;
for (cu_idx = 0;
(dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL;
@@ -1891,8 +1882,8 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,
if (sc.comp_unit) {
uint32_t file_idx = UINT32_MAX;
- // If we are looking for inline functions only and we don't
- // find it in the support files, we are done.
+ // If we are looking for inline functions only and we don't find it
+ // in the support files, we are done.
if (check_inlines) {
file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex(
1, file_spec, true);
@@ -1904,8 +1895,8 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,
LineTable *line_table = sc.comp_unit->GetLineTable();
if (line_table != NULL && line != 0) {
- // We will have already looked up the file index if
- // we are searching for inline entries.
+ // We will have already looked up the file index if we are
+ // searching for inline entries.
if (!check_inlines)
file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex(
1, file_spec, true);
@@ -1962,16 +1953,14 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,
}
} else if (file_spec_matches_cu_file_spec && !check_inlines) {
// only append the context if we aren't looking for inline call
- // sites
- // by file and line and if the file spec matches that of the
- // compile unit
+ // sites by file and line and if the file spec matches that of
+ // the compile unit
sc_list.Append(sc);
}
} else if (file_spec_matches_cu_file_spec && !check_inlines) {
// only append the context if we aren't looking for inline call
- // sites
- // by file and line and if the file spec matches that of the
- // compile unit
+ // sites by file and line and if the file spec matches that of
+ // the compile unit
sc_list.Append(sc);
}
@@ -1988,143 +1977,15 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,
void SymbolFileDWARF::PreloadSymbols() {
std::lock_guard<std::recursive_mutex> guard(
GetObjectFile()->GetModule()->GetMutex());
- Index();
-}
-
-void SymbolFileDWARF::Index() {
- if (m_indexed)
- return;
- m_indexed = true;
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(
- func_cat, "SymbolFileDWARF::Index (%s)",
- GetObjectFile()->GetFileSpec().GetFilename().AsCString("<Unknown>"));
-
- DWARFDebugInfo *debug_info = DebugInfo();
- if (debug_info) {
- const uint32_t num_compile_units = GetNumCompileUnits();
- if (num_compile_units == 0)
- return;
-
- std::vector<NameToDIE> function_basename_index(num_compile_units);
- std::vector<NameToDIE> function_fullname_index(num_compile_units);
- std::vector<NameToDIE> function_method_index(num_compile_units);
- std::vector<NameToDIE> function_selector_index(num_compile_units);
- std::vector<NameToDIE> objc_class_selectors_index(num_compile_units);
- std::vector<NameToDIE> global_index(num_compile_units);
- std::vector<NameToDIE> type_index(num_compile_units);
- std::vector<NameToDIE> namespace_index(num_compile_units);
-
- // std::vector<bool> might be implemented using bit test-and-set, so use
- // uint8_t instead.
- std::vector<uint8_t> clear_cu_dies(num_compile_units, false);
- auto parser_fn = [debug_info, &function_basename_index,
- &function_fullname_index, &function_method_index,
- &function_selector_index, &objc_class_selectors_index,
- &global_index, &type_index,
- &namespace_index](size_t cu_idx) {
- DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
- if (dwarf_cu) {
- dwarf_cu->Index(
- function_basename_index[cu_idx], function_fullname_index[cu_idx],
- function_method_index[cu_idx], function_selector_index[cu_idx],
- objc_class_selectors_index[cu_idx], global_index[cu_idx],
- type_index[cu_idx], namespace_index[cu_idx]);
- }
- };
-
- auto extract_fn = [debug_info, &clear_cu_dies](size_t cu_idx) {
- DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
- if (dwarf_cu) {
- // dwarf_cu->ExtractDIEsIfNeeded(false) will return zero if the
- // DIEs for a compile unit have already been parsed.
- if (dwarf_cu->ExtractDIEsIfNeeded(false) > 1)
- clear_cu_dies[cu_idx] = true;
- }
- };
-
- // Create a task runner that extracts dies for each DWARF compile unit in a
- // separate thread
- //----------------------------------------------------------------------
- // First figure out which compile units didn't have their DIEs already
- // parsed and remember this. If no DIEs were parsed prior to this index
- // function call, we are going to want to clear the CU dies after we
- // are done indexing to make sure we don't pull in all DWARF dies, but
- // we need to wait until all compile units have been indexed in case
- // a DIE in one compile unit refers to another and the indexes accesses
- // those DIEs.
- //----------------------------------------------------------------------
- TaskMapOverInt(0, num_compile_units, extract_fn);
-
- // Now create a task runner that can index each DWARF compile unit in a
- // separate
- // thread so we can index quickly.
-
- TaskMapOverInt(0, num_compile_units, parser_fn);
-
- auto finalize_fn = [](NameToDIE &index, std::vector<NameToDIE> &srcs) {
- for (auto &src : srcs)
- index.Append(src);
- index.Finalize();
- };
-
- TaskPool::RunTasks(
- [&]() {
- finalize_fn(m_function_basename_index, function_basename_index);
- },
- [&]() {
- finalize_fn(m_function_fullname_index, function_fullname_index);
- },
- [&]() { finalize_fn(m_function_method_index, function_method_index); },
- [&]() {
- finalize_fn(m_function_selector_index, function_selector_index);
- },
- [&]() {
- finalize_fn(m_objc_class_selectors_index, objc_class_selectors_index);
- },
- [&]() { finalize_fn(m_global_index, global_index); },
- [&]() { finalize_fn(m_type_index, type_index); },
- [&]() { finalize_fn(m_namespace_index, namespace_index); });
-
- //----------------------------------------------------------------------
- // Keep memory down by clearing DIEs for any compile units if indexing
- // caused us to load the compile unit's DIEs.
- //----------------------------------------------------------------------
- for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
- if (clear_cu_dies[cu_idx])
- debug_info->GetCompileUnitAtIndex(cu_idx)->ClearDIEs(true);
- }
-
-#if defined(ENABLE_DEBUG_PRINTF)
- StreamFile s(stdout, false);
- s.Printf("DWARF index for '%s':",
- GetObjectFile()->GetFileSpec().GetPath().c_str());
- s.Printf("\nFunction basenames:\n");
- m_function_basename_index.Dump(&s);
- s.Printf("\nFunction fullnames:\n");
- m_function_fullname_index.Dump(&s);
- s.Printf("\nFunction methods:\n");
- m_function_method_index.Dump(&s);
- s.Printf("\nFunction selectors:\n");
- m_function_selector_index.Dump(&s);
- s.Printf("\nObjective C class selectors:\n");
- m_objc_class_selectors_index.Dump(&s);
- s.Printf("\nGlobals and statics:\n");
- m_global_index.Dump(&s);
- s.Printf("\nTypes:\n");
- m_type_index.Dump(&s);
- s.Printf("\nNamespaces:\n");
- m_namespace_index.Dump(&s);
-#endif
- }
+ m_index->Preload();
}
bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile(
const lldb_private::CompilerDeclContext *decl_ctx) {
if (decl_ctx == nullptr || !decl_ctx->IsValid()) {
- // Invalid namespace decl which means we aren't matching only things
- // in this symbol file, so return true to indicate it matches this
- // symbol file.
+ // Invalid namespace decl which means we aren't matching only things in
+ // this symbol file, so return true to indicate it matches this symbol
+ // file.
return true;
}
@@ -2146,14 +2007,15 @@ bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile(
uint32_t SymbolFileDWARF::FindGlobalVariables(
const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches, VariableList &variables) {
+ uint32_t max_matches, VariableList &variables) {
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
if (log)
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", "
- "parent_decl_ctx=%p, append=%u, max_matches=%u, variables)",
- name.GetCString(), static_cast<const void *>(parent_decl_ctx), append,
+ log,
+ "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", "
+ "parent_decl_ctx=%p, max_matches=%u, variables)",
+ name.GetCString(), static_cast<const void *>(parent_decl_ctx),
max_matches);
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
@@ -2163,42 +2025,28 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(
if (info == NULL)
return 0;
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- variables.Clear();
-
- // Remember how many variables are in the list before we search in case
- // we are appending the results to a variable list.
+ // Remember how many variables are in the list before we search.
const uint32_t original_size = variables.GetSize();
- DIEArray die_offsets;
-
- if (m_using_apple_tables) {
- if (m_apple_names_ap.get()) {
- const char *name_cstr = name.GetCString();
- llvm::StringRef basename;
- llvm::StringRef context;
-
- if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
- basename))
- basename = name_cstr;
-
- m_apple_names_ap->FindByName(basename.data(), die_offsets);
- }
- } else {
- // Index the DWARF if we haven't already
- if (!m_indexed)
- Index();
+ llvm::StringRef basename;
+ llvm::StringRef context;
- m_global_index.Find(name, die_offsets);
- }
+ if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name.GetCString(),
+ context, basename))
+ basename = name.GetStringRef();
+ DIEArray die_offsets;
+ m_index->GetGlobalVariables(ConstString(basename), die_offsets);
const size_t num_die_matches = die_offsets.size();
if (num_die_matches) {
SymbolContext sc;
sc.module_sp = m_obj_file->GetModule();
assert(sc.module_sp);
+ // Loop invariant: Variables up to this index have been checked for context
+ // matches.
+ uint32_t pruned_idx = original_size;
+
bool done = false;
for (size_t i = 0; i < num_die_matches && !done; ++i) {
const DIERef &die_ref = die_offsets[i];
@@ -2229,18 +2077,21 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(
ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false,
&variables);
+ while (pruned_idx < variables.GetSize()) {
+ VariableSP var_sp = variables.GetVariableAtIndex(pruned_idx);
+ if (var_sp->GetName().GetStringRef().contains(name.GetStringRef()))
+ ++pruned_idx;
+ else
+ variables.RemoveVariableAtIndex(pruned_idx);
+ }
if (variables.GetSize() - original_size >= max_matches)
done = true;
} break;
}
} else {
- if (m_using_apple_tables) {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
- "the DWARF debug information has been modified (.apple_names "
- "accelerator table had bad die 0x%8.8x for '%s')\n",
- die_ref.die_offset, name.GetCString());
- }
+ m_index->ReportInvalidDIEOffset(die_ref.die_offset,
+ name.GetStringRef());
}
}
}
@@ -2249,54 +2100,37 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(
const uint32_t num_matches = variables.GetSize() - original_size;
if (log && num_matches > 0) {
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", "
- "parent_decl_ctx=%p, append=%u, max_matches=%u, variables) => %u",
- name.GetCString(), static_cast<const void *>(parent_decl_ctx), append,
+ log,
+ "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", "
+ "parent_decl_ctx=%p, max_matches=%u, variables) => %u",
+ name.GetCString(), static_cast<const void *>(parent_decl_ctx),
max_matches, num_matches);
}
return num_matches;
}
uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression &regex,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
VariableList &variables) {
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
if (log) {
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindGlobalVariables (regex=\"%s\", append=%u, "
- "max_matches=%u, variables)",
- regex.GetText().str().c_str(), append, max_matches);
+ log,
+ "SymbolFileDWARF::FindGlobalVariables (regex=\"%s\", "
+ "max_matches=%u, variables)",
+ regex.GetText().str().c_str(), max_matches);
}
DWARFDebugInfo *info = DebugInfo();
if (info == NULL)
return 0;
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- variables.Clear();
-
- // Remember how many variables are in the list before we search in case
- // we are appending the results to a variable list.
+ // Remember how many variables are in the list before we search.
const uint32_t original_size = variables.GetSize();
DIEArray die_offsets;
-
- if (m_using_apple_tables) {
- if (m_apple_names_ap.get()) {
- DWARFMappedHash::DIEInfoArray hash_data_array;
- if (m_apple_names_ap->AppendAllDIEsThatMatchingRegex(regex,
- hash_data_array))
- DWARFMappedHash::ExtractDIEArray(hash_data_array, die_offsets);
- }
- } else {
- // Index the DWARF if we haven't already
- if (!m_indexed)
- Index();
-
- m_global_index.Find(regex, die_offsets);
- }
+ m_index->GetGlobalVariables(regex, die_offsets);
SymbolContext sc;
sc.module_sp = m_obj_file->GetModule();
@@ -2315,14 +2149,8 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression &regex,
if (variables.GetSize() - original_size >= max_matches)
break;
- } else {
- if (m_using_apple_tables) {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
- "the DWARF debug information has been modified (.apple_names "
- "accelerator table had bad die 0x%8.8x for regex '%s')\n",
- die_ref.die_offset, regex.GetText().str().c_str());
- }
- }
+ } else
+ m_index->ReportInvalidDIEOffset(die_ref.die_offset, regex.GetText());
}
}
@@ -2330,13 +2158,6 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression &regex,
return variables.GetSize() - original_size;
}
-bool SymbolFileDWARF::ResolveFunction(const DIERef &die_ref,
- bool include_inlines,
- SymbolContextList &sc_list) {
- DWARFDIE die = DebugInfo()->GetDIE(die_ref);
- return ResolveFunction(die, include_inlines, sc_list);
-}
-
bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die,
bool include_inlines,
SymbolContextList &sc_list) {
@@ -2390,54 +2211,11 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die,
return false;
}
-void SymbolFileDWARF::FindFunctions(const ConstString &name,
- const NameToDIE &name_to_die,
- bool include_inlines,
- SymbolContextList &sc_list) {
- DIEArray die_offsets;
- if (name_to_die.Find(name, die_offsets)) {
- ParseFunctions(die_offsets, include_inlines, sc_list);
- }
-}
-
-void SymbolFileDWARF::FindFunctions(const RegularExpression &regex,
- const NameToDIE &name_to_die,
- bool include_inlines,
- SymbolContextList &sc_list) {
- DIEArray die_offsets;
- if (name_to_die.Find(regex, die_offsets)) {
- ParseFunctions(die_offsets, include_inlines, sc_list);
- }
-}
-
-void SymbolFileDWARF::FindFunctions(
- const RegularExpression &regex,
- const DWARFMappedHash::MemoryTable &memory_table, bool include_inlines,
- SymbolContextList &sc_list) {
- DIEArray die_offsets;
- DWARFMappedHash::DIEInfoArray hash_data_array;
- if (memory_table.AppendAllDIEsThatMatchingRegex(regex, hash_data_array)) {
- DWARFMappedHash::ExtractDIEArray(hash_data_array, die_offsets);
- ParseFunctions(die_offsets, include_inlines, sc_list);
- }
-}
-
-void SymbolFileDWARF::ParseFunctions(const DIEArray &die_offsets,
- bool include_inlines,
- SymbolContextList &sc_list) {
- const size_t num_matches = die_offsets.size();
- if (num_matches) {
- for (size_t i = 0; i < num_matches; ++i)
- ResolveFunction(die_offsets[i], include_inlines, sc_list);
- }
-}
-
bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext *decl_ctx,
const DWARFDIE &die) {
// If we have no parent decl context to match this DIE matches, and if the
- // parent
- // decl context isn't valid, we aren't trying to look for any particular decl
- // context so any die matches.
+ // parent decl context isn't valid, we aren't trying to look for any
+ // particular decl context so any die matches.
if (decl_ctx == nullptr || !decl_ctx->IsValid())
return true;
@@ -2486,10 +2264,8 @@ SymbolFileDWARF::FindFunctions(const ConstString &name,
if (name.IsEmpty())
return 0;
- // Remember how many sc_list are in the list before we search in case
- // we are appending the results to a variable list.
-
- const char *name_cstr = name.GetCString();
+ // Remember how many sc_list are in the list before we search in case we are
+ // appending the results to a variable list.
const uint32_t original_size = sc_list.GetSize();
@@ -2497,228 +2273,17 @@ SymbolFileDWARF::FindFunctions(const ConstString &name,
if (info == NULL)
return 0;
- std::set<const DWARFDebugInfoEntry *> resolved_dies;
- if (m_using_apple_tables) {
- if (m_apple_names_ap.get()) {
-
- DIEArray die_offsets;
-
- uint32_t num_matches = 0;
-
- if (name_type_mask & eFunctionNameTypeFull) {
- // If they asked for the full name, match what they typed. At some
- // point we may
- // want to canonicalize this (strip double spaces, etc. For now, we
- // just add all the
- // dies that we find by exact match.
- num_matches = m_apple_names_ap->FindByName(name_cstr, die_offsets);
- for (uint32_t i = 0; i < num_matches; i++) {
- const DIERef &die_ref = die_offsets[i];
- DWARFDIE die = info->GetDIE(die_ref);
- if (die) {
- if (!DIEInDeclContext(parent_decl_ctx, die))
- continue; // The containing decl contexts don't match
-
- if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) {
- if (ResolveFunction(die, include_inlines, sc_list))
- resolved_dies.insert(die.GetDIE());
- }
- } else {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
- "the DWARF debug information has been modified (.apple_names "
- "accelerator table had bad die 0x%8.8x for '%s')",
- die_ref.die_offset, name_cstr);
- }
- }
- }
-
- if (name_type_mask & eFunctionNameTypeSelector) {
- if (parent_decl_ctx && parent_decl_ctx->IsValid())
- return 0; // no selectors in namespaces
-
- num_matches = m_apple_names_ap->FindByName(name_cstr, die_offsets);
- // Now make sure these are actually ObjC methods. In this case we can
- // simply look up the name,
- // and if it is an ObjC method name, we're good.
-
- for (uint32_t i = 0; i < num_matches; i++) {
- const DIERef &die_ref = die_offsets[i];
- DWARFDIE die = info->GetDIE(die_ref);
- if (die) {
- const char *die_name = die.GetName();
- if (ObjCLanguage::IsPossibleObjCMethodName(die_name)) {
- if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) {
- if (ResolveFunction(die, include_inlines, sc_list))
- resolved_dies.insert(die.GetDIE());
- }
- }
- } else {
- GetObjectFile()->GetModule()->ReportError(
- "the DWARF debug information has been modified (.apple_names "
- "accelerator table had bad die 0x%8.8x for '%s')",
- die_ref.die_offset, name_cstr);
- }
- }
- die_offsets.clear();
- }
-
- if (((name_type_mask & eFunctionNameTypeMethod) && !parent_decl_ctx) ||
- name_type_mask & eFunctionNameTypeBase) {
- // The apple_names table stores just the "base name" of C++ methods in
- // the table. So we have to
- // extract the base name, look that up, and if there is any other
- // information in the name we were
- // passed in we have to post-filter based on that.
-
- // FIXME: Arrange the logic above so that we don't calculate the base
- // name twice:
- num_matches = m_apple_names_ap->FindByName(name_cstr, die_offsets);
-
- for (uint32_t i = 0; i < num_matches; i++) {
- const DIERef &die_ref = die_offsets[i];
- DWARFDIE die = info->GetDIE(die_ref);
- if (die) {
- if (!DIEInDeclContext(parent_decl_ctx, die))
- continue; // The containing decl contexts don't match
-
- // If we get to here, the die is good, and we should add it:
- if (resolved_dies.find(die.GetDIE()) == resolved_dies.end() &&
- ResolveFunction(die, include_inlines, sc_list)) {
- bool keep_die = true;
- if ((name_type_mask &
- (eFunctionNameTypeBase | eFunctionNameTypeMethod)) !=
- (eFunctionNameTypeBase | eFunctionNameTypeMethod)) {
- // We are looking for either basenames or methods, so we need to
- // trim out the ones we won't want by looking at the type
- SymbolContext sc;
- if (sc_list.GetLastContext(sc)) {
- if (sc.block) {
- // We have an inlined function
- } else if (sc.function) {
- Type *type = sc.function->GetType();
-
- if (type) {
- CompilerDeclContext decl_ctx =
- GetDeclContextContainingUID(type->GetID());
- if (decl_ctx.IsStructUnionOrClass()) {
- if (name_type_mask & eFunctionNameTypeBase) {
- sc_list.RemoveContextAtIndex(sc_list.GetSize() - 1);
- keep_die = false;
- }
- } else {
- if (name_type_mask & eFunctionNameTypeMethod) {
- sc_list.RemoveContextAtIndex(sc_list.GetSize() - 1);
- keep_die = false;
- }
- }
- } else {
- GetObjectFile()->GetModule()->ReportWarning(
- "function at die offset 0x%8.8x had no function type",
- die_ref.die_offset);
- }
- }
- }
- }
- if (keep_die)
- resolved_dies.insert(die.GetDIE());
- }
- } else {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
- "the DWARF debug information has been modified (.apple_names "
- "accelerator table had bad die 0x%8.8x for '%s')",
- die_ref.die_offset, name_cstr);
- }
- }
- die_offsets.clear();
- }
- }
- } else {
-
- // Index the DWARF if we haven't already
- if (!m_indexed)
- Index();
-
- if (name_type_mask & eFunctionNameTypeFull) {
- FindFunctions(name, m_function_fullname_index, include_inlines, sc_list);
-
- // FIXME Temporary workaround for global/anonymous namespace
- // functions debugging FreeBSD and Linux binaries.
- // If we didn't find any functions in the global namespace try
- // looking in the basename index but ignore any returned
- // functions that have a namespace but keep functions which
- // have an anonymous namespace
- // TODO: The arch in the object file isn't correct for MSVC
- // binaries on windows, we should find a way to make it
- // correct and handle those symbols as well.
- if (sc_list.GetSize() == original_size) {
- ArchSpec arch;
- if (!parent_decl_ctx && GetObjectFile()->GetArchitecture(arch) &&
- arch.GetTriple().isOSBinFormatELF()) {
- SymbolContextList temp_sc_list;
- FindFunctions(name, m_function_basename_index, include_inlines,
- temp_sc_list);
- SymbolContext sc;
- for (uint32_t i = 0; i < temp_sc_list.GetSize(); i++) {
- if (temp_sc_list.GetContextAtIndex(i, sc)) {
- ConstString mangled_name =
- sc.GetFunctionName(Mangled::ePreferMangled);
- ConstString demangled_name =
- sc.GetFunctionName(Mangled::ePreferDemangled);
- // Mangled names on Linux and FreeBSD are of the form:
- // _ZN18function_namespace13function_nameEv.
- if (strncmp(mangled_name.GetCString(), "_ZN", 3) ||
- !strncmp(demangled_name.GetCString(), "(anonymous namespace)",
- 21)) {
- sc_list.Append(sc);
- }
- }
- }
- }
- }
- }
- DIEArray die_offsets;
- if (name_type_mask & eFunctionNameTypeBase) {
- uint32_t num_base = m_function_basename_index.Find(name, die_offsets);
- for (uint32_t i = 0; i < num_base; i++) {
- DWARFDIE die = info->GetDIE(die_offsets[i]);
- if (die) {
- if (!DIEInDeclContext(parent_decl_ctx, die))
- continue; // The containing decl contexts don't match
-
- // If we get to here, the die is good, and we should add it:
- if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) {
- if (ResolveFunction(die, include_inlines, sc_list))
- resolved_dies.insert(die.GetDIE());
- }
- }
- }
- die_offsets.clear();
- }
-
- if (name_type_mask & eFunctionNameTypeMethod) {
- if (parent_decl_ctx && parent_decl_ctx->IsValid())
- return 0; // no methods in namespaces
-
- uint32_t num_base = m_function_method_index.Find(name, die_offsets);
- {
- for (uint32_t i = 0; i < num_base; i++) {
- DWARFDIE die = info->GetDIE(die_offsets[i]);
- if (die) {
- // If we get to here, the die is good, and we should add it:
- if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) {
- if (ResolveFunction(die, include_inlines, sc_list))
- resolved_dies.insert(die.GetDIE());
- }
- }
- }
- }
- die_offsets.clear();
- }
+ llvm::DenseSet<const DWARFDebugInfoEntry *> resolved_dies;
+ DIEArray offsets;
+ CompilerDeclContext empty_decl_ctx;
+ if (!parent_decl_ctx)
+ parent_decl_ctx = &empty_decl_ctx;
- if ((name_type_mask & eFunctionNameTypeSelector) &&
- (!parent_decl_ctx || !parent_decl_ctx->IsValid())) {
- FindFunctions(name, m_function_selector_index, include_inlines, sc_list);
- }
+ std::vector<DWARFDIE> dies;
+ m_index->GetFunctions(name, *info, *parent_decl_ctx, name_type_mask, dies);
+ for (const DWARFDIE &die: dies) {
+ if (resolved_dies.insert(die.GetDIE()).second)
+ ResolveFunction(die, include_inlines, sc_list);
}
// Return the number of variable that were appended to the list
@@ -2755,21 +2320,26 @@ uint32_t SymbolFileDWARF::FindFunctions(const RegularExpression &regex,
if (!append)
sc_list.Clear();
- // Remember how many sc_list are in the list before we search in case
- // we are appending the results to a variable list.
- uint32_t original_size = sc_list.GetSize();
+ DWARFDebugInfo *info = DebugInfo();
+ if (!info)
+ return 0;
- if (m_using_apple_tables) {
- if (m_apple_names_ap.get())
- FindFunctions(regex, *m_apple_names_ap, include_inlines, sc_list);
- } else {
- // Index the DWARF if we haven't already
- if (!m_indexed)
- Index();
+ // Remember how many sc_list are in the list before we search in case we are
+ // appending the results to a variable list.
+ uint32_t original_size = sc_list.GetSize();
- FindFunctions(regex, m_function_basename_index, include_inlines, sc_list);
+ DIEArray offsets;
+ m_index->GetFunctions(regex, offsets);
- FindFunctions(regex, m_function_fullname_index, include_inlines, sc_list);
+ llvm::DenseSet<const DWARFDebugInfoEntry *> resolved_dies;
+ for (DIERef ref : offsets) {
+ DWARFDIE die = info->GetDIE(ref);
+ if (!die) {
+ m_index->ReportInvalidDIEOffset(ref.die_offset, regex.GetText());
+ continue;
+ }
+ if (resolved_dies.insert(die.GetDIE()).second)
+ ResolveFunction(die, include_inlines, sc_list);
}
// Return the number of variable that were appended to the list
@@ -2785,7 +2355,7 @@ void SymbolFileDWARF::GetMangledNamesForFunction(
num_comp_units = info->GetNumCompileUnits();
for (uint32_t i = 0; i < num_comp_units; i++) {
- DWARFCompileUnit *cu = info->GetCompileUnitAtIndex(i);
+ DWARFUnit *cu = info->GetCompileUnitAtIndex(i);
if (cu == nullptr)
continue;
@@ -2847,19 +2417,7 @@ uint32_t SymbolFileDWARF::FindTypes(
return 0;
DIEArray die_offsets;
-
- if (m_using_apple_tables) {
- if (m_apple_types_ap.get()) {
- const char *name_cstr = name.GetCString();
- m_apple_types_ap->FindByName(name_cstr, die_offsets);
- }
- } else {
- if (!m_indexed)
- Index();
-
- m_type_index.Find(name, die_offsets);
- }
-
+ m_index->GetTypes(name, die_offsets);
const size_t num_die_matches = die_offsets.size();
if (num_die_matches) {
@@ -2881,12 +2439,8 @@ uint32_t SymbolFileDWARF::FindTypes(
break;
}
} else {
- if (m_using_apple_tables) {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
- "the DWARF debug information has been modified (.apple_types "
- "accelerator table had bad die 0x%8.8x for '%s')\n",
- die_ref.die_offset, name.GetCString());
- }
+ m_index->ReportInvalidDIEOffset(die_ref.die_offset,
+ name.GetStringRef());
}
}
const uint32_t num_matches = types.GetSize() - initial_types_size;
@@ -2935,25 +2489,13 @@ size_t SymbolFileDWARF::FindTypes(const std::vector<CompilerContext> &context,
if (context.empty())
return 0;
- DIEArray die_offsets;
-
ConstString name = context.back().name;
if (!name)
return 0;
- if (m_using_apple_tables) {
- if (m_apple_types_ap.get()) {
- const char *name_cstr = name.GetCString();
- m_apple_types_ap->FindByName(name_cstr, die_offsets);
- }
- } else {
- if (!m_indexed)
- Index();
-
- m_type_index.Find(name, die_offsets);
- }
-
+ DIEArray die_offsets;
+ m_index->GetTypes(name, die_offsets);
const size_t num_die_matches = die_offsets.size();
if (num_die_matches) {
@@ -2976,12 +2518,8 @@ size_t SymbolFileDWARF::FindTypes(const std::vector<CompilerContext> &context,
++num_matches;
}
} else {
- if (m_using_apple_tables) {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
- "the DWARF debug information has been modified (.apple_types "
- "accelerator table had bad die 0x%8.8x for '%s')\n",
- die_ref.die_offset, name.GetCString());
- }
+ m_index->ReportInvalidDIEOffset(die_ref.die_offset,
+ name.GetStringRef());
}
}
return num_matches;
@@ -3008,21 +2546,7 @@ SymbolFileDWARF::FindNamespace(const SymbolContext &sc, const ConstString &name,
DWARFDebugInfo *info = DebugInfo();
if (info) {
DIEArray die_offsets;
-
- // Index if we already haven't to make sure the compile units
- // get indexed and make their global DIE index list
- if (m_using_apple_tables) {
- if (m_apple_namespaces_ap.get()) {
- const char *name_cstr = name.GetCString();
- m_apple_namespaces_ap->FindByName(name_cstr, die_offsets);
- }
- } else {
- if (!m_indexed)
- Index();
-
- m_namespace_index.Find(name, die_offsets);
- }
-
+ m_index->GetNamespaces(name, die_offsets);
const size_t num_matches = die_offsets.size();
if (num_matches) {
for (size_t i = 0; i < num_matches; ++i) {
@@ -3040,13 +2564,8 @@ SymbolFileDWARF::FindNamespace(const SymbolContext &sc, const ConstString &name,
break;
}
} else {
- if (m_using_apple_tables) {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
- "the DWARF debug information has been modified "
- "(.apple_namespaces accelerator table had bad die 0x%8.8x for "
- "'%s')\n",
- die_ref.die_offset, name.GetCString());
- }
+ m_index->ReportInvalidDIEOffset(die_ref.die_offset,
+ name.GetStringRef());
}
}
}
@@ -3105,6 +2624,7 @@ SymbolFileDWARF::GetDeclContextDIEContainingDIE(const DWARFDIE &orig_die) {
if (orig_die != die) {
switch (die.Tag()) {
case DW_TAG_compile_unit:
+ case DW_TAG_partial_unit:
case DW_TAG_namespace:
case DW_TAG_structure_type:
case DW_TAG_union_type:
@@ -3159,16 +2679,14 @@ SymbolFileDWARF::GetObjCClassSymbol(const ConstString &objc_class_name) {
}
// Some compilers don't emit the DW_AT_APPLE_objc_complete_type attribute. If
-// they don't
-// then we can end up looking through all class types for a complete type and
-// never find
-// the full definition. We need to know if this attribute is supported, so we
-// determine
-// this here and cache th result. We also need to worry about the debug map
+// they don't then we can end up looking through all class types for a complete
+// type and never find the full definition. We need to know if this attribute
+// is supported, so we determine this here and cache th result. We also need to
+// worry about the debug map
// DWARF file
// if we are doing darwin DWARF in .o file debugging.
bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type(
- DWARFCompileUnit *cu) {
+ DWARFUnit *cu) {
if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) {
m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type())
@@ -3177,7 +2695,7 @@ bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type(
DWARFDebugInfo *debug_info = DebugInfo();
const uint32_t num_compile_units = GetNumCompileUnits();
for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
- DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+ DWARFUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
if (dwarf_cu != cu &&
dwarf_cu->Supports_DW_AT_APPLE_objc_complete_type()) {
m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
@@ -3204,19 +2722,7 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE(
return type_sp;
DIEArray die_offsets;
-
- if (m_using_apple_tables) {
- if (m_apple_types_ap.get()) {
- const char *name_cstr = type_name.GetCString();
- m_apple_types_ap->FindCompleteObjCClassByName(name_cstr, die_offsets,
- must_be_implementation);
- }
- } else {
- if (!m_indexed)
- Index();
-
- m_type_index.Find(type_name, die_offsets);
- }
+ m_index->GetCompleteObjCClass(type_name, must_be_implementation, die_offsets);
const size_t num_matches = die_offsets.size();
@@ -3228,7 +2734,8 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE(
if (type_die) {
bool try_resolving_type = false;
- // Don't try and resolve the DIE we are looking for with the DIE itself!
+ // Don't try and resolve the DIE we are looking for with the DIE
+ // itself!
if (type_die != die) {
switch (type_die.Tag()) {
case DW_TAG_class_type:
@@ -3264,12 +2771,8 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE(
}
}
} else {
- if (m_using_apple_tables) {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
- "the DWARF debug information has been modified (.apple_types "
- "accelerator table had bad die 0x%8.8x for '%s')\n",
- die_ref.die_offset, type_name.GetCString());
- }
+ m_index->ReportInvalidDIEOffset(die_ref.die_offset,
+ type_name.GetStringRef());
}
}
}
@@ -3277,16 +2780,15 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE(
}
//----------------------------------------------------------------------
-// This function helps to ensure that the declaration contexts match for
-// two different DIEs. Often times debug information will refer to a
-// forward declaration of a type (the equivalent of "struct my_struct;".
-// There will often be a declaration of that type elsewhere that has the
-// full definition. When we go looking for the full type "my_struct", we
-// will find one or more matches in the accelerator tables and we will
-// then need to make sure the type was in the same declaration context
-// as the original DIE. This function can efficiently compare two DIEs
-// and will return true when the declaration context matches, and false
-// when they don't.
+// This function helps to ensure that the declaration contexts match for two
+// different DIEs. Often times debug information will refer to a forward
+// declaration of a type (the equivalent of "struct my_struct;". There will
+// often be a declaration of that type elsewhere that has the full definition.
+// When we go looking for the full type "my_struct", we will find one or more
+// matches in the accelerator tables and we will then need to make sure the
+// type was in the same declaration context as the original DIE. This function
+// can efficiently compare two DIEs and will return true when the declaration
+// context matches, and false when they don't.
//----------------------------------------------------------------------
bool SymbolFileDWARF::DIEDeclContextsMatch(const DWARFDIE &die1,
const DWARFDIE &die2) {
@@ -3295,32 +2797,31 @@ bool SymbolFileDWARF::DIEDeclContextsMatch(const DWARFDIE &die1,
DWARFDIECollection decl_ctx_1;
DWARFDIECollection decl_ctx_2;
- // The declaration DIE stack is a stack of the declaration context
- // DIEs all the way back to the compile unit. If a type "T" is
- // declared inside a class "B", and class "B" is declared inside
- // a class "A" and class "A" is in a namespace "lldb", and the
- // namespace is in a compile unit, there will be a stack of DIEs:
+ // The declaration DIE stack is a stack of the declaration context DIEs all
+ // the way back to the compile unit. If a type "T" is declared inside a class
+ // "B", and class "B" is declared inside a class "A" and class "A" is in a
+ // namespace "lldb", and the namespace is in a compile unit, there will be a
+ // stack of DIEs:
//
// [0] DW_TAG_class_type for "B"
// [1] DW_TAG_class_type for "A"
// [2] DW_TAG_namespace for "lldb"
- // [3] DW_TAG_compile_unit for the source file.
+ // [3] DW_TAG_compile_unit or DW_TAG_partial_unit for the source file.
//
- // We grab both contexts and make sure that everything matches
- // all the way back to the compiler unit.
+ // We grab both contexts and make sure that everything matches all the way
+ // back to the compiler unit.
// First lets grab the decl contexts for both DIEs
die1.GetDeclContextDIEs(decl_ctx_1);
die2.GetDeclContextDIEs(decl_ctx_2);
- // Make sure the context arrays have the same size, otherwise
- // we are done
+ // Make sure the context arrays have the same size, otherwise we are done
const size_t count1 = decl_ctx_1.Size();
const size_t count2 = decl_ctx_2.Size();
if (count1 != count2)
return false;
- // Make sure the DW_TAG values match all the way back up the
- // compile unit. If they don't, then we are done.
+ // Make sure the DW_TAG values match all the way back up the compile unit. If
+ // they don't, then we are done.
DWARFDIE decl_ctx_die1;
DWARFDIE decl_ctx_die2;
size_t i;
@@ -3333,25 +2834,28 @@ bool SymbolFileDWARF::DIEDeclContextsMatch(const DWARFDIE &die1,
#if defined LLDB_CONFIGURATION_DEBUG
// Make sure the top item in the decl context die array is always
- // DW_TAG_compile_unit. If it isn't then something went wrong in
- // the DWARFDIE::GetDeclContextDIEs() function...
- assert(decl_ctx_1.GetDIEAtIndex(count1 - 1).Tag() == DW_TAG_compile_unit);
+ // DW_TAG_compile_unit or DW_TAG_partial_unit. If it isn't then
+ // something went wrong in the DWARFDIE::GetDeclContextDIEs()
+ // function.
+ dw_tag_t cu_tag = decl_ctx_1.GetDIEAtIndex(count1 - 1).Tag();
+ UNUSED_IF_ASSERT_DISABLED(cu_tag);
+ assert(cu_tag == DW_TAG_compile_unit || cu_tag == DW_TAG_partial_unit);
#endif
- // Always skip the compile unit when comparing by only iterating up to
- // "count - 1". Here we compare the names as we go.
+ // Always skip the compile unit when comparing by only iterating up to "count
+ // - 1". Here we compare the names as we go.
for (i = 0; i < count1 - 1; i++) {
decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex(i);
decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex(i);
const char *name1 = decl_ctx_die1.GetName();
const char *name2 = decl_ctx_die2.GetName();
- // If the string was from a DW_FORM_strp, then the pointer will often
- // be the same!
+ // If the string was from a DW_FORM_strp, then the pointer will often be
+ // the same!
if (name1 == name2)
continue;
- // Name pointers are not equal, so only compare the strings
- // if both are not NULL.
+ // Name pointers are not equal, so only compare the strings if both are not
+ // NULL.
if (name1 && name2) {
// If the strings don't compare, we are done...
if (strcmp(name1, name2) != 0)
@@ -3361,8 +2865,8 @@ bool SymbolFileDWARF::DIEDeclContextsMatch(const DWARFDIE &die1,
return false;
}
}
- // We made it through all of the checks and the declaration contexts
- // are equal.
+ // We made it through all of the checks and the declaration contexts are
+ // equal.
return true;
}
@@ -3387,47 +2891,12 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(
}
DIEArray die_offsets;
-
- if (m_using_apple_tables) {
- if (m_apple_types_ap.get()) {
- const bool has_tag =
- m_apple_types_ap->GetHeader().header_data.ContainsAtom(
- DWARFMappedHash::eAtomTypeTag);
- const bool has_qualified_name_hash =
- m_apple_types_ap->GetHeader().header_data.ContainsAtom(
- DWARFMappedHash::eAtomTypeQualNameHash);
- if (has_tag && has_qualified_name_hash) {
- const char *qualified_name = dwarf_decl_ctx.GetQualifiedName();
- const uint32_t qualified_name_hash =
- MappedHash::HashStringUsingDJB(qualified_name);
- if (log)
- GetObjectFile()->GetModule()->LogMessage(
- log, "FindByNameAndTagAndQualifiedNameHash()");
- m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash(
- type_name.GetCString(), tag, qualified_name_hash, die_offsets);
- } else if (has_tag) {
- if (log)
- GetObjectFile()->GetModule()->LogMessage(log,
- "FindByNameAndTag()");
- m_apple_types_ap->FindByNameAndTag(type_name.GetCString(), tag,
- die_offsets);
- } else {
- m_apple_types_ap->FindByName(type_name.GetCString(), die_offsets);
- }
- }
- } else {
- if (!m_indexed)
- Index();
-
- m_type_index.Find(type_name, die_offsets);
- }
-
+ m_index->GetTypes(dwarf_decl_ctx, die_offsets);
const size_t num_matches = die_offsets.size();
- // Get the type system that we are looking to find a type for. We will use
- // this
- // to ensure any matches we find are in a language that this type system
- // supports
+ // Get the type system that we are looking to find a type for. We will
+ // use this to ensure any matches we find are in a language that this
+ // type system supports
const LanguageType language = dwarf_decl_ctx.GetLanguage();
TypeSystem *type_system = (language == eLanguageTypeUnknown)
? nullptr
@@ -3440,10 +2909,8 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(
if (type_die) {
// Make sure type_die's langauge matches the type system we are
- // looking for.
- // We don't want to find a "Foo" type from Java if we are looking
- // for a "Foo"
- // type for C, C++, ObjC, or ObjC++.
+ // looking for. We don't want to find a "Foo" type from Java if we
+ // are looking for a "Foo" type for C, C++, ObjC, or ObjC++.
if (type_system &&
!type_system->SupportsLanguage(type_die.GetLanguage()))
continue;
@@ -3457,24 +2924,23 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(
// The tags match, lets try resolving this type
try_resolving_type = true;
} else {
- // The tags don't match, but we need to watch our for a
- // forward declaration for a struct and ("struct foo")
- // ends up being a class ("class foo { ... };") or
- // vice versa.
+ // The tags don't match, but we need to watch our for a forward
+ // declaration for a struct and ("struct foo") ends up being a
+ // class ("class foo { ... };") or vice versa.
switch (type_tag) {
case DW_TAG_class_type:
- // We had a "class foo", see if we ended up with a "struct foo {
- // ... };"
+ // We had a "class foo", see if we ended up with a "struct foo
+ // { ... };"
try_resolving_type = (tag == DW_TAG_structure_type);
break;
case DW_TAG_structure_type:
- // We had a "struct foo", see if we ended up with a "class foo {
- // ... };"
+ // We had a "struct foo", see if we ended up with a "class foo
+ // { ... };"
try_resolving_type = (tag == DW_TAG_class_type);
break;
default:
- // Tags don't match, don't event try to resolve
- // using this type whose name matches....
+ // Tags don't match, don't event try to resolve using this type
+ // whose name matches....
break;
}
}
@@ -3515,12 +2981,8 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(
}
}
} else {
- if (m_using_apple_tables) {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
- "the DWARF debug information has been modified (.apple_types "
- "accelerator table had bad die 0x%8.8x for '%s')\n",
- die_ref.die_offset, type_name.GetCString());
- }
+ m_index->ReportInvalidDIEOffset(die_ref.die_offset,
+ type_name.GetStringRef());
}
}
}
@@ -3606,7 +3068,7 @@ size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc,
size_t SymbolFileDWARF::ParseFunctionBlocks(const SymbolContext &sc) {
assert(sc.comp_unit && sc.function);
size_t functions_added = 0;
- DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
if (dwarf_cu) {
const dw_offset_t function_die_offset = sc.function->GetID();
DWARFDIE function_die = dwarf_cu->GetDIE(function_die_offset);
@@ -3623,7 +3085,7 @@ size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc) {
// At least a compile unit must be valid
assert(sc.comp_unit);
size_t types_added = 0;
- DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
if (dwarf_cu) {
if (sc.function) {
dw_offset_t function_die_offset = sc.function->GetID();
@@ -3662,7 +3124,7 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
return num_variables;
}
} else if (sc.comp_unit) {
- DWARFCompileUnit *dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID());
+ DWARFUnit *dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID());
if (dwarf_cu == NULL)
return 0;
@@ -3675,25 +3137,7 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
sc.comp_unit->SetVariableList(variables);
DIEArray die_offsets;
- if (m_using_apple_tables) {
- if (m_apple_names_ap.get()) {
- DWARFMappedHash::DIEInfoArray hash_data_array;
- if (m_apple_names_ap->AppendAllDIEsInRange(
- dwarf_cu->GetOffset(), dwarf_cu->GetNextCompileUnitOffset(),
- hash_data_array)) {
- DWARFMappedHash::ExtractDIEArray(hash_data_array, die_offsets);
- }
- }
- } else {
- // Index if we already haven't to make sure the compile units
- // get indexed and make their global DIE index list
- if (!m_indexed)
- Index();
-
- m_global_index.FindAllEntriesForCompileUnit(dwarf_cu->GetOffset(),
- die_offsets);
- }
-
+ m_index->GetGlobalVariables(*dwarf_cu, die_offsets);
const size_t num_matches = die_offsets.size();
if (num_matches) {
for (size_t i = 0; i < num_matches; ++i) {
@@ -3706,14 +3150,8 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
variables->AddVariableIfUnique(var_sp);
++vars_added;
}
- } else {
- if (m_using_apple_tables) {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
- "the DWARF debug information has been modified "
- "(.apple_names accelerator table had bad die 0x%8.8x)\n",
- die_ref.die_offset);
- }
- }
+ } else
+ m_index->ReportInvalidDIEOffset(die_ref.die_offset, "");
}
}
}
@@ -3796,7 +3234,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
location_is_const_value_data = true;
// The constant value will be either a block, a data value or a
// string.
- const DWARFDataExtractor &debug_info_data = get_debug_info_data();
+ auto debug_info_data = die.GetData();
if (DWARFFormValue::IsBlockForm(form_value.Form())) {
// Retrieve the value as a block expression.
uint32_t block_offset =
@@ -3853,13 +3291,12 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
location_is_const_value_data = false;
has_explicit_location = true;
if (DWARFFormValue::IsBlockForm(form_value.Form())) {
- const DWARFDataExtractor &debug_info_data = get_debug_info_data();
+ auto data = die.GetData();
uint32_t block_offset =
- form_value.BlockData() - debug_info_data.GetDataStart();
+ form_value.BlockData() - data.GetDataStart();
uint32_t block_length = form_value.Unsigned();
- location.CopyOpcodeData(module, get_debug_info_data(),
- block_offset, block_length);
+ location.CopyOpcodeData(module, data, block_offset, block_length);
} else {
const DWARFDataExtractor &debug_loc_data = get_debug_loc_data();
const dw_offset_t debug_loc_offset = form_value.Unsigned();
@@ -3902,10 +3339,9 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
// TODO: Handle the case when DW_AT_start_scope have form
// constant. The
// dwarf spec is a bit ambiguous about what is the expected
- // behavior in
- // case the enclosing block have a non coninious address range and
- // the
- // DW_AT_start_scope entry have a form constant.
+ // behavior in case the enclosing block have a non coninious
+ // address range and the DW_AT_start_scope entry have a form
+ // constant.
GetObjectFile()->GetModule()->ReportWarning(
"0x%8.8" PRIx64
": DW_AT_start_scope has unsupported form type (0x%x)\n",
@@ -3937,7 +3373,8 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die);
const dw_tag_t parent_tag = die.GetParent().Tag();
bool is_static_member =
- parent_tag == DW_TAG_compile_unit &&
+ (parent_tag == DW_TAG_compile_unit ||
+ parent_tag == DW_TAG_partial_unit) &&
(parent_context_die.Tag() == DW_TAG_class_type ||
parent_context_die.Tag() == DW_TAG_structure_type);
@@ -3949,17 +3386,17 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
bool has_explicit_mangled = mangled != nullptr;
if (!mangled) {
// LLDB relies on the mangled name (DW_TAG_linkage_name or
- // DW_AT_MIPS_linkage_name) to
- // generate fully qualified names of global variables with commands like
- // "frame var j".
- // For example, if j were an int variable holding a value 4 and declared
- // in a namespace
- // B which in turn is contained in a namespace A, the command "frame var
- // j" returns
- // "(int) A::B::j = 4". If the compiler does not emit a linkage name, we
- // should be able
- // to generate a fully qualified name from the declaration context.
- if (parent_tag == DW_TAG_compile_unit &&
+ // DW_AT_MIPS_linkage_name) to generate fully qualified names
+ // of global variables with commands like "frame var j". For
+ // example, if j were an int variable holding a value 4 and
+ // declared in a namespace B which in turn is contained in a
+ // namespace A, the command "frame var j" returns
+ // "(int) A::B::j = 4".
+ // If the compiler does not emit a linkage name, we should be
+ // able to generate a fully qualified name from the
+ // declaration context.
+ if ((parent_tag == DW_TAG_compile_unit ||
+ parent_tag == DW_TAG_partial_unit) &&
Language::LanguageIsCPlusPlus(die.GetLanguage())) {
DWARFDeclContext decl_ctx;
@@ -4007,24 +3444,21 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
scope = eValueTypeVariableStatic;
if (debug_map_symfile) {
- // When leaving the DWARF in the .o files on darwin,
- // when we have a global variable that wasn't initialized,
- // the .o file might not have allocated a virtual
- // address for the global variable. In this case it will
- // have created a symbol for the global variable
- // that is undefined/data and external and the value will
- // be the byte size of the variable. When we do the
- // address map in SymbolFileDWARFDebugMap we rely on
- // having an address, we need to do some magic here
- // so we can get the correct address for our global
- // variable. The address for all of these entries
- // will be zero, and there will be an undefined symbol
- // in this object file, and the executable will have
- // a matching symbol with a good address. So here we
- // dig up the correct address and replace it in the
- // location for the variable, and set the variable's
- // symbol context scope to be that of the main executable
- // so the file address will resolve correctly.
+ // When leaving the DWARF in the .o files on darwin, when we have a
+ // global variable that wasn't initialized, the .o file might not
+ // have allocated a virtual address for the global variable. In
+ // this case it will have created a symbol for the global variable
+ // that is undefined/data and external and the value will be the
+ // byte size of the variable. When we do the address map in
+ // SymbolFileDWARFDebugMap we rely on having an address, we need to
+ // do some magic here so we can get the correct address for our
+ // global variable. The address for all of these entries will be
+ // zero, and there will be an undefined symbol in this object file,
+ // and the executable will have a matching symbol with a good
+ // address. So here we dig up the correct address and replace it in
+ // the location for the variable, and set the variable's symbol
+ // context scope to be that of the main executable so the file
+ // address will resolve correctly.
bool linked_oso_file_addr = false;
if (is_external && location_DW_OP_addr == 0) {
// we have a possible uninitialized extern global
@@ -4056,8 +3490,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
if (!linked_oso_file_addr) {
// The DW_OP_addr is not zero, but it contains a .o file address
- // which
- // needs to be linked up correctly.
+ // which needs to be linked up correctly.
const lldb::addr_t exe_file_addr =
debug_map_symfile->LinkOSOFileAddress(this,
location_DW_OP_addr);
@@ -4127,16 +3560,16 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
var_sp->SetLocationIsConstantValueData(location_is_const_value_data);
} else {
- // Not ready to parse this variable yet. It might be a global
- // or static variable that is in a function scope and the function
- // in the symbol context wasn't filled in yet
+ // Not ready to parse this variable yet. It might be a global or static
+ // variable that is in a function scope and the function in the symbol
+ // context wasn't filled in yet
return var_sp;
}
}
- // Cache var_sp even if NULL (the variable was just a specification or
- // was missing vital information to be able to be displayed in the debugger
- // (missing location due to optimization, etc)) so we don't re-parse
- // this DIE over and over later...
+ // Cache var_sp even if NULL (the variable was just a specification or was
+ // missing vital information to be able to be displayed in the debugger
+ // (missing location due to optimization, etc)) so we don't re-parse this
+ // DIE over and over later...
GetDIEToVariable()[die.GetDIE()] = var_sp;
if (spec_die)
GetDIEToVariable()[spec_die.GetDIE()] = var_sp;
@@ -4217,11 +3650,11 @@ size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc,
dw_tag_t parent_tag = sc_parent_die.Tag();
switch (parent_tag) {
case DW_TAG_compile_unit:
+ case DW_TAG_partial_unit:
if (sc.comp_unit != NULL) {
variable_list_sp = sc.comp_unit->GetVariableList(false);
if (variable_list_sp.get() == NULL) {
variable_list_sp.reset(new VariableList());
- sc.comp_unit->SetVariableList(variable_list_sp);
}
} else {
GetObjectFile()->GetModule()->ReportError(
@@ -4243,8 +3676,8 @@ size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc,
Block *block = sc.function->GetBlock(true).FindBlockByID(
sc_parent_die.GetID());
if (block == NULL) {
- // This must be a specification or abstract origin with
- // a concrete block counterpart in the current function. We need
+ // This must be a specification or abstract origin with a
+ // concrete block counterpart in the current function. We need
// to find the concrete block so we can correctly add the
// variable to it
const DWARFDIE concrete_block_die =
@@ -4310,30 +3743,7 @@ ConstString SymbolFileDWARF::GetPluginName() { return GetPluginNameStatic(); }
uint32_t SymbolFileDWARF::GetPluginVersion() { return 1; }
-void SymbolFileDWARF::DumpIndexes() {
- StreamFile s(stdout, false);
-
- s.Printf(
- "DWARF index for (%s) '%s':",
- GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
- GetObjectFile()->GetFileSpec().GetPath().c_str());
- s.Printf("\nFunction basenames:\n");
- m_function_basename_index.Dump(&s);
- s.Printf("\nFunction fullnames:\n");
- m_function_fullname_index.Dump(&s);
- s.Printf("\nFunction methods:\n");
- m_function_method_index.Dump(&s);
- s.Printf("\nFunction selectors:\n");
- m_function_selector_index.Dump(&s);
- s.Printf("\nObjective C class selectors:\n");
- m_objc_class_selectors_index.Dump(&s);
- s.Printf("\nGlobals and statics:\n");
- m_global_index.Dump(&s);
- s.Printf("\nTypes:\n");
- m_type_index.Dump(&s);
- s.Printf("\nNamespaces:\n");
- m_namespace_index.Dump(&s);
-}
+void SymbolFileDWARF::Dump(lldb_private::Stream &s) { m_index->Dump(s); }
SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() {
if (m_debug_map_symfile == NULL && !m_debug_map_module_wp.expired()) {
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 6902dc0333d2..a5f2ac8f3e7d 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -38,8 +38,7 @@
// Project includes
#include "DWARFDataExtractor.h"
#include "DWARFDefines.h"
-#include "HashedNameToDIE.h"
-#include "NameToDIE.h"
+#include "DWARFIndex.h"
#include "UniqueDWARFASTType.h"
//----------------------------------------------------------------------
@@ -54,7 +53,6 @@ class DWARFDebugAranges;
class DWARFDebugInfo;
class DWARFDebugInfoEntry;
class DWARFDebugLine;
-class DWARFDebugPubnames;
class DWARFDebugRanges;
class DWARFDeclContext;
class DWARFDIECollection;
@@ -72,7 +70,7 @@ public:
friend class SymbolFileDWARFDwo;
friend class DebugMapModule;
friend struct DIERef;
- friend class DWARFCompileUnit;
+ friend class DWARFUnit;
friend class DWARFDIE;
friend class DWARFASTParserClang;
friend class DWARFASTParserGo;
@@ -181,11 +179,11 @@ public:
uint32_t
FindGlobalVariables(const lldb_private::ConstString &name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
lldb_private::VariableList &variables) override;
uint32_t FindGlobalVariables(const lldb_private::RegularExpression &regex,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
lldb_private::VariableList &variables) override;
uint32_t
@@ -247,10 +245,12 @@ public:
const lldb_private::DWARFDataExtractor &get_debug_ranges_data();
const lldb_private::DWARFDataExtractor &get_debug_str_data();
const lldb_private::DWARFDataExtractor &get_debug_str_offsets_data();
+ const lldb_private::DWARFDataExtractor &get_debug_types_data();
const lldb_private::DWARFDataExtractor &get_apple_names_data();
const lldb_private::DWARFDataExtractor &get_apple_types_data();
const lldb_private::DWARFDataExtractor &get_apple_namespaces_data();
const lldb_private::DWARFDataExtractor &get_apple_objc_data();
+ const lldb_private::DWARFDataExtractor &get_gnu_debugaltlink();
DWARFDebugAbbrev *DebugAbbrev();
@@ -273,19 +273,19 @@ public:
HasForwardDeclForClangType(const lldb_private::CompilerType &compiler_type);
lldb_private::CompileUnit *
- GetCompUnitForDWARFCompUnit(DWARFCompileUnit *dwarf_cu,
+ GetCompUnitForDWARFCompUnit(DWARFUnit *dwarf_cu,
uint32_t cu_idx = UINT32_MAX);
virtual size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name,
DIEArray &method_die_offsets);
- bool Supports_DW_AT_APPLE_objc_complete_type(DWARFCompileUnit *cu);
+ bool Supports_DW_AT_APPLE_objc_complete_type(DWARFUnit *cu);
lldb_private::DebugMacrosSP ParseDebugMacros(lldb::offset_t *offset);
static DWARFDIE GetParentSymbolContextDIE(const DWARFDIE &die);
- virtual lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit *dwarf_cu,
+ virtual lldb::CompUnitSP ParseCompileUnit(DWARFUnit *dwarf_cu,
uint32_t cu_idx);
virtual lldb_private::DWARFExpression::LocationListFormat
@@ -293,16 +293,30 @@ public:
lldb::ModuleSP GetDWOModule(lldb_private::ConstString name);
+ typedef std::map<lldb_private::ConstString, lldb::ModuleSP>
+ ExternalTypeModuleMap;
+
+ /// Return the list of Clang modules imported by this SymbolFile.
+ const ExternalTypeModuleMap& getExternalTypeModules() const {
+ return m_external_type_modules;
+ }
+
virtual DWARFDIE GetDIE(const DIERef &die_ref);
virtual std::unique_ptr<SymbolFileDWARFDwo>
- GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu,
+ GetDwoSymbolFileForCompileUnit(DWARFUnit &dwarf_cu,
const DWARFDebugInfoEntry &cu_die);
// For regular SymbolFileDWARF instances the method returns nullptr,
// for the instances of the subclass SymbolFileDWARFDwo
// the method returns a pointer to the base compile unit.
- virtual DWARFCompileUnit *GetBaseCompileUnit();
+ virtual DWARFUnit *GetBaseCompileUnit();
+
+ static bool
+ DIEInDeclContext(const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ const DWARFDIE &die);
+
+ void Dump(lldb_private::Stream &s) override;
protected:
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *>
@@ -331,14 +345,10 @@ protected:
bool DeclContextMatchesThisSymbolFile(
const lldb_private::CompilerDeclContext *decl_ctx);
- bool
- DIEInDeclContext(const lldb_private::CompilerDeclContext *parent_decl_ctx,
- const DWARFDIE &die);
-
- virtual DWARFCompileUnit *
+ virtual DWARFUnit *
GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit);
- DWARFCompileUnit *GetNextUnparsedDWARFCompileUnit(DWARFCompileUnit *prev_cu);
+ DWARFUnit *GetNextUnparsedDWARFCompileUnit(DWARFUnit *prev_cu);
bool GetFunction(const DWARFDIE &die, lldb_private::SymbolContext &sc);
@@ -375,25 +385,9 @@ protected:
bool ClassOrStructIsVirtual(const DWARFDIE &die);
// Given a die_offset, figure out the symbol context representing that die.
- bool ResolveFunction(const DIERef &die_ref, bool include_inlines,
- lldb_private::SymbolContextList &sc_list);
-
bool ResolveFunction(const DWARFDIE &die, bool include_inlines,
lldb_private::SymbolContextList &sc_list);
- void FindFunctions(const lldb_private::ConstString &name,
- const NameToDIE &name_to_die, bool include_inlines,
- lldb_private::SymbolContextList &sc_list);
-
- void FindFunctions(const lldb_private::RegularExpression &regex,
- const NameToDIE &name_to_die, bool include_inlines,
- lldb_private::SymbolContextList &sc_list);
-
- void FindFunctions(const lldb_private::RegularExpression &regex,
- const DWARFMappedHash::MemoryTable &memory_table,
- bool include_inlines,
- lldb_private::SymbolContextList &sc_list);
-
virtual lldb::TypeSP
FindDefinitionTypeForDWARFDeclContext(const DWARFDeclContext &die_decl_ctx);
@@ -404,16 +398,9 @@ protected:
lldb_private::Symbol *
GetObjCClassSymbol(const lldb_private::ConstString &objc_class_name);
- void ParseFunctions(const DIEArray &die_offsets, bool include_inlines,
- lldb_private::SymbolContextList &sc_list);
-
lldb::TypeSP GetTypeForDIE(const DWARFDIE &die,
bool resolve_function_context = false);
- void Index();
-
- void DumpIndexes();
-
void SetDebugMapModule(const lldb::ModuleSP &module_sp) {
m_debug_map_module_wp = module_sp;
}
@@ -439,9 +426,6 @@ protected:
typedef std::set<lldb_private::Type *> TypeSet;
- typedef std::map<lldb_private::ConstString, lldb::ModuleSP>
- ExternalTypeModuleMap;
-
void GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,
dw_offset_t max_die_offset, uint32_t type_mask,
TypeSet &type_set);
@@ -487,10 +471,12 @@ protected:
DWARFDataSegment m_data_debug_ranges;
DWARFDataSegment m_data_debug_str;
DWARFDataSegment m_data_debug_str_offsets;
+ DWARFDataSegment m_data_debug_types;
DWARFDataSegment m_data_apple_names;
DWARFDataSegment m_data_apple_types;
DWARFDataSegment m_data_apple_namespaces;
DWARFDataSegment m_data_apple_objc;
+ DWARFDataSegment m_data_gnu_debugaltlink;
// The unique pointer items below are generated on demand if and when someone
// accesses
@@ -498,10 +484,6 @@ protected:
std::unique_ptr<DWARFDebugAbbrev> m_abbr;
std::unique_ptr<DWARFDebugInfo> m_info;
std::unique_ptr<DWARFDebugLine> m_line;
- std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_names_ap;
- std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_types_ap;
- std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_namespaces_ap;
- std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_objc_ap;
std::unique_ptr<GlobalVariableMap> m_global_aranges_ap;
typedef std::unordered_map<lldb::offset_t, lldb_private::DebugMacrosSP>
@@ -509,17 +491,8 @@ protected:
DebugMacrosMap m_debug_macros_map;
ExternalTypeModuleMap m_external_type_modules;
- NameToDIE m_function_basename_index; // All concrete functions
- NameToDIE m_function_fullname_index; // All concrete functions
- NameToDIE m_function_method_index; // All inlined functions
- NameToDIE
- m_function_selector_index; // All method names for functions of classes
- NameToDIE m_objc_class_selectors_index; // Given a class name, find all
- // selectors for the class
- NameToDIE m_global_index; // Global and static variables
- NameToDIE m_type_index; // All type DIE offsets
- NameToDIE m_namespace_index; // All type DIE offsets
- bool m_indexed : 1, m_using_apple_tables : 1, m_fetched_external_modules : 1;
+ std::unique_ptr<lldb_private::DWARFIndex> m_index;
+ bool m_fetched_external_modules : 1;
lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
typedef std::shared_ptr<std::set<DIERef>> DIERefSetSP;
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
index eabff86a5428..39c70d146524 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -44,10 +44,8 @@ using namespace lldb;
using namespace lldb_private;
// Subclass lldb_private::Module so we can intercept the
-// "Module::GetObjectFile()"
-// (so we can fixup the object file sections) and also for
-// "Module::GetSymbolVendor()"
-// (so we can fixup the symbol file id.
+// "Module::GetObjectFile()" (so we can fixup the object file sections) and
+// also for "Module::GetSymbolVendor()" (so we can fixup the symbol file id.
const SymbolFileDWARFDebugMap::FileRangeMap &
SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(
@@ -84,8 +82,8 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(
/// const uint32_t fun_resolve_flags = SymbolContext::Module |
/// eSymbolContextCompUnit | eSymbolContextFunction;
// SectionList *oso_sections = oso_objfile->Sections();
- // Now we need to make sections that map from zero based object
- // file addresses to where things ended up in the main executable.
+ // Now we need to make sections that map from zero based object file
+ // addresses to where things ended up in the main executable.
assert(comp_unit_info->first_symbol_index != UINT32_MAX);
// End index is one past the last valid symbol index
@@ -104,9 +102,9 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(
break;
case eSymbolTypeCode: {
- // For each N_FUN, or function that we run into in the debug map
- // we make a new section that we add to the sections found in the
- // .o file. This new section has the file address set to what the
+ // For each N_FUN, or function that we run into in the debug map we
+ // make a new section that we add to the sections found in the .o
+ // file. This new section has the file address set to what the
// addresses are in the .o file, and the load address is adjusted
// to match where it ended up in the final executable! We do this
// before we parse any dwarf info so that when it goes get parsed
@@ -129,21 +127,21 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(
} break;
case eSymbolTypeData: {
- // For each N_GSYM we remap the address for the global by making
- // a new section that we add to the sections found in the .o file.
- // This new section has the file address set to what the
- // addresses are in the .o file, and the load address is adjusted
- // to match where it ended up in the final executable! We do this
- // before we parse any dwarf info so that when it goes get parsed
- // all section/offset addresses that get registered will resolve
+ // For each N_GSYM we remap the address for the global by making a
+ // new section that we add to the sections found in the .o file.
+ // This new section has the file address set to what the addresses
+ // are in the .o file, and the load address is adjusted to match
+ // where it ended up in the final executable! We do this before we
+ // parse any dwarf info so that when it goes get parsed all
+ // section/offset addresses that get registered will resolve
// correctly to the new addresses in the main executable. We
// initially set the section size to be 1 byte, but will need to
// fix up these addresses further after all globals have been
// parsed to span the gaps, or we can find the global variable
// sizes from the DWARF info as we are parsing.
- // Next we find the non-stab entry that corresponds to the N_GSYM in
- // the .o file
+ // Next we find the non-stab entry that corresponds to the N_GSYM
+ // in the .o file
Symbol *oso_gsym_symbol =
oso_symtab->FindFirstSymbolWithNameAndType(
exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown,
@@ -198,9 +196,9 @@ public:
SymbolVendor *symbol_vendor =
Module::GetSymbolVendor(can_create, feedback_strm);
if (symbol_vendor) {
- // Set a pointer to this class to set our OSO DWARF file know
- // that the DWARF is being used along with a debug map and that
- // it will have the remapped sections that we do below.
+ // Set a pointer to this class to set our OSO DWARF file know that
+ // the DWARF is being used along with a debug map and that it will
+ // have the remapped sections that we do below.
SymbolFileDWARF *oso_symfile =
SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(
symbol_vendor->GetSymbolFile());
@@ -292,8 +290,8 @@ void SymbolFileDWARFDebugMap::InitOSO() {
// In order to get the abilities of this plug-in, we look at the list of
// N_OSO entries (object files) from the symbol table and make sure that
- // these files exist and also contain valid DWARF. If we get any of that
- // then we return the abilities of the first N_OSO's DWARF.
+ // these files exist and also contain valid DWARF. If we get any of that then
+ // we return the abilities of the first N_OSO's DWARF.
Symtab *symtab = m_obj_file->GetSymtab();
if (symtab) {
@@ -303,10 +301,10 @@ void SymbolFileDWARFDebugMap::InitOSO() {
// When a mach-o symbol is encoded, the n_type field is encoded in bits
// 23:16, and the n_desc field is encoded in bits 15:0.
//
- // To find all N_OSO entries that are part of the DWARF + debug map
- // we find only object file symbols with the flags value as follows:
- // bits 23:16 == 0x66 (N_OSO)
- // bits 15: 0 == 0x0001 (specifies this is a debug map object file)
+ // To find all N_OSO entries that are part of the DWARF + debug map we find
+ // only object file symbols with the flags value as follows: bits 23:16 ==
+ // 0x66 (N_OSO) bits 15: 0 == 0x0001 (specifies this is a debug map object
+ // file)
const uint32_t k_oso_symbol_flags_value = 0x660001u;
const uint32_t oso_index_count =
@@ -353,7 +351,7 @@ void SymbolFileDWARFDebugMap::InitOSO() {
so_symbol->GetType() == eSymbolTypeSourceFile &&
oso_symbol->GetType() == eSymbolTypeObjectFile) {
m_compile_unit_infos[i].so_file.SetFile(
- so_symbol->GetName().AsCString(), false);
+ so_symbol->GetName().AsCString(), false, FileSpec::Style::native);
m_compile_unit_infos[i].oso_path = oso_symbol->GetName();
m_compile_unit_infos[i].oso_mod_time =
llvm::sys::toTimePoint(oso_symbol->GetIntegerValue(0));
@@ -413,13 +411,15 @@ Module *SymbolFileDWARFDebugMap::GetModuleByOSOIndex(uint32_t oso_idx) {
Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo(
CompileUnitInfo *comp_unit_info) {
if (!comp_unit_info->oso_sp) {
- auto pos = m_oso_map.find(comp_unit_info->oso_path);
+ auto pos = m_oso_map.find(
+ {comp_unit_info->oso_path, comp_unit_info->oso_mod_time});
if (pos != m_oso_map.end()) {
comp_unit_info->oso_sp = pos->second;
} else {
ObjectFile *obj_file = GetObjectFile();
comp_unit_info->oso_sp.reset(new OSOInfo());
- m_oso_map[comp_unit_info->oso_path] = comp_unit_info->oso_sp;
+ m_oso_map[{comp_unit_info->oso_path, comp_unit_info->oso_mod_time}] =
+ comp_unit_info->oso_sp;
const char *oso_path = comp_unit_info->oso_path.GetCString();
FileSpec oso_file(oso_path, false);
ConstString oso_object;
@@ -443,16 +443,15 @@ Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo(
return NULL;
}
}
- // Always create a new module for .o files. Why? Because we
- // use the debug map, to add new sections to each .o file and
- // even though a .o file might not have changed, the sections
- // that get added to the .o file can change.
+ // Always create a new module for .o files. Why? Because we use the debug
+ // map, to add new sections to each .o file and even though a .o file
+ // might not have changed, the sections that get added to the .o file can
+ // change.
ArchSpec oso_arch;
// Only adopt the architecture from the module (not the vendor or OS)
- // since .o files for "i386-apple-ios" will historically show up as
- // "i386-apple-macosx"
- // due to the lack of a LC_VERSION_MIN_MACOSX or LC_VERSION_MIN_IPHONEOS
- // load command...
+ // since .o files for "i386-apple-ios" will historically show up as "i386
+ // -apple-macosx" due to the lack of a LC_VERSION_MIN_MACOSX or
+ // LC_VERSION_MIN_IPHONEOS load command...
oso_arch.SetTriple(m_obj_file->GetModule()
->GetArchitecture()
.GetTriple()
@@ -546,8 +545,8 @@ SymbolFileDWARF *SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo(
uint32_t SymbolFileDWARFDebugMap::CalculateAbilities() {
// In order to get the abilities of this plug-in, we look at the list of
// N_OSO entries (object files) from the symbol table and make sure that
- // these files exist and also contain valid DWARF. If we get any of that
- // then we return the abilities of the first N_OSO's DWARF.
+ // these files exist and also contain valid DWARF. If we get any of that then
+ // we return the abilities of the first N_OSO's DWARF.
const uint32_t oso_index_count = GetNumCompileUnits();
if (oso_index_count > 0) {
@@ -576,9 +575,8 @@ CompUnitSP SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx) {
if (oso_module) {
FileSpec so_file_spec;
if (GetFileSpecForSO(cu_idx, so_file_spec)) {
- // User zero as the ID to match the compile unit at offset
- // zero in each .o file since each .o file can only have
- // one compile unit for now.
+ // User zero as the ID to match the compile unit at offset zero in each
+ // .o file since each .o file can only have one compile unit for now.
lldb::user_id_t cu_id = 0;
m_compile_unit_infos[cu_idx].compile_unit_sp.reset(
new CompileUnit(m_obj_file->GetModule(), NULL, so_file_spec, cu_id,
@@ -767,8 +765,8 @@ uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext(
const uint32_t cu_count = GetNumCompileUnits();
for (uint32_t i = 0; i < cu_count; ++i) {
- // If we are checking for inlines, then we need to look through all
- // compile units no matter if "file_spec" matches.
+ // If we are checking for inlines, then we need to look through all compile
+ // units no matter if "file_spec" matches.
bool resolve = check_inlines;
if (!resolve) {
@@ -805,8 +803,8 @@ uint32_t SymbolFileDWARFDebugMap::PrivateFindGlobalVariables(
if (comp_unit_info) {
SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
if (oso_dwarf) {
- if (oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, true,
- max_matches, variables))
+ if (oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, max_matches,
+ variables))
if (variables.GetSize() > max_matches)
break;
}
@@ -817,21 +815,16 @@ uint32_t SymbolFileDWARFDebugMap::PrivateFindGlobalVariables(
uint32_t SymbolFileDWARFDebugMap::FindGlobalVariables(
const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches, VariableList &variables) {
+ uint32_t max_matches, VariableList &variables) {
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- variables.Clear();
-
- // Remember how many variables are in the list before we search in case
- // we are appending the results to a variable list.
+ // Remember how many variables are in the list before we search.
const uint32_t original_size = variables.GetSize();
uint32_t total_matches = 0;
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
const uint32_t oso_matches = oso_dwarf->FindGlobalVariables(
- name, parent_decl_ctx, true, max_matches, variables);
+ name, parent_decl_ctx, max_matches, variables);
if (oso_matches > 0) {
total_matches += oso_matches;
@@ -843,8 +836,8 @@ uint32_t SymbolFileDWARFDebugMap::FindGlobalVariables(
if (max_matches >= total_matches)
return true;
- // Update the max matches for any subsequent calls to find globals
- // in any other object files with DWARF
+ // Update the max matches for any subsequent calls to find globals in any
+ // other object files with DWARF
max_matches -= oso_matches;
}
@@ -857,20 +850,15 @@ uint32_t SymbolFileDWARFDebugMap::FindGlobalVariables(
uint32_t
SymbolFileDWARFDebugMap::FindGlobalVariables(const RegularExpression &regex,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
VariableList &variables) {
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- variables.Clear();
-
- // Remember how many variables are in the list before we search in case
- // we are appending the results to a variable list.
+ // Remember how many variables are in the list before we search.
const uint32_t original_size = variables.GetSize();
uint32_t total_matches = 0;
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
const uint32_t oso_matches =
- oso_dwarf->FindGlobalVariables(regex, true, max_matches, variables);
+ oso_dwarf->FindGlobalVariables(regex, max_matches, variables);
if (oso_matches > 0) {
total_matches += oso_matches;
@@ -882,8 +870,8 @@ SymbolFileDWARFDebugMap::FindGlobalVariables(const RegularExpression &regex,
if (max_matches >= total_matches)
return true;
- // Update the max matches for any subsequent calls to find globals
- // in any other object files with DWARF
+ // Update the max matches for any subsequent calls to find globals in any
+ // other object files with DWARF
max_matches -= oso_matches;
}
@@ -965,12 +953,12 @@ SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID(
static void RemoveFunctionsWithModuleNotEqualTo(const ModuleSP &module_sp,
SymbolContextList &sc_list,
uint32_t start_idx) {
- // We found functions in .o files. Not all functions in the .o files
- // will have made it into the final output file. The ones that did
- // make it into the final output file will have a section whose module
- // matches the module from the ObjectFile for this SymbolFile. When
- // the modules don't match, then we have something that was in a
- // .o file, but doesn't map to anything in the final executable.
+ // We found functions in .o files. Not all functions in the .o files will
+ // have made it into the final output file. The ones that did make it into
+ // the final output file will have a section whose module matches the module
+ // from the ObjectFile for this SymbolFile. When the modules don't match,
+ // then we have something that was in a .o file, but doesn't map to anything
+ // in the final executable.
uint32_t i = start_idx;
while (i < sc_list.GetSize()) {
SymbolContext sc;
@@ -1101,12 +1089,12 @@ bool SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type(
TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
const DWARFDIE &die, const ConstString &type_name,
bool must_be_implementation) {
- // If we have a debug map, we will have an Objective C symbol whose name is
+ // If we have a debug map, we will have an Objective-C symbol whose name is
// the type name and whose type is eSymbolTypeObjCClass. If we can find that
// symbol and find its containing parent, we can locate the .o file that will
// contain the implementation definition since it will be scoped inside the
- // N_SO
- // and we can then locate the SymbolFileDWARF that corresponds to that N_SO.
+ // N_SO and we can then locate the SymbolFileDWARF that corresponds to that
+ // N_SO.
SymbolFileDWARF *oso_dwarf = NULL;
TypeSP type_sp;
ObjectFile *module_objfile = m_obj_file->GetModule()->GetObjectFile();
@@ -1118,8 +1106,7 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
Symtab::eVisibilityAny);
if (objc_class_symbol) {
// Get the N_SO symbol that contains the objective C class symbol as
- // this
- // should be the .o file that contains the real definition...
+ // this should be the .o file that contains the real definition...
const Symbol *source_file_symbol = symtab->GetParent(objc_class_symbol);
if (source_file_symbol &&
@@ -1147,10 +1134,8 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
}
// Only search all .o files for the definition if we don't need the
- // implementation
- // because otherwise, with a valid debug map we should have the ObjC class
- // symbol and
- // the code above should have found it.
+ // implementation because otherwise, with a valid debug map we should have
+ // the ObjC class symbol and the code above should have found it.
if (must_be_implementation == false) {
TypeSP type_sp;
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
index dcca4268b6eb..550f74a203ea 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -95,10 +95,10 @@ public:
uint32_t
FindGlobalVariables(const lldb_private::ConstString &name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
lldb_private::VariableList &variables) override;
uint32_t FindGlobalVariables(const lldb_private::RegularExpression &regex,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
lldb_private::VariableList &variables) override;
uint32_t
FindFunctions(const lldb_private::ConstString &name,
@@ -136,7 +136,7 @@ protected:
friend class DebugMapModule;
friend struct DIERef;
friend class DWARFASTParserClang;
- friend class DWARFCompileUnit;
+ friend class DWARFUnit;
friend class SymbolFileDWARF;
struct OSOInfo {
lldb::ModuleSP module_sp;
@@ -300,7 +300,9 @@ protected:
std::vector<CompileUnitInfo> m_compile_unit_infos;
std::vector<uint32_t> m_func_indexes; // Sorted by address
std::vector<uint32_t> m_glob_indexes;
- std::map<lldb_private::ConstString, OSOInfoSP> m_oso_map;
+ std::map<std::pair<lldb_private::ConstString, llvm::sys::TimePoint<>>,
+ OSOInfoSP>
+ m_oso_map;
UniqueDWARFASTTypeMap m_unique_ast_type_map;
lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
DebugMap m_debug_map;
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
index 17c188a41a77..15fe362fa117 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -14,14 +14,14 @@
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/LLDBAssert.h"
-#include "DWARFCompileUnit.h"
+#include "DWARFUnit.h"
#include "DWARFDebugInfo.h"
using namespace lldb;
using namespace lldb_private;
SymbolFileDWARFDwo::SymbolFileDWARFDwo(ObjectFileSP objfile,
- DWARFCompileUnit *dwarf_cu)
+ DWARFUnit *dwarf_cu)
: SymbolFileDWARF(objfile.get()), m_obj_file_sp(objfile),
m_base_dwarf_cu(dwarf_cu) {
SetID(((lldb::user_id_t)dwarf_cu->GetOffset()) << 32);
@@ -52,7 +52,7 @@ void SymbolFileDWARFDwo::LoadSectionData(lldb::SectionType sect_type,
}
lldb::CompUnitSP
-SymbolFileDWARFDwo::ParseCompileUnit(DWARFCompileUnit *dwarf_cu,
+SymbolFileDWARFDwo::ParseCompileUnit(DWARFUnit *dwarf_cu,
uint32_t cu_idx) {
assert(GetCompileUnit() == dwarf_cu && "SymbolFileDWARFDwo::ParseCompileUnit "
"called with incompatible compile "
@@ -60,7 +60,7 @@ SymbolFileDWARFDwo::ParseCompileUnit(DWARFCompileUnit *dwarf_cu,
return GetBaseSymbolFile()->ParseCompileUnit(m_base_dwarf_cu, UINT32_MAX);
}
-DWARFCompileUnit *SymbolFileDWARFDwo::GetCompileUnit() {
+DWARFUnit *SymbolFileDWARFDwo::GetCompileUnit() {
// A clang module is found via a skeleton CU, but is not a proper DWO.
// Clang modules have a .debug_info section instead of the *_dwo variant.
if (auto *section_list = m_obj_file->GetSectionList(false))
@@ -76,7 +76,7 @@ DWARFCompileUnit *SymbolFileDWARFDwo::GetCompileUnit() {
return nullptr;
}
-DWARFCompileUnit *
+DWARFUnit *
SymbolFileDWARFDwo::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) {
return GetCompileUnit();
}
@@ -122,7 +122,7 @@ lldb::TypeSP SymbolFileDWARFDwo::FindCompleteObjCDefinitionTypeForDIE(
die, type_name, must_be_implementation);
}
-DWARFCompileUnit *SymbolFileDWARFDwo::GetBaseCompileUnit() {
+DWARFUnit *SymbolFileDWARFDwo::GetBaseCompileUnit() {
return m_base_dwarf_cu;
}
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
index b67967aafab2..483a19512a36 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -18,16 +18,16 @@
class SymbolFileDWARFDwo : public SymbolFileDWARF {
public:
- SymbolFileDWARFDwo(lldb::ObjectFileSP objfile, DWARFCompileUnit *dwarf_cu);
+ SymbolFileDWARFDwo(lldb::ObjectFileSP objfile, DWARFUnit *dwarf_cu);
~SymbolFileDWARFDwo() override = default;
- lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit *dwarf_cu,
+ lldb::CompUnitSP ParseCompileUnit(DWARFUnit *dwarf_cu,
uint32_t cu_idx) override;
- DWARFCompileUnit *GetCompileUnit();
+ DWARFUnit *GetCompileUnit();
- DWARFCompileUnit *
+ DWARFUnit *
GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) override;
lldb_private::DWARFExpression::LocationListFormat
@@ -43,12 +43,12 @@ public:
GetDIE(const DIERef &die_ref) override;
std::unique_ptr<SymbolFileDWARFDwo>
- GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu,
+ GetDwoSymbolFileForCompileUnit(DWARFUnit &dwarf_cu,
const DWARFDebugInfoEntry &cu_die) override {
return nullptr;
}
- DWARFCompileUnit *GetBaseCompileUnit() override;
+ DWARFUnit *GetBaseCompileUnit() override;
protected:
void LoadSectionData(lldb::SectionType sect_type,
@@ -74,7 +74,7 @@ protected:
SymbolFileDWARF *GetBaseSymbolFile();
lldb::ObjectFileSP m_obj_file_sp;
- DWARFCompileUnit *m_base_dwarf_cu;
+ DWARFUnit *m_base_dwarf_cu;
};
#endif // SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp
index f6de1818eae0..403c10fe65ea 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp
@@ -14,7 +14,7 @@
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/LLDBAssert.h"
-#include "DWARFCompileUnit.h"
+#include "DWARFUnit.h"
#include "DWARFDebugInfo.h"
using namespace lldb;
@@ -22,7 +22,7 @@ using namespace lldb_private;
SymbolFileDWARFDwoDwp::SymbolFileDWARFDwoDwp(SymbolFileDWARFDwp *dwp_symfile,
ObjectFileSP objfile,
- DWARFCompileUnit *dwarf_cu,
+ DWARFUnit *dwarf_cu,
uint64_t dwo_id)
: SymbolFileDWARFDwo(objfile, dwarf_cu), m_dwp_symfile(dwp_symfile),
m_dwo_id(dwo_id) {}
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h
index 00ad7aafd96b..b1b505b5899f 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h
@@ -20,7 +20,7 @@
class SymbolFileDWARFDwoDwp : public SymbolFileDWARFDwo {
public:
SymbolFileDWARFDwoDwp(SymbolFileDWARFDwp *dwp_symfile,
- lldb::ObjectFileSP objfile, DWARFCompileUnit *dwarf_cu,
+ lldb::ObjectFileSP objfile, DWARFUnit *dwarf_cu,
uint64_t dwo_id);
protected:
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
index 1dc1dab34a5c..ae10e7179e33 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
@@ -85,7 +85,7 @@ SymbolFileDWARFDwp::SymbolFileDWARFDwp(lldb::ModuleSP module_sp,
{}
std::unique_ptr<SymbolFileDWARFDwo>
-SymbolFileDWARFDwp::GetSymbolFileForDwoId(DWARFCompileUnit *dwarf_cu,
+SymbolFileDWARFDwp::GetSymbolFileForDwoId(DWARFUnit *dwarf_cu,
uint64_t dwo_id) {
return std::unique_ptr<SymbolFileDWARFDwo>(
new SymbolFileDWARFDwoDwp(this, m_obj_file, dwarf_cu, dwo_id));
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h
index a7372b9358b1..470d1c5b1c48 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h
@@ -29,7 +29,7 @@ public:
Create(lldb::ModuleSP module_sp, const lldb_private::FileSpec &file_spec);
std::unique_ptr<SymbolFileDWARFDwo>
- GetSymbolFileForDwoId(DWARFCompileUnit *dwarf_cu, uint64_t dwo_id);
+ GetSymbolFileForDwoId(DWARFUnit *dwarf_cu, uint64_t dwo_id);
bool LoadSectionData(uint64_t dwo_id, lldb::SectionType sect_type,
lldb_private::DWARFDataExtractor &data);
diff --git a/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp b/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
index 8697e08dbf86..8273d975e57d 100644
--- a/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
+++ b/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
@@ -27,8 +27,8 @@ bool UniqueDWARFASTTypeList::Find(const DWARFDIE &die,
udt.m_byte_size == byte_size) {
// Make sure the file and line match
if (udt.m_declaration == decl) {
- // The type has the same name, and was defined on the same
- // file and line. Now verify all of the parent DIEs match.
+ // The type has the same name, and was defined on the same file and
+ // line. Now verify all of the parent DIEs match.
DWARFDIE parent_arg_die = die.GetParent();
DWARFDIE parent_pos_die = udt.m_die.GetParent();
bool match = true;
@@ -57,6 +57,7 @@ bool UniqueDWARFASTTypeList::Find(const DWARFDIE &die,
} break;
case DW_TAG_compile_unit:
+ case DW_TAG_partial_unit:
done = true;
break;
}
diff --git a/source/Plugins/SymbolFile/PDB/CMakeLists.txt b/source/Plugins/SymbolFile/PDB/CMakeLists.txt
index 871f382298d6..1c176c32224d 100644
--- a/source/Plugins/SymbolFile/PDB/CMakeLists.txt
+++ b/source/Plugins/SymbolFile/PDB/CMakeLists.txt
@@ -1,5 +1,6 @@
add_lldb_library(lldbPluginSymbolFilePDB PLUGIN
PDBASTParser.cpp
+ PDBLocationToDWARFExpression.cpp
SymbolFilePDB.cpp
LINK_LIBS
diff --git a/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
index 7802d6f0d859..8bea994aae5d 100644
--- a/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
+++ b/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -19,19 +19,22 @@
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeSystem.h"
+#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
+#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
using namespace lldb;
using namespace lldb_private;
-using namespace llvm;
using namespace llvm::pdb;
namespace {
@@ -46,7 +49,7 @@ int TranslateUdtKind(PDB_UdtType pdb_kind) {
case PDB_UdtType::Interface:
return clang::TTK_Interface;
}
- return clang::TTK_Class;
+ return -1;
}
lldb::Encoding TranslateBuiltinEncoding(PDB_BuiltinType type) {
@@ -58,16 +61,146 @@ lldb::Encoding TranslateBuiltinEncoding(PDB_BuiltinType type) {
case PDB_BuiltinType::Char:
return lldb::eEncodingSint;
case PDB_BuiltinType::Bool:
+ case PDB_BuiltinType::Char16:
+ case PDB_BuiltinType::Char32:
case PDB_BuiltinType::UInt:
case PDB_BuiltinType::ULong:
case PDB_BuiltinType::HResult:
+ case PDB_BuiltinType::WCharT:
return lldb::eEncodingUint;
default:
return lldb::eEncodingInvalid;
}
}
+
+lldb::Encoding TranslateEnumEncoding(PDB_VariantType type) {
+ switch (type) {
+ case PDB_VariantType::Int8:
+ case PDB_VariantType::Int16:
+ case PDB_VariantType::Int32:
+ case PDB_VariantType::Int64:
+ return lldb::eEncodingSint;
+
+ case PDB_VariantType::UInt8:
+ case PDB_VariantType::UInt16:
+ case PDB_VariantType::UInt32:
+ case PDB_VariantType::UInt64:
+ return lldb::eEncodingUint;
+
+ default:
+ break;
+ }
+
+ return lldb::eEncodingSint;
}
+CompilerType
+GetBuiltinTypeForPDBEncodingAndBitSize(ClangASTContext &clang_ast,
+ const PDBSymbolTypeBuiltin &pdb_type,
+ Encoding encoding, uint32_t width) {
+ auto *ast = clang_ast.getASTContext();
+ if (!ast)
+ return CompilerType();
+
+ switch (pdb_type.getBuiltinType()) {
+ default:
+ break;
+ case PDB_BuiltinType::None:
+ return CompilerType();
+ case PDB_BuiltinType::Void:
+ return clang_ast.GetBasicType(eBasicTypeVoid);
+ case PDB_BuiltinType::Bool:
+ return clang_ast.GetBasicType(eBasicTypeBool);
+ case PDB_BuiltinType::Long:
+ if (width == ast->getTypeSize(ast->LongTy))
+ return CompilerType(ast, ast->LongTy);
+ if (width == ast->getTypeSize(ast->LongLongTy))
+ return CompilerType(ast, ast->LongLongTy);
+ break;
+ case PDB_BuiltinType::ULong:
+ if (width == ast->getTypeSize(ast->UnsignedLongTy))
+ return CompilerType(ast, ast->UnsignedLongTy);
+ if (width == ast->getTypeSize(ast->UnsignedLongLongTy))
+ return CompilerType(ast, ast->UnsignedLongLongTy);
+ break;
+ case PDB_BuiltinType::WCharT:
+ if (width == ast->getTypeSize(ast->WCharTy))
+ return CompilerType(ast, ast->WCharTy);
+ break;
+ case PDB_BuiltinType::Char16:
+ return CompilerType(ast, ast->Char16Ty);
+ case PDB_BuiltinType::Char32:
+ return CompilerType(ast, ast->Char32Ty);
+ case PDB_BuiltinType::Float:
+ // Note: types `long double` and `double` have same bit size in MSVC and
+ // there is no information in the PDB to distinguish them. So when falling
+ // back to default search, the compiler type of `long double` will be
+ // represented by the one generated for `double`.
+ break;
+ }
+ // If there is no match on PDB_BuiltinType, fall back to default search by
+ // encoding and width only
+ return clang_ast.GetBuiltinTypeForEncodingAndBitSize(encoding, width);
+}
+
+ConstString GetPDBBuiltinTypeName(const PDBSymbolTypeBuiltin &pdb_type,
+ CompilerType &compiler_type) {
+ PDB_BuiltinType kind = pdb_type.getBuiltinType();
+ switch (kind) {
+ default:
+ break;
+ case PDB_BuiltinType::Currency:
+ return ConstString("CURRENCY");
+ case PDB_BuiltinType::Date:
+ return ConstString("DATE");
+ case PDB_BuiltinType::Variant:
+ return ConstString("VARIANT");
+ case PDB_BuiltinType::Complex:
+ return ConstString("complex");
+ case PDB_BuiltinType::Bitfield:
+ return ConstString("bitfield");
+ case PDB_BuiltinType::BSTR:
+ return ConstString("BSTR");
+ case PDB_BuiltinType::HResult:
+ return ConstString("HRESULT");
+ case PDB_BuiltinType::BCD:
+ return ConstString("BCD");
+ case PDB_BuiltinType::Char16:
+ return ConstString("char16_t");
+ case PDB_BuiltinType::Char32:
+ return ConstString("char32_t");
+ case PDB_BuiltinType::None:
+ return ConstString("...");
+ }
+ return compiler_type.GetTypeName();
+}
+
+bool GetDeclarationForSymbol(const PDBSymbol &symbol, Declaration &decl) {
+ auto &raw_sym = symbol.getRawSymbol();
+ auto first_line_up = raw_sym.getSrcLineOnTypeDefn();
+
+ if (!first_line_up) {
+ auto lines_up = symbol.getSession().findLineNumbersByAddress(
+ raw_sym.getVirtualAddress(), raw_sym.getLength());
+ if (!lines_up)
+ return false;
+ first_line_up = lines_up->getNext();
+ if (!first_line_up)
+ return false;
+ }
+ uint32_t src_file_id = first_line_up->getSourceFileId();
+ auto src_file_up = symbol.getSession().getSourceFileById(src_file_id);
+ if (!src_file_up)
+ return false;
+
+ FileSpec spec(src_file_up->getFileName(), /*resolve_path*/ false);
+ decl.SetFile(spec);
+ decl.SetColumn(first_line_up->getColumnNumber());
+ decl.SetLine(first_line_up->getLineNumber());
+ return true;
+}
+} // namespace
+
PDBASTParser::PDBASTParser(lldb_private::ClangASTContext &ast) : m_ast(ast) {}
PDBASTParser::~PDBASTParser() {}
@@ -76,21 +209,27 @@ PDBASTParser::~PDBASTParser() {}
lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
// PDB doesn't maintain enough information to robustly rebuild the entire
- // tree, and this is most problematic when it comes to figure out the
- // right DeclContext to put a type in. So for now, everything goes in
- // the translation unit decl as a fully qualified type.
+ // tree, and this is most problematic when it comes to figure out the right
+ // DeclContext to put a type in. So for now, everything goes in the
+ // translation unit decl as a fully qualified type.
clang::DeclContext *tu_decl_ctx = m_ast.GetTranslationUnitDecl();
Declaration decl;
- if (auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&type)) {
+ switch (type.getSymTag()) {
+ case PDB_SymType::UDT: {
+ auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&type);
+ assert(udt);
AccessType access = lldb::eAccessPublic;
PDB_UdtType udt_kind = udt->getUdtKind();
+ auto tag_type_kind = TranslateUdtKind(udt_kind);
+ if (tag_type_kind == -1)
+ return nullptr;
if (udt_kind == PDB_UdtType::Class)
access = lldb::eAccessPrivate;
CompilerType clang_type = m_ast.CreateRecordType(
- tu_decl_ctx, access, udt->getName().c_str(), TranslateUdtKind(udt_kind),
+ tu_decl_ctx, access, udt->getName().c_str(), tag_type_kind,
lldb::eLanguageTypeC_plus_plus, nullptr);
m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
@@ -100,51 +239,107 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
ConstString(udt->getName()), udt->getLength(), nullptr,
LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, clang_type,
lldb_private::Type::eResolveStateForward);
- } else if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(&type)) {
- std::string name = enum_type->getName();
+ } break;
+ case PDB_SymType::Enum: {
+ auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(&type);
+ assert(enum_type);
+ auto underlying_type_up = enum_type->getUnderlyingType();
+ if (!underlying_type_up)
+ return nullptr;
lldb::Encoding encoding =
- TranslateBuiltinEncoding(enum_type->getBuiltinType());
+ TranslateBuiltinEncoding(underlying_type_up->getBuiltinType());
+ // FIXME: Type of underlying builtin is always `Int`. We correct it with
+ // the very first enumerator's encoding if any.
+ auto first_child = enum_type->findOneChild<PDBSymbolData>();
+ if (first_child) {
+ encoding = TranslateEnumEncoding(first_child->getValue().Type);
+ }
+ std::string name = enum_type->getName();
uint64_t bytes = enum_type->getLength();
- CompilerType builtin_type =
- m_ast.GetBuiltinTypeForEncodingAndBitSize(encoding, bytes * 8);
+ CompilerType builtin_type;
+ if (bytes > 0)
+ builtin_type = GetBuiltinTypeForPDBEncodingAndBitSize(
+ m_ast, *underlying_type_up, encoding, bytes * 8);
+ else
+ builtin_type = m_ast.GetBasicType(eBasicTypeInt);
+ // FIXME: PDB does not have information about scoped enumeration (Enum
+ // Class). Set it false for now.
+ bool isScoped = false;
CompilerType ast_enum = m_ast.CreateEnumerationType(
- name.c_str(), tu_decl_ctx, decl, builtin_type, false);
+ name.c_str(), tu_decl_ctx, decl, builtin_type, isScoped);
auto enum_values = enum_type->findAllChildren<PDBSymbolData>();
- while (auto enum_value = enum_values->getNext()) {
- if (enum_value->getDataKind() != PDB_DataKind::Constant)
- continue;
- AddEnumValue(ast_enum, *enum_value);
+ if (enum_values) {
+ while (auto enum_value = enum_values->getNext()) {
+ if (enum_value->getDataKind() != PDB_DataKind::Constant)
+ continue;
+ AddEnumValue(ast_enum, *enum_value);
+ }
}
+ if (ClangASTContext::StartTagDeclarationDefinition(ast_enum))
+ ClangASTContext::CompleteTagDeclarationDefinition(ast_enum);
+ GetDeclarationForSymbol(type, decl);
return std::make_shared<lldb_private::Type>(
type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), bytes,
nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
ast_enum, lldb_private::Type::eResolveStateFull);
- } else if (auto type_def = llvm::dyn_cast<PDBSymbolTypeTypedef>(&type)) {
+ } break;
+ case PDB_SymType::Typedef: {
+ auto type_def = llvm::dyn_cast<PDBSymbolTypeTypedef>(&type);
+ assert(type_def);
lldb_private::Type *target_type =
m_ast.GetSymbolFile()->ResolveTypeUID(type_def->getTypeId());
if (!target_type)
return nullptr;
std::string name = type_def->getName();
uint64_t bytes = type_def->getLength();
- if (!target_type)
- return nullptr;
CompilerType target_ast_type = target_type->GetFullCompilerType();
CompilerDeclContext target_decl_ctx =
m_ast.GetSymbolFile()->GetDeclContextForUID(target_type->GetID());
CompilerType ast_typedef =
m_ast.CreateTypedefType(target_ast_type, name.c_str(), target_decl_ctx);
+ if (!ast_typedef)
+ return nullptr;
+
return std::make_shared<lldb_private::Type>(
type_def->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name),
bytes, nullptr, target_type->GetID(),
lldb_private::Type::eEncodingIsTypedefUID, decl, ast_typedef,
lldb_private::Type::eResolveStateFull);
- } else if (auto func_sig = llvm::dyn_cast<PDBSymbolTypeFunctionSig>(&type)) {
+ } break;
+ case PDB_SymType::Function:
+ case PDB_SymType::FunctionSig: {
+ std::string name;
+ PDBSymbolTypeFunctionSig *func_sig = nullptr;
+ if (auto pdb_func = llvm::dyn_cast<PDBSymbolFunc>(&type)) {
+ if (pdb_func->isCompilerGenerated())
+ return nullptr;
+
+ auto sig = pdb_func->getSignature();
+ if (!sig)
+ return nullptr;
+ func_sig = sig.release();
+ // Function type is named.
+ name = pdb_func->getName();
+ } else if (auto pdb_func_sig =
+ llvm::dyn_cast<PDBSymbolTypeFunctionSig>(&type)) {
+ func_sig = const_cast<PDBSymbolTypeFunctionSig *>(pdb_func_sig);
+ } else
+ llvm_unreachable("Unexpected PDB symbol!");
+
auto arg_enum = func_sig->getArguments();
uint32_t num_args = arg_enum->getChildCount();
- std::vector<CompilerType> arg_list(num_args);
- while (auto arg = arg_enum->getNext()) {
+ std::vector<CompilerType> arg_list;
+
+ bool is_variadic = func_sig->isCVarArgs();
+ // Drop last variadic argument.
+ if (is_variadic)
+ --num_args;
+ for (uint32_t arg_idx = 0; arg_idx < num_args; arg_idx++) {
+ auto arg = arg_enum->getChildAtIndex(arg_idx);
+ if (!arg)
+ break;
lldb_private::Type *arg_type =
m_ast.GetSymbolFile()->ResolveTypeUID(arg->getSymIndexId());
// If there's some error looking up one of the dependent types of this
@@ -154,6 +349,8 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
CompilerType arg_ast_type = arg_type->GetFullCompilerType();
arg_list.push_back(arg_ast_type);
}
+ lldbassert(arg_list.size() <= num_args);
+
auto pdb_return_type = func_sig->getReturnType();
lldb_private::Type *return_type =
m_ast.GetSymbolFile()->ResolveTypeUID(pdb_return_type->getSymIndexId());
@@ -167,29 +364,109 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
type_quals |= clang::Qualifiers::Const;
if (func_sig->isVolatileType())
type_quals |= clang::Qualifiers::Volatile;
- CompilerType func_sig_ast_type = m_ast.CreateFunctionType(
- return_ast_type, &arg_list[0], num_args, false, type_quals);
+ CompilerType func_sig_ast_type =
+ m_ast.CreateFunctionType(return_ast_type, arg_list.data(),
+ arg_list.size(), is_variadic, type_quals);
+ GetDeclarationForSymbol(type, decl);
return std::make_shared<lldb_private::Type>(
- func_sig->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(), 0,
+ type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), 0,
nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
func_sig_ast_type, lldb_private::Type::eResolveStateFull);
- } else if (auto array_type = llvm::dyn_cast<PDBSymbolTypeArray>(&type)) {
+ } break;
+ case PDB_SymType::ArrayType: {
+ auto array_type = llvm::dyn_cast<PDBSymbolTypeArray>(&type);
+ assert(array_type);
uint32_t num_elements = array_type->getCount();
- uint32_t element_uid = array_type->getElementType()->getSymIndexId();
+ uint32_t element_uid = array_type->getElementTypeId();
uint32_t bytes = array_type->getLength();
+ // If array rank > 0, PDB gives the element type at N=0. So element type
+ // will parsed in the order N=0, N=1,..., N=rank sequentially.
lldb_private::Type *element_type =
m_ast.GetSymbolFile()->ResolveTypeUID(element_uid);
if (!element_type)
return nullptr;
- CompilerType element_ast_type = element_type->GetFullCompilerType();
- CompilerType array_ast_type =
- m_ast.CreateArrayType(element_ast_type, num_elements, false);
- return std::make_shared<lldb_private::Type>(
+
+ CompilerType element_ast_type = element_type->GetForwardCompilerType();
+ // If element type is UDT, it needs to be complete.
+ if (ClangASTContext::IsCXXClassType(element_ast_type) &&
+ element_ast_type.GetCompleteType() == false) {
+ if (ClangASTContext::StartTagDeclarationDefinition(element_ast_type)) {
+ ClangASTContext::CompleteTagDeclarationDefinition(element_ast_type);
+ } else {
+ // We are not able to start defintion.
+ return nullptr;
+ }
+ }
+ CompilerType array_ast_type = m_ast.CreateArrayType(
+ element_ast_type, num_elements, /*is_gnu_vector*/ false);
+ TypeSP type_sp = std::make_shared<lldb_private::Type>(
array_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(),
bytes, nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID,
decl, array_ast_type, lldb_private::Type::eResolveStateFull);
+ type_sp->SetEncodingType(element_type);
+ return type_sp;
+ } break;
+ case PDB_SymType::BuiltinType: {
+ auto *builtin_type = llvm::dyn_cast<PDBSymbolTypeBuiltin>(&type);
+ assert(builtin_type);
+ PDB_BuiltinType builtin_kind = builtin_type->getBuiltinType();
+ if (builtin_kind == PDB_BuiltinType::None)
+ return nullptr;
+
+ uint64_t bytes = builtin_type->getLength();
+ Encoding encoding = TranslateBuiltinEncoding(builtin_kind);
+ CompilerType builtin_ast_type = GetBuiltinTypeForPDBEncodingAndBitSize(
+ m_ast, *builtin_type, encoding, bytes * 8);
+
+ if (builtin_type->isConstType())
+ builtin_ast_type = builtin_ast_type.AddConstModifier();
+
+ if (builtin_type->isVolatileType())
+ builtin_ast_type = builtin_ast_type.AddVolatileModifier();
+
+ auto type_name = GetPDBBuiltinTypeName(*builtin_type, builtin_ast_type);
+
+ return std::make_shared<lldb_private::Type>(
+ builtin_type->getSymIndexId(), m_ast.GetSymbolFile(), type_name, bytes,
+ nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
+ builtin_ast_type, lldb_private::Type::eResolveStateFull);
+ } break;
+ case PDB_SymType::PointerType: {
+ auto *pointer_type = llvm::dyn_cast<PDBSymbolTypePointer>(&type);
+ assert(pointer_type);
+ Type *pointee_type = m_ast.GetSymbolFile()->ResolveTypeUID(
+ pointer_type->getPointeeType()->getSymIndexId());
+ if (!pointee_type)
+ return nullptr;
+
+ CompilerType pointer_ast_type;
+ pointer_ast_type = pointee_type->GetFullCompilerType();
+ if (pointer_type->isReference())
+ pointer_ast_type = pointer_ast_type.GetLValueReferenceType();
+ else if (pointer_type->isRValueReference())
+ pointer_ast_type = pointer_ast_type.GetRValueReferenceType();
+ else
+ pointer_ast_type = pointer_ast_type.GetPointerType();
+
+ if (pointer_type->isConstType())
+ pointer_ast_type = pointer_ast_type.AddConstModifier();
+
+ if (pointer_type->isVolatileType())
+ pointer_ast_type = pointer_ast_type.AddVolatileModifier();
+
+ if (pointer_type->isRestrictedType())
+ pointer_ast_type = pointer_ast_type.AddRestrictModifier();
+
+ return std::make_shared<lldb_private::Type>(
+ pointer_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(),
+ pointer_type->getLength(), nullptr, LLDB_INVALID_UID,
+ lldb_private::Type::eEncodingIsUID, decl, pointer_ast_type,
+ lldb_private::Type::eResolveStateFull);
+ } break;
+ default:
+ break;
}
return nullptr;
}
diff --git a/source/Plugins/SymbolFile/PDB/PDBASTParser.h b/source/Plugins/SymbolFile/PDB/PDBASTParser.h
index e9ff02c0a77e..d1ac138b8115 100644
--- a/source/Plugins/SymbolFile/PDB/PDBASTParser.h
+++ b/source/Plugins/SymbolFile/PDB/PDBASTParser.h
@@ -19,20 +19,20 @@ class CharUnits;
class CXXRecordDecl;
class FieldDecl;
class RecordDecl;
-}
+} // namespace clang
namespace lldb_private {
class ClangASTContext;
class CompilerType;
-}
+} // namespace lldb_private
namespace llvm {
namespace pdb {
class PDBSymbol;
class PDBSymbolData;
class PDBSymbolTypeBuiltin;
-}
-}
+} // namespace pdb
+} // namespace llvm
class PDBASTParser {
public:
@@ -49,4 +49,4 @@ private:
lldb_private::ClangASTImporter m_ast_importer;
};
-#endif // SymbolFileDWARF_DWARFASTParserClang_h_
+#endif // LLDB_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H
diff --git a/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp b/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
new file mode 100644
index 000000000000..69ef70cc508c
--- /dev/null
+++ b/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
@@ -0,0 +1,585 @@
+//===-- PDBLocationToDWARFExpression.cpp ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "PDBLocationToDWARFExpression.h"
+
+#include "lldb/Core/Section.h"
+#include "lldb/Core/StreamBuffer.h"
+#include "lldb/Core/dwarf.h"
+#include "lldb/Expression/DWARFExpression.h"
+#include "lldb/Utility/DataBufferHeap.h"
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+
+#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace llvm::pdb;
+
+namespace {
+const uint32_t g_code_view_to_lldb_registers_x86[] = {
+ LLDB_INVALID_REGNUM, // CVRegNONE
+ lldb_al_i386, // CVRegAL
+ lldb_cl_i386, // CVRegCL
+ lldb_dl_i386, // CVRegDL
+ lldb_bl_i386, // CVRegBL
+ lldb_ah_i386, // CVRegAH
+ lldb_ch_i386, // CVRegCH
+ lldb_dh_i386, // CVRegDH
+ lldb_bh_i386, // CVRegBH
+ lldb_ax_i386, // CVRegAX
+ lldb_cx_i386, // CVRegCX
+ lldb_dx_i386, // CVRegDX
+ lldb_bx_i386, // CVRegBX
+ lldb_sp_i386, // CVRegSP
+ lldb_bp_i386, // CVRegBP
+ lldb_si_i386, // CVRegSI
+ lldb_di_i386, // CVRegDI
+ lldb_eax_i386, // CVRegEAX
+ lldb_ecx_i386, // CVRegECX
+ lldb_edx_i386, // CVRegEDX
+ lldb_ebx_i386, // CVRegEBX
+ lldb_esp_i386, // CVRegESP
+ lldb_ebp_i386, // CVRegEBP
+ lldb_esi_i386, // CVRegESI
+ lldb_edi_i386, // CVRegEDI
+ lldb_es_i386, // CVRegES
+ lldb_cs_i386, // CVRegCS
+ lldb_ss_i386, // CVRegSS
+ lldb_ds_i386, // CVRegDS
+ lldb_fs_i386, // CVRegFS
+ lldb_gs_i386, // CVRegGS
+ LLDB_INVALID_REGNUM, // CVRegIP
+ LLDB_INVALID_REGNUM, // CVRegFLAGS
+ lldb_eip_i386, // CVRegEIP
+ lldb_eflags_i386, // CVRegEFLAGS
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, // CVRegTEMP
+ LLDB_INVALID_REGNUM, // CVRegTEMPH
+ LLDB_INVALID_REGNUM, // CVRegQUOTE
+ LLDB_INVALID_REGNUM, // CVRegPCDR3
+ LLDB_INVALID_REGNUM, // CVRegPCDR4
+ LLDB_INVALID_REGNUM, // CVRegPCDR5
+ LLDB_INVALID_REGNUM, // CVRegPCDR6
+ LLDB_INVALID_REGNUM, // CVRegPCDR7
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, // CVRegCR0
+ LLDB_INVALID_REGNUM, // CVRegCR1
+ LLDB_INVALID_REGNUM, // CVRegCR2
+ LLDB_INVALID_REGNUM, // CVRegCR3
+ LLDB_INVALID_REGNUM, // CVRegCR4
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ lldb_dr0_i386, // CVRegDR0
+ lldb_dr1_i386, // CVRegDR1
+ lldb_dr2_i386, // CVRegDR2
+ lldb_dr3_i386, // CVRegDR3
+ lldb_dr4_i386, // CVRegDR4
+ lldb_dr5_i386, // CVRegDR5
+ lldb_dr6_i386, // CVRegDR6
+ lldb_dr7_i386, // CVRegDR7
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, // CVRegGDTR
+ LLDB_INVALID_REGNUM, // CVRegGDTL
+ LLDB_INVALID_REGNUM, // CVRegIDTR
+ LLDB_INVALID_REGNUM, // CVRegIDTL
+ LLDB_INVALID_REGNUM, // CVRegLDTR
+ LLDB_INVALID_REGNUM, // CVRegTR
+ LLDB_INVALID_REGNUM, // CVRegPSEUDO1
+ LLDB_INVALID_REGNUM, // CVRegPSEUDO2
+ LLDB_INVALID_REGNUM, // CVRegPSEUDO3
+ LLDB_INVALID_REGNUM, // CVRegPSEUDO4
+ LLDB_INVALID_REGNUM, // CVRegPSEUDO5
+ LLDB_INVALID_REGNUM, // CVRegPSEUDO6
+ LLDB_INVALID_REGNUM, // CVRegPSEUDO7
+ LLDB_INVALID_REGNUM, // CVRegPSEUDO8
+ LLDB_INVALID_REGNUM, // CVRegPSEUDO9
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ lldb_st0_i386, // CVRegST0
+ lldb_st1_i386, // CVRegST1
+ lldb_st2_i386, // CVRegST2
+ lldb_st3_i386, // CVRegST3
+ lldb_st4_i386, // CVRegST4
+ lldb_st5_i386, // CVRegST5
+ lldb_st6_i386, // CVRegST6
+ lldb_st7_i386, // CVRegST7
+ LLDB_INVALID_REGNUM, // CVRegCTRL
+ LLDB_INVALID_REGNUM, // CVRegSTAT
+ LLDB_INVALID_REGNUM, // CVRegTAG
+ LLDB_INVALID_REGNUM, // CVRegFPIP
+ LLDB_INVALID_REGNUM, // CVRegFPCS
+ LLDB_INVALID_REGNUM, // CVRegFPDO
+ LLDB_INVALID_REGNUM, // CVRegFPDS
+ LLDB_INVALID_REGNUM, // CVRegISEM
+ LLDB_INVALID_REGNUM, // CVRegFPEIP
+ LLDB_INVALID_REGNUM, // CVRegFPEDO
+ lldb_mm0_i386, // CVRegMM0
+ lldb_mm1_i386, // CVRegMM1
+ lldb_mm2_i386, // CVRegMM2
+ lldb_mm3_i386, // CVRegMM3
+ lldb_mm4_i386, // CVRegMM4
+ lldb_mm5_i386, // CVRegMM5
+ lldb_mm6_i386, // CVRegMM6
+ lldb_mm7_i386, // CVRegMM7
+ lldb_xmm0_i386, // CVRegXMM0
+ lldb_xmm1_i386, // CVRegXMM1
+ lldb_xmm2_i386, // CVRegXMM2
+ lldb_xmm3_i386, // CVRegXMM3
+ lldb_xmm4_i386, // CVRegXMM4
+ lldb_xmm5_i386, // CVRegXMM5
+ lldb_xmm6_i386, // CVRegXMM6
+ lldb_xmm7_i386 // CVRegXMM7
+};
+
+const uint32_t g_code_view_to_lldb_registers_x86_64[] = {
+ LLDB_INVALID_REGNUM, // CVRegNONE
+ lldb_al_x86_64, // CVRegAL
+ lldb_cl_x86_64, // CVRegCL
+ lldb_dl_x86_64, // CVRegDL
+ lldb_bl_x86_64, // CVRegBL
+ lldb_ah_x86_64, // CVRegAH
+ lldb_ch_x86_64, // CVRegCH
+ lldb_dh_x86_64, // CVRegDH
+ lldb_bh_x86_64, // CVRegBH
+ lldb_ax_x86_64, // CVRegAX
+ lldb_cx_x86_64, // CVRegCX
+ lldb_dx_x86_64, // CVRegDX
+ lldb_bx_x86_64, // CVRegBX
+ lldb_sp_x86_64, // CVRegSP
+ lldb_bp_x86_64, // CVRegBP
+ lldb_si_x86_64, // CVRegSI
+ lldb_di_x86_64, // CVRegDI
+ lldb_eax_x86_64, // CVRegEAX
+ lldb_ecx_x86_64, // CVRegECX
+ lldb_edx_x86_64, // CVRegEDX
+ lldb_ebx_x86_64, // CVRegEBX
+ lldb_esp_x86_64, // CVRegESP
+ lldb_ebp_x86_64, // CVRegEBP
+ lldb_esi_x86_64, // CVRegESI
+ lldb_edi_x86_64, // CVRegEDI
+ lldb_es_x86_64, // CVRegES
+ lldb_cs_x86_64, // CVRegCS
+ lldb_ss_x86_64, // CVRegSS
+ lldb_ds_x86_64, // CVRegDS
+ lldb_fs_x86_64, // CVRegFS
+ lldb_gs_x86_64, // CVRegGS
+ LLDB_INVALID_REGNUM, // CVRegIP
+ LLDB_INVALID_REGNUM, // CVRegFLAGS
+ LLDB_INVALID_REGNUM, // CVRegEIP
+ LLDB_INVALID_REGNUM, // CVRegEFLAGS
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, // CVRegTEMP
+ LLDB_INVALID_REGNUM, // CVRegTEMPH
+ LLDB_INVALID_REGNUM, // CVRegQUOTE
+ LLDB_INVALID_REGNUM, // CVRegPCDR3
+ LLDB_INVALID_REGNUM, // CVRegPCDR4
+ LLDB_INVALID_REGNUM, // CVRegPCDR5
+ LLDB_INVALID_REGNUM, // CVRegPCDR6
+ LLDB_INVALID_REGNUM, // CVRegPCDR7
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, // CVRegCR0
+ LLDB_INVALID_REGNUM, // CVRegCR1
+ LLDB_INVALID_REGNUM, // CVRegCR2
+ LLDB_INVALID_REGNUM, // CVRegCR3
+ LLDB_INVALID_REGNUM, // CVRegCR4
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ lldb_dr0_x86_64, // CVRegDR0
+ lldb_dr1_x86_64, // CVRegDR1
+ lldb_dr2_x86_64, // CVRegDR2
+ lldb_dr3_x86_64, // CVRegDR3
+ lldb_dr4_x86_64, // CVRegDR4
+ lldb_dr5_x86_64, // CVRegDR5
+ lldb_dr6_x86_64, // CVRegDR6
+ lldb_dr7_x86_64, // CVRegDR7
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, // CVRegGDTR
+ LLDB_INVALID_REGNUM, // CVRegGDTL
+ LLDB_INVALID_REGNUM, // CVRegIDTR
+ LLDB_INVALID_REGNUM, // CVRegIDTL
+ LLDB_INVALID_REGNUM, // CVRegLDTR
+ LLDB_INVALID_REGNUM, // CVRegTR
+ LLDB_INVALID_REGNUM, // CVRegPSEUDO1
+ LLDB_INVALID_REGNUM, // CVRegPSEUDO2
+ LLDB_INVALID_REGNUM, // CVRegPSEUDO3
+ LLDB_INVALID_REGNUM, // CVRegPSEUDO4
+ LLDB_INVALID_REGNUM, // CVRegPSEUDO5
+ LLDB_INVALID_REGNUM, // CVRegPSEUDO6
+ LLDB_INVALID_REGNUM, // CVRegPSEUDO7
+ LLDB_INVALID_REGNUM, // CVRegPSEUDO8
+ LLDB_INVALID_REGNUM, // CVRegPSEUDO9
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ lldb_st0_x86_64, // CVRegST0
+ lldb_st1_x86_64, // CVRegST1
+ lldb_st2_x86_64, // CVRegST2
+ lldb_st3_x86_64, // CVRegST3
+ lldb_st4_x86_64, // CVRegST4
+ lldb_st5_x86_64, // CVRegST5
+ lldb_st6_x86_64, // CVRegST6
+ lldb_st7_x86_64, // CVRegST7
+ LLDB_INVALID_REGNUM, // CVRegCTRL
+ LLDB_INVALID_REGNUM, // CVRegSTAT
+ LLDB_INVALID_REGNUM, // CVRegTAG
+ LLDB_INVALID_REGNUM, // CVRegFPIP
+ LLDB_INVALID_REGNUM, // CVRegFPCS
+ LLDB_INVALID_REGNUM, // CVRegFPDO
+ LLDB_INVALID_REGNUM, // CVRegFPDS
+ LLDB_INVALID_REGNUM, // CVRegISEM
+ LLDB_INVALID_REGNUM, // CVRegFPEIP
+ LLDB_INVALID_REGNUM, // CVRegFPEDO
+ lldb_mm0_x86_64, // CVRegMM0
+ lldb_mm1_x86_64, // CVRegMM1
+ lldb_mm2_x86_64, // CVRegMM2
+ lldb_mm3_x86_64, // CVRegMM3
+ lldb_mm4_x86_64, // CVRegMM4
+ lldb_mm5_x86_64, // CVRegMM5
+ lldb_mm6_x86_64, // CVRegMM6
+ lldb_mm7_x86_64, // CVRegMM7
+ lldb_xmm0_x86_64, // CVRegXMM0
+ lldb_xmm1_x86_64, // CVRegXMM1
+ lldb_xmm2_x86_64, // CVRegXMM2
+ lldb_xmm3_x86_64, // CVRegXMM3
+ lldb_xmm4_x86_64, // CVRegXMM4
+ lldb_xmm5_x86_64, // CVRegXMM5
+ lldb_xmm6_x86_64, // CVRegXMM6
+ lldb_xmm7_x86_64, // CVRegXMM7
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM,
+ lldb_mxcsr_x86_64, // CVRegMXCSR
+ LLDB_INVALID_REGNUM, // CVRegEDXEAX
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, // CVRegEMM0L
+ LLDB_INVALID_REGNUM, // CVRegEMM1L
+ LLDB_INVALID_REGNUM, // CVRegEMM2L
+ LLDB_INVALID_REGNUM, // CVRegEMM3L
+ LLDB_INVALID_REGNUM, // CVRegEMM4L
+ LLDB_INVALID_REGNUM, // CVRegEMM5L
+ LLDB_INVALID_REGNUM, // CVRegEMM6L
+ LLDB_INVALID_REGNUM, // CVRegEMM7L
+ LLDB_INVALID_REGNUM, // CVRegEMM0H
+ LLDB_INVALID_REGNUM, // CVRegEMM1H
+ LLDB_INVALID_REGNUM, // CVRegEMM2H
+ LLDB_INVALID_REGNUM, // CVRegEMM3H
+ LLDB_INVALID_REGNUM, // CVRegEMM4H
+ LLDB_INVALID_REGNUM, // CVRegEMM5H
+ LLDB_INVALID_REGNUM, // CVRegEMM6H
+ LLDB_INVALID_REGNUM, // CVRegEMM7H
+ LLDB_INVALID_REGNUM, // CVRegMM00
+ LLDB_INVALID_REGNUM, // CVRegMM01
+ LLDB_INVALID_REGNUM, // CVRegMM10
+ LLDB_INVALID_REGNUM, // CVRegMM11
+ LLDB_INVALID_REGNUM, // CVRegMM20
+ LLDB_INVALID_REGNUM, // CVRegMM21
+ LLDB_INVALID_REGNUM, // CVRegMM30
+ LLDB_INVALID_REGNUM, // CVRegMM31
+ LLDB_INVALID_REGNUM, // CVRegMM40
+ LLDB_INVALID_REGNUM, // CVRegMM41
+ LLDB_INVALID_REGNUM, // CVRegMM50
+ LLDB_INVALID_REGNUM, // CVRegMM51
+ LLDB_INVALID_REGNUM, // CVRegMM60
+ LLDB_INVALID_REGNUM, // CVRegMM61
+ LLDB_INVALID_REGNUM, // CVRegMM70
+ LLDB_INVALID_REGNUM, // CVRegMM71
+ lldb_xmm8_x86_64, // CVRegXMM8
+ lldb_xmm9_x86_64, // CVRegXMM9
+ lldb_xmm10_x86_64, // CVRegXMM10
+ lldb_xmm11_x86_64, // CVRegXMM11
+ lldb_xmm12_x86_64, // CVRegXMM12
+ lldb_xmm13_x86_64, // CVRegXMM13
+ lldb_xmm14_x86_64, // CVRegXMM14
+ lldb_xmm15_x86_64, // CVRegXMM15
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM,
+ lldb_sil_x86_64, // CVRegSIL
+ lldb_dil_x86_64, // CVRegDIL
+ lldb_bpl_x86_64, // CVRegBPL
+ lldb_spl_x86_64, // CVRegSPL
+ lldb_rax_x86_64, // CVRegRAX
+ lldb_rbx_x86_64, // CVRegRBX
+ lldb_rcx_x86_64, // CVRegRCX
+ lldb_rdx_x86_64, // CVRegRDX
+ lldb_rsi_x86_64, // CVRegRSI
+ lldb_rdi_x86_64, // CVRegRDI
+ lldb_rbp_x86_64, // CVRegRBP
+ lldb_rsp_x86_64, // CVRegRSP
+ lldb_r8_x86_64, // CVRegR8
+ lldb_r9_x86_64, // CVRegR9
+ lldb_r10_x86_64, // CVRegR10
+ lldb_r11_x86_64, // CVRegR11
+ lldb_r12_x86_64, // CVRegR12
+ lldb_r13_x86_64, // CVRegR13
+ lldb_r14_x86_64, // CVRegR14
+ lldb_r15_x86_64, // CVRegR15
+ lldb_r8l_x86_64, // CVRegR8B
+ lldb_r9l_x86_64, // CVRegR9B
+ lldb_r10l_x86_64, // CVRegR10B
+ lldb_r11l_x86_64, // CVRegR11B
+ lldb_r12l_x86_64, // CVRegR12B
+ lldb_r13l_x86_64, // CVRegR13B
+ lldb_r14l_x86_64, // CVRegR14B
+ lldb_r15l_x86_64, // CVRegR15B
+ lldb_r8w_x86_64, // CVRegR8W
+ lldb_r9w_x86_64, // CVRegR9W
+ lldb_r10w_x86_64, // CVRegR10W
+ lldb_r11w_x86_64, // CVRegR11W
+ lldb_r12w_x86_64, // CVRegR12W
+ lldb_r13w_x86_64, // CVRegR13W
+ lldb_r14w_x86_64, // CVRegR14W
+ lldb_r15w_x86_64, // CVRegR15W
+ lldb_r8d_x86_64, // CVRegR8D
+ lldb_r9d_x86_64, // CVRegR9D
+ lldb_r10d_x86_64, // CVRegR10D
+ lldb_r11d_x86_64, // CVRegR11D
+ lldb_r12d_x86_64, // CVRegR12D
+ lldb_r13d_x86_64, // CVRegR13D
+ lldb_r14d_x86_64, // CVRegR14D
+ lldb_r15d_x86_64, // CVRegR15D
+ lldb_ymm0_x86_64, // CVRegAMD64_YMM0
+ lldb_ymm1_x86_64, // CVRegAMD64_YMM1
+ lldb_ymm2_x86_64, // CVRegAMD64_YMM2
+ lldb_ymm3_x86_64, // CVRegAMD64_YMM3
+ lldb_ymm4_x86_64, // CVRegAMD64_YMM4
+ lldb_ymm5_x86_64, // CVRegAMD64_YMM5
+ lldb_ymm6_x86_64, // CVRegAMD64_YMM6
+ lldb_ymm7_x86_64, // CVRegAMD64_YMM7
+ lldb_ymm8_x86_64, // CVRegAMD64_YMM8
+ lldb_ymm9_x86_64, // CVRegAMD64_YMM9
+ lldb_ymm10_x86_64, // CVRegAMD64_YMM10
+ lldb_ymm11_x86_64, // CVRegAMD64_YMM11
+ lldb_ymm12_x86_64, // CVRegAMD64_YMM12
+ lldb_ymm13_x86_64, // CVRegAMD64_YMM13
+ lldb_ymm14_x86_64, // CVRegAMD64_YMM14
+ lldb_ymm15_x86_64, // CVRegAMD64_YMM15
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ lldb_bnd0_x86_64, // CVRegBND0
+ lldb_bnd1_x86_64, // CVRegBND1
+ lldb_bnd2_x86_64 // CVRegBND2
+};
+
+uint32_t GetLLDBRegisterNumber(llvm::Triple::ArchType arch_type,
+ llvm::codeview::RegisterId register_id) {
+ switch (arch_type) {
+ case llvm::Triple::x86:
+ if (static_cast<uint16_t>(register_id) <
+ sizeof(g_code_view_to_lldb_registers_x86) /
+ sizeof(g_code_view_to_lldb_registers_x86[0]))
+ return g_code_view_to_lldb_registers_x86[static_cast<uint16_t>(
+ register_id)];
+
+ switch (register_id) {
+ case llvm::codeview::RegisterId::CVRegMXCSR:
+ return lldb_mxcsr_i386;
+ case llvm::codeview::RegisterId::CVRegBND0:
+ return lldb_bnd0_i386;
+ case llvm::codeview::RegisterId::CVRegBND1:
+ return lldb_bnd1_i386;
+ case llvm::codeview::RegisterId::CVRegBND2:
+ return lldb_bnd2_i386;
+ default:
+ return LLDB_INVALID_REGNUM;
+ }
+ case llvm::Triple::x86_64:
+ if (static_cast<uint16_t>(register_id) <
+ sizeof(g_code_view_to_lldb_registers_x86_64) /
+ sizeof(g_code_view_to_lldb_registers_x86_64[0]))
+ return g_code_view_to_lldb_registers_x86_64[static_cast<uint16_t>(
+ register_id)];
+
+ return LLDB_INVALID_REGNUM;
+ default:
+ return LLDB_INVALID_REGNUM;
+ }
+}
+
+uint32_t GetGenericRegisterNumber(llvm::codeview::RegisterId register_id) {
+ if (register_id == llvm::codeview::RegisterId::CVRegVFRAME)
+ return LLDB_REGNUM_GENERIC_FP;
+
+ return LLDB_INVALID_REGNUM;
+}
+
+uint32_t GetRegisterNumber(llvm::Triple::ArchType arch_type,
+ llvm::codeview::RegisterId register_id,
+ RegisterKind &register_kind) {
+ register_kind = eRegisterKindLLDB;
+ uint32_t reg_num = GetLLDBRegisterNumber(arch_type, register_id);
+ if (reg_num != LLDB_INVALID_REGNUM)
+ return reg_num;
+
+ register_kind = eRegisterKindGeneric;
+ return GetGenericRegisterNumber(register_id);
+}
+} // namespace
+
+DWARFExpression ConvertPDBLocationToDWARFExpression(ModuleSP module,
+ const PDBSymbolData &symbol,
+ bool &is_constant) {
+ is_constant = true;
+
+ if (!module)
+ return DWARFExpression(nullptr);
+
+ const ArchSpec &architecture = module->GetArchitecture();
+ llvm::Triple::ArchType arch_type = architecture.GetMachine();
+ ByteOrder byte_order = architecture.GetByteOrder();
+ uint32_t address_size = architecture.GetAddressByteSize();
+ uint32_t byte_size = architecture.GetDataByteSize();
+ if (byte_order == eByteOrderInvalid || address_size == 0)
+ return DWARFExpression(nullptr);
+
+ RegisterKind register_kind = eRegisterKindDWARF;
+ StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order);
+ switch (symbol.getLocationType()) {
+ case PDB_LocType::Static:
+ case PDB_LocType::TLS: {
+ stream.PutHex8(DW_OP_addr);
+
+ SectionList *section_list = module->GetSectionList();
+ if (!section_list)
+ return DWARFExpression(nullptr);
+
+ uint32_t section_idx = symbol.getAddressSection() - 1;
+ if (section_idx >= section_list->GetSize())
+ return DWARFExpression(nullptr);
+
+ auto section = section_list->GetSectionAtIndex(section_idx);
+ if (!section)
+ return DWARFExpression(nullptr);
+
+ uint32_t offset = symbol.getAddressOffset();
+ stream.PutMaxHex64(section->GetFileAddress() + offset, address_size,
+ byte_order);
+
+ is_constant = false;
+
+ break;
+ }
+ case PDB_LocType::RegRel: {
+ uint32_t reg_num =
+ GetRegisterNumber(arch_type, symbol.getRegisterId(), register_kind);
+ if (reg_num == LLDB_INVALID_REGNUM)
+ return DWARFExpression(nullptr);
+
+ if (reg_num > 31) {
+ stream.PutHex8(DW_OP_bregx);
+ stream.PutULEB128(reg_num);
+ } else
+ stream.PutHex8(DW_OP_breg0 + reg_num);
+
+ int32_t offset = symbol.getOffset();
+ stream.PutSLEB128(offset);
+
+ is_constant = false;
+
+ break;
+ }
+ case PDB_LocType::Enregistered: {
+ uint32_t reg_num =
+ GetRegisterNumber(arch_type, symbol.getRegisterId(), register_kind);
+ if (reg_num == LLDB_INVALID_REGNUM)
+ return DWARFExpression(nullptr);
+
+ if (reg_num > 31) {
+ stream.PutHex8(DW_OP_regx);
+ stream.PutULEB128(reg_num);
+ } else
+ stream.PutHex8(DW_OP_reg0 + reg_num);
+
+ is_constant = false;
+
+ break;
+ }
+ case PDB_LocType::Constant: {
+ Variant value = symbol.getValue();
+ stream.PutRawBytes(&value.Value, sizeof(value.Value),
+ endian::InlHostByteOrder());
+ break;
+ }
+ default:
+ return DWARFExpression(nullptr);
+ }
+
+ DataBufferSP buffer =
+ std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
+ DataExtractor extractor(buffer, byte_order, address_size, byte_size);
+ DWARFExpression result(module, extractor, nullptr, 0, buffer->GetByteSize());
+ result.SetRegisterKind(register_kind);
+
+ return result;
+}
diff --git a/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h b/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h
new file mode 100644
index 000000000000..37b80dfccb84
--- /dev/null
+++ b/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h
@@ -0,0 +1,45 @@
+//===-- PDBLocationToDWARFExpression.h --------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_Plugins_SymbolFile_PDB_PDBLocationToDWARFExpression_h_
+#define lldb_Plugins_SymbolFile_PDB_PDBLocationToDWARFExpression_h_
+
+#include "lldb/Core/Module.h"
+
+namespace lldb_private {
+class DWARFExpression;
+}
+
+namespace llvm {
+namespace pdb {
+class PDBSymbolData;
+}
+} // namespace llvm
+
+//------------------------------------------------------------------------------
+/// Converts a location information from a PDB symbol to a DWARF expression
+///
+/// @param[in] module
+/// The module \a symbol belongs to.
+///
+/// @param[in] symbol
+/// The symbol with a location information to convert.
+///
+/// @param[out] is_constant
+/// Set to \b true if the result expression is a constant value data,
+/// and \b false if it is a DWARF bytecode.
+///
+/// @return
+/// The DWARF expression corresponding to the location data of \a symbol.
+//------------------------------------------------------------------------------
+lldb_private::DWARFExpression
+ConvertPDBLocationToDWARFExpression(lldb::ModuleSP module,
+ const llvm::pdb::PDBSymbolData &symbol,
+ bool &is_constant);
+#endif
diff --git a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index de9b9f024fc7..05f3017819fa 100644
--- a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -18,16 +18,21 @@
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/TypeMap.h"
+#include "lldb/Symbol/Variable.h"
#include "lldb/Utility/RegularExpression.h"
#include "llvm/DebugInfo/PDB/GenericError.h"
#include "llvm/DebugInfo/PDB/IPDBDataStream.h"
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
+#include "llvm/DebugInfo/PDB/IPDBSectionContrib.h"
#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
#include "llvm/DebugInfo/PDB/IPDBTable.h"
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolBlock.h"
#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
#include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
@@ -35,14 +40,18 @@
#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
+#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
#include "Plugins/SymbolFile/PDB/PDBASTParser.h"
+#include "Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h"
#include <regex>
+using namespace lldb;
using namespace lldb_private;
using namespace llvm::pdb;
@@ -63,7 +72,7 @@ bool ShouldAddLine(uint32_t requested_line, uint32_t actual_line,
return ((requested_line == 0 || actual_line == requested_line) &&
addr_length > 0);
}
-}
+} // namespace
void SymbolFilePDB::Initialize() {
PluginManager::RegisterPlugin(GetPluginNameStatic(),
@@ -92,7 +101,8 @@ SymbolFilePDB::CreateInstance(lldb_private::ObjectFile *obj_file) {
}
SymbolFilePDB::SymbolFilePDB(lldb_private::ObjectFile *object_file)
- : SymbolFile(object_file), m_cached_compile_unit_count(0) {}
+ : SymbolFile(object_file), m_session_up(), m_global_scope_up(),
+ m_cached_compile_unit_count(0), m_tu_decl_ctx_up() {}
SymbolFilePDB::~SymbolFilePDB() {}
@@ -116,15 +126,14 @@ uint32_t SymbolFilePDB::CalculateAbilities() {
if (!symfile)
return 0;
error = loadDataForPDB(PDB_ReaderType::DIA,
- llvm::StringRef(symfile.GetPath()),
- m_session_up);
+ llvm::StringRef(symfile.GetPath()), m_session_up);
if (error) {
llvm::consumeError(std::move(error));
return 0;
}
}
}
- if (!m_session_up.get())
+ if (!m_session_up)
return 0;
auto enum_tables_up = m_session_up->getEnumTables();
@@ -138,13 +147,14 @@ uint32_t SymbolFilePDB::CalculateAbilities() {
case PDB_TableType::Symbols:
// This table represents a store of symbols with types listed in
// PDBSym_Type
- abilities |= (CompileUnits | Functions | Blocks |
- GlobalVariables | LocalVariables | VariableTypes);
+ abilities |= (CompileUnits | Functions | Blocks | GlobalVariables |
+ LocalVariables | VariableTypes);
break;
case PDB_TableType::LineNumbers:
abilities |= LineTables;
break;
- default: break;
+ default:
+ break;
}
}
return abilities;
@@ -152,41 +162,88 @@ uint32_t SymbolFilePDB::CalculateAbilities() {
void SymbolFilePDB::InitializeObject() {
lldb::addr_t obj_load_address = m_obj_file->GetFileOffset();
+ lldbassert(obj_load_address && obj_load_address != LLDB_INVALID_ADDRESS);
m_session_up->setLoadAddress(obj_load_address);
+ if (!m_global_scope_up)
+ m_global_scope_up = m_session_up->getGlobalScope();
+ lldbassert(m_global_scope_up.get());
TypeSystem *type_system =
GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
ClangASTContext *clang_type_system =
llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ lldbassert(clang_type_system);
m_tu_decl_ctx_up = llvm::make_unique<CompilerDeclContext>(
type_system, clang_type_system->GetTranslationUnitDecl());
}
uint32_t SymbolFilePDB::GetNumCompileUnits() {
if (m_cached_compile_unit_count == 0) {
- auto global = m_session_up->getGlobalScope();
- auto compilands = global->findAllChildren<PDBSymbolCompiland>();
+ auto compilands = m_global_scope_up->findAllChildren<PDBSymbolCompiland>();
+ if (!compilands)
+ return 0;
+
+ // The linker could link *.dll (compiland language = LINK), or import
+ // *.dll. For example, a compiland with name `Import:KERNEL32.dll` could be
+ // found as a child of the global scope (PDB executable). Usually, such
+ // compilands contain `thunk` symbols in which we are not interested for
+ // now. However we still count them in the compiland list. If we perform
+ // any compiland related activity, like finding symbols through
+ // llvm::pdb::IPDBSession methods, such compilands will all be searched
+ // automatically no matter whether we include them or not.
m_cached_compile_unit_count = compilands->getChildCount();
// The linker can inject an additional "dummy" compilation unit into the
// PDB. Ignore this special compile unit for our purposes, if it is there.
// It is always the last one.
- auto last_cu = compilands->getChildAtIndex(m_cached_compile_unit_count - 1);
- std::string name = last_cu->getName();
+ auto last_compiland_up =
+ compilands->getChildAtIndex(m_cached_compile_unit_count - 1);
+ lldbassert(last_compiland_up.get());
+ std::string name = last_compiland_up->getName();
if (name == "* Linker *")
--m_cached_compile_unit_count;
}
return m_cached_compile_unit_count;
}
-lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index) {
- auto global = m_session_up->getGlobalScope();
- auto compilands = global->findAllChildren<PDBSymbolCompiland>();
- auto cu = compilands->getChildAtIndex(index);
+void SymbolFilePDB::GetCompileUnitIndex(
+ const llvm::pdb::PDBSymbolCompiland &pdb_compiland, uint32_t &index) {
+ auto results_up = m_global_scope_up->findAllChildren<PDBSymbolCompiland>();
+ if (!results_up)
+ return;
+ auto uid = pdb_compiland.getSymIndexId();
+ for (uint32_t cu_idx = 0; cu_idx < GetNumCompileUnits(); ++cu_idx) {
+ auto compiland_up = results_up->getChildAtIndex(cu_idx);
+ if (!compiland_up)
+ continue;
+ if (compiland_up->getSymIndexId() == uid) {
+ index = cu_idx;
+ return;
+ }
+ }
+ index = UINT32_MAX;
+ return;
+}
+
+std::unique_ptr<llvm::pdb::PDBSymbolCompiland>
+SymbolFilePDB::GetPDBCompilandByUID(uint32_t uid) {
+ return m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(uid);
+}
- uint32_t id = cu->getSymIndexId();
+lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index) {
+ if (index >= GetNumCompileUnits())
+ return CompUnitSP();
- return ParseCompileUnitForSymIndex(id);
+ // Assuming we always retrieve same compilands listed in same order through
+ // `PDBSymbolExe::findAllChildren` method, otherwise using `index` to get a
+ // compile unit makes no sense.
+ auto results = m_global_scope_up->findAllChildren<PDBSymbolCompiland>();
+ if (!results)
+ return CompUnitSP();
+ auto compiland_up = results->getChildAtIndex(index);
+ if (!compiland_up)
+ return CompUnitSP();
+ return ParseCompileUnitForUID(compiland_up->getSymIndexId(), index);
}
lldb::LanguageType
@@ -196,24 +253,71 @@ SymbolFilePDB::ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) {
if (!sc.comp_unit)
return lldb::eLanguageTypeUnknown;
- auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(
- sc.comp_unit->GetID());
- if (!cu)
+ auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID());
+ if (!compiland_up)
return lldb::eLanguageTypeUnknown;
- auto details = cu->findOneChild<PDBSymbolCompilandDetails>();
+ auto details = compiland_up->findOneChild<PDBSymbolCompilandDetails>();
if (!details)
return lldb::eLanguageTypeUnknown;
return TranslateLanguage(details->getLanguage());
}
+lldb_private::Function *SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(
+ const PDBSymbolFunc &pdb_func, const lldb_private::SymbolContext &sc) {
+ lldbassert(sc.comp_unit && sc.module_sp.get());
+
+ auto file_vm_addr = pdb_func.getVirtualAddress();
+ if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0)
+ return nullptr;
+
+ auto func_length = pdb_func.getLength();
+ AddressRange func_range =
+ AddressRange(file_vm_addr, func_length, sc.module_sp->GetSectionList());
+ if (!func_range.GetBaseAddress().IsValid())
+ return nullptr;
+
+ lldb_private::Type *func_type = ResolveTypeUID(pdb_func.getSymIndexId());
+ if (!func_type)
+ return nullptr;
+
+ user_id_t func_type_uid = pdb_func.getSignatureId();
+
+ Mangled mangled = GetMangledForPDBFunc(pdb_func);
+
+ FunctionSP func_sp =
+ std::make_shared<Function>(sc.comp_unit, pdb_func.getSymIndexId(),
+ func_type_uid, mangled, func_type, func_range);
+
+ sc.comp_unit->AddFunction(func_sp);
+ return func_sp.get();
+}
+
size_t SymbolFilePDB::ParseCompileUnitFunctions(
const lldb_private::SymbolContext &sc) {
- // TODO: Implement this
- return size_t();
+ lldbassert(sc.comp_unit);
+ size_t func_added = 0;
+ auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID());
+ if (!compiland_up)
+ return 0;
+ auto results_up = compiland_up->findAllChildren<PDBSymbolFunc>();
+ if (!results_up)
+ return 0;
+ while (auto pdb_func_up = results_up->getNext()) {
+ auto func_sp =
+ sc.comp_unit->FindFunctionByUID(pdb_func_up->getSymIndexId());
+ if (!func_sp) {
+ if (ParseCompileUnitFunctionForPDBFunc(*pdb_func_up, sc))
+ ++func_added;
+ }
+ }
+ return func_added;
}
bool SymbolFilePDB::ParseCompileUnitLineTable(
const lldb_private::SymbolContext &sc) {
+ lldbassert(sc.comp_unit);
+ if (sc.comp_unit->GetLineTable())
+ return true;
return ParseCompileUnitLineTable(sc, 0);
}
@@ -226,26 +330,29 @@ bool SymbolFilePDB::ParseCompileUnitDebugMacros(
bool SymbolFilePDB::ParseCompileUnitSupportFiles(
const lldb_private::SymbolContext &sc,
lldb_private::FileSpecList &support_files) {
- if (!sc.comp_unit)
- return false;
+ lldbassert(sc.comp_unit);
// In theory this is unnecessary work for us, because all of this information
// is easily (and quickly) accessible from DebugInfoPDB, so caching it a
// second time seems like a waste. Unfortunately, there's no good way around
// this short of a moderate refactor since SymbolVendor depends on being able
// to cache this list.
- auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(
- sc.comp_unit->GetID());
- if (!cu)
+ auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID());
+ if (!compiland_up)
return false;
- auto files = m_session_up->getSourceFilesForCompiland(*cu);
+ auto files = m_session_up->getSourceFilesForCompiland(*compiland_up);
if (!files || files->getChildCount() == 0)
return false;
while (auto file = files->getNext()) {
- FileSpec spec(file->getFileName(), false);
- support_files.Append(spec);
+ FileSpec spec(file->getFileName(), false, FileSpec::Style::windows);
+ support_files.AppendIfUnique(spec);
}
+
+ // LLDB uses the DWARF-like file numeration (one based),
+ // the zeroth file is the compile unit itself
+ support_files.Insert(0, *sc.comp_unit);
+
return true;
}
@@ -256,21 +363,178 @@ bool SymbolFilePDB::ParseImportedModules(
return false;
}
+static size_t ParseFunctionBlocksForPDBSymbol(
+ const lldb_private::SymbolContext &sc, uint64_t func_file_vm_addr,
+ const llvm::pdb::PDBSymbol *pdb_symbol, lldb_private::Block *parent_block,
+ bool is_top_parent) {
+ assert(pdb_symbol && parent_block);
+
+ size_t num_added = 0;
+ switch (pdb_symbol->getSymTag()) {
+ case PDB_SymType::Block:
+ case PDB_SymType::Function: {
+ Block *block = nullptr;
+ auto &raw_sym = pdb_symbol->getRawSymbol();
+ if (auto *pdb_func = llvm::dyn_cast<PDBSymbolFunc>(pdb_symbol)) {
+ if (pdb_func->hasNoInlineAttribute())
+ break;
+ if (is_top_parent)
+ block = parent_block;
+ else
+ break;
+ } else if (llvm::dyn_cast<PDBSymbolBlock>(pdb_symbol)) {
+ auto uid = pdb_symbol->getSymIndexId();
+ if (parent_block->FindBlockByID(uid))
+ break;
+ if (raw_sym.getVirtualAddress() < func_file_vm_addr)
+ break;
+
+ auto block_sp = std::make_shared<Block>(pdb_symbol->getSymIndexId());
+ parent_block->AddChild(block_sp);
+ block = block_sp.get();
+ } else
+ llvm_unreachable("Unexpected PDB symbol!");
+
+ block->AddRange(Block::Range(
+ raw_sym.getVirtualAddress() - func_file_vm_addr, raw_sym.getLength()));
+ block->FinalizeRanges();
+ ++num_added;
+
+ auto results_up = pdb_symbol->findAllChildren();
+ if (!results_up)
+ break;
+ while (auto symbol_up = results_up->getNext()) {
+ num_added += ParseFunctionBlocksForPDBSymbol(
+ sc, func_file_vm_addr, symbol_up.get(), block, false);
+ }
+ } break;
+ default:
+ break;
+ }
+ return num_added;
+}
+
size_t
SymbolFilePDB::ParseFunctionBlocks(const lldb_private::SymbolContext &sc) {
- // TODO: Implement this
- return size_t();
+ lldbassert(sc.comp_unit && sc.function);
+ size_t num_added = 0;
+ auto uid = sc.function->GetID();
+ auto pdb_func_up = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(uid);
+ if (!pdb_func_up)
+ return 0;
+ Block &parent_block = sc.function->GetBlock(false);
+ num_added =
+ ParseFunctionBlocksForPDBSymbol(sc, pdb_func_up->getVirtualAddress(),
+ pdb_func_up.get(), &parent_block, true);
+ return num_added;
}
size_t SymbolFilePDB::ParseTypes(const lldb_private::SymbolContext &sc) {
- // TODO: Implement this
- return size_t();
+ lldbassert(sc.module_sp.get());
+ if (!sc.comp_unit)
+ return 0;
+
+ size_t num_added = 0;
+ auto compiland = GetPDBCompilandByUID(sc.comp_unit->GetID());
+ if (!compiland)
+ return 0;
+
+ auto ParseTypesByTagFn = [&num_added, this](const PDBSymbol &raw_sym) {
+ std::unique_ptr<IPDBEnumSymbols> results;
+ PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef,
+ PDB_SymType::UDT};
+ for (auto tag : tags_to_search) {
+ results = raw_sym.findAllChildren(tag);
+ if (!results || results->getChildCount() == 0)
+ continue;
+ while (auto symbol = results->getNext()) {
+ switch (symbol->getSymTag()) {
+ case PDB_SymType::Enum:
+ case PDB_SymType::UDT:
+ case PDB_SymType::Typedef:
+ break;
+ default:
+ continue;
+ }
+
+ // This should cause the type to get cached and stored in the `m_types`
+ // lookup.
+ if (!ResolveTypeUID(symbol->getSymIndexId()))
+ continue;
+
+ ++num_added;
+ }
+ }
+ };
+
+ if (sc.function) {
+ auto pdb_func = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(
+ sc.function->GetID());
+ if (!pdb_func)
+ return 0;
+ ParseTypesByTagFn(*pdb_func);
+ } else {
+ ParseTypesByTagFn(*compiland);
+
+ // Also parse global types particularly coming from this compiland.
+ // Unfortunately, PDB has no compiland information for each global type. We
+ // have to parse them all. But ensure we only do this once.
+ static bool parse_all_global_types = false;
+ if (!parse_all_global_types) {
+ ParseTypesByTagFn(*m_global_scope_up);
+ parse_all_global_types = true;
+ }
+ }
+ return num_added;
}
size_t
SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc) {
- // TODO: Implement this
- return size_t();
+ if (!sc.comp_unit)
+ return 0;
+
+ size_t num_added = 0;
+ if (sc.function) {
+ auto pdb_func = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(
+ sc.function->GetID());
+ if (!pdb_func)
+ return 0;
+
+ num_added += ParseVariables(sc, *pdb_func);
+ sc.function->GetBlock(false).SetDidParseVariables(true, true);
+ } else if (sc.comp_unit) {
+ auto compiland = GetPDBCompilandByUID(sc.comp_unit->GetID());
+ if (!compiland)
+ return 0;
+
+ if (sc.comp_unit->GetVariableList(false))
+ return 0;
+
+ auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();
+ if (results && results->getChildCount()) {
+ while (auto result = results->getNext()) {
+ auto cu_id = result->getCompilandId();
+ // FIXME: We are not able to determine variable's compile unit.
+ if (cu_id == 0)
+ continue;
+
+ if (cu_id == sc.comp_unit->GetID())
+ num_added += ParseVariables(sc, *result);
+ }
+ }
+
+ // FIXME: A `file static` or `global constant` variable appears both in
+ // compiland's children and global scope's children with unexpectedly
+ // different symbol's Id making it ambiguous.
+
+ // FIXME: 'local constant', for example, const char var[] = "abc", declared
+ // in a function scope, can't be found in PDB.
+
+ // Parse variables in this compiland.
+ num_added += ParseVariables(sc, *compiland);
+ }
+
+ return num_added;
}
lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
@@ -294,8 +558,12 @@ lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
return nullptr;
lldb::TypeSP result = pdb->CreateLLDBTypeFromPDBType(*pdb_type);
- if (result.get())
+ if (result) {
m_types.insert(std::make_pair(type_uid, result));
+ auto type_list = GetTypeList();
+ if (type_list)
+ type_list->Insert(result);
+ }
return result.get();
}
@@ -328,12 +596,62 @@ uint32_t
SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,
uint32_t resolve_scope,
lldb_private::SymbolContext &sc) {
- return uint32_t();
+ uint32_t resolved_flags = 0;
+ if (resolve_scope & eSymbolContextCompUnit ||
+ resolve_scope & eSymbolContextVariable ||
+ resolve_scope & eSymbolContextFunction ||
+ resolve_scope & eSymbolContextBlock ||
+ resolve_scope & eSymbolContextLineEntry) {
+ auto cu_sp = GetCompileUnitContainsAddress(so_addr);
+ if (!cu_sp) {
+ if (resolved_flags | eSymbolContextVariable) {
+ // TODO: Resolve variables
+ }
+ return 0;
+ }
+ sc.comp_unit = cu_sp.get();
+ resolved_flags |= eSymbolContextCompUnit;
+ lldbassert(sc.module_sp == cu_sp->GetModule());
+ }
+
+ if (resolve_scope & eSymbolContextFunction) {
+ addr_t file_vm_addr = so_addr.GetFileAddress();
+ auto symbol_up =
+ m_session_up->findSymbolByAddress(file_vm_addr, PDB_SymType::Function);
+ if (symbol_up) {
+ auto *pdb_func = llvm::dyn_cast<PDBSymbolFunc>(symbol_up.get());
+ assert(pdb_func);
+ auto func_uid = pdb_func->getSymIndexId();
+ sc.function = sc.comp_unit->FindFunctionByUID(func_uid).get();
+ if (sc.function == nullptr)
+ sc.function = ParseCompileUnitFunctionForPDBFunc(*pdb_func, sc);
+ if (sc.function) {
+ resolved_flags |= eSymbolContextFunction;
+ if (resolve_scope & eSymbolContextBlock) {
+ Block &block = sc.function->GetBlock(true);
+ sc.block = block.FindBlockByID(sc.function->GetID());
+ if (sc.block)
+ resolved_flags |= eSymbolContextBlock;
+ }
+ }
+ }
+ }
+
+ if (resolve_scope & eSymbolContextLineEntry) {
+ if (auto *line_table = sc.comp_unit->GetLineTable()) {
+ Address addr(so_addr);
+ if (line_table->FindLineEntryByAddress(addr, sc.line_entry))
+ resolved_flags |= eSymbolContextLineEntry;
+ }
+ }
+
+ return resolved_flags;
}
uint32_t SymbolFilePDB::ResolveSymbolContext(
const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines,
uint32_t resolve_scope, lldb_private::SymbolContextList &sc_list) {
+ const size_t old_size = sc_list.GetSize();
if (resolve_scope & lldb::eSymbolContextCompUnit) {
// Locate all compilation units with line numbers referencing the specified
// file. For example, if `file_spec` is <vector>, then this should return
@@ -342,56 +660,498 @@ uint32_t SymbolFilePDB::ResolveSymbolContext(
auto compilands = m_session_up->findCompilandsForSourceFile(
file_spec.GetPath(), PDB_NameSearchFlags::NS_CaseInsensitive);
+ if (!compilands)
+ return 0;
+
// For each one, either find its previously parsed data or parse it afresh
// and add it to the symbol context list.
while (auto compiland = compilands->getNext()) {
- // If we're not checking inlines, then don't add line information for this
- // file unless the FileSpec matches.
+ // If we're not checking inlines, then don't add line information for
+ // this file unless the FileSpec matches. For inline functions, we don't
+ // have to match the FileSpec since they could be defined in headers
+ // other than file specified in FileSpec.
if (!check_inlines) {
- // `getSourceFileName` returns the basename of the original source file
- // used to generate this compiland. It does not return the full path.
- // Currently the only way to get that is to do a basename lookup to get
- // the IPDBSourceFile, but this is ambiguous in the case of two source
- // files with the same name contributing to the same compiland. This is
- // a moderately extreme edge case, so we consider this OK for now,
- // although we need to find a long-term solution.
- std::string source_file = compiland->getSourceFileName();
- auto pdb_file = m_session_up->findOneSourceFile(
- compiland.get(), source_file,
- PDB_NameSearchFlags::NS_CaseInsensitive);
- source_file = pdb_file->getFileName();
- FileSpec this_spec(source_file, false, FileSpec::ePathSyntaxWindows);
- if (!file_spec.FileEquals(this_spec))
+ std::string source_file = compiland->getSourceFileFullPath();
+ if (source_file.empty())
+ continue;
+ FileSpec this_spec(source_file, false, FileSpec::Style::windows);
+ bool need_full_match = !file_spec.GetDirectory().IsEmpty();
+ if (FileSpec::Compare(file_spec, this_spec, need_full_match) != 0)
continue;
}
SymbolContext sc;
- auto cu = ParseCompileUnitForSymIndex(compiland->getSymIndexId());
+ auto cu = ParseCompileUnitForUID(compiland->getSymIndexId());
+ if (!cu)
+ continue;
sc.comp_unit = cu.get();
sc.module_sp = cu->GetModule();
- sc_list.Append(sc);
// If we were asked to resolve line entries, add all entries to the line
// table that match the requested line (or all lines if `line` == 0).
- if (resolve_scope & lldb::eSymbolContextLineEntry)
- ParseCompileUnitLineTable(sc, line);
+ if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock |
+ eSymbolContextLineEntry)) {
+ bool has_line_table = ParseCompileUnitLineTable(sc, line);
+
+ if ((resolve_scope & eSymbolContextLineEntry) && !has_line_table) {
+ // The query asks for line entries, but we can't get them for the
+ // compile unit. This is not normal for `line` = 0. So just assert
+ // it.
+ assert(line && "Couldn't get all line entries!\n");
+
+ // Current compiland does not have the requested line. Search next.
+ continue;
+ }
+
+ if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) {
+ if (!has_line_table)
+ continue;
+
+ auto *line_table = sc.comp_unit->GetLineTable();
+ lldbassert(line_table);
+
+ uint32_t num_line_entries = line_table->GetSize();
+ // Skip the terminal line entry.
+ --num_line_entries;
+
+ // If `line `!= 0, see if we can resolve function for each line entry
+ // in the line table.
+ for (uint32_t line_idx = 0; line && line_idx < num_line_entries;
+ ++line_idx) {
+ if (!line_table->GetLineEntryAtIndex(line_idx, sc.line_entry))
+ continue;
+
+ auto file_vm_addr =
+ sc.line_entry.range.GetBaseAddress().GetFileAddress();
+ if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0)
+ continue;
+
+ auto symbol_up = m_session_up->findSymbolByAddress(
+ file_vm_addr, PDB_SymType::Function);
+ if (symbol_up) {
+ auto func_uid = symbol_up->getSymIndexId();
+ sc.function = sc.comp_unit->FindFunctionByUID(func_uid).get();
+ if (sc.function == nullptr) {
+ auto pdb_func = llvm::dyn_cast<PDBSymbolFunc>(symbol_up.get());
+ assert(pdb_func);
+ sc.function = ParseCompileUnitFunctionForPDBFunc(*pdb_func, sc);
+ }
+ if (sc.function && (resolve_scope & eSymbolContextBlock)) {
+ Block &block = sc.function->GetBlock(true);
+ sc.block = block.FindBlockByID(sc.function->GetID());
+ }
+ }
+ sc_list.Append(sc);
+ }
+ } else if (has_line_table) {
+ // We can parse line table for the compile unit. But no query to
+ // resolve function or block. We append `sc` to the list anyway.
+ sc_list.Append(sc);
+ }
+ } else {
+ // No query for line entry, function or block. But we have a valid
+ // compile unit, append `sc` to the list.
+ sc_list.Append(sc);
+ }
+ }
+ }
+ return sc_list.GetSize() - old_size;
+}
+
+std::string SymbolFilePDB::GetMangledForPDBData(const PDBSymbolData &pdb_data) {
+ std::string decorated_name;
+ auto vm_addr = pdb_data.getVirtualAddress();
+ if (vm_addr != LLDB_INVALID_ADDRESS && vm_addr) {
+ auto result_up =
+ m_global_scope_up->findAllChildren(PDB_SymType::PublicSymbol);
+ if (result_up) {
+ while (auto symbol_up = result_up->getNext()) {
+ if (symbol_up->getRawSymbol().getVirtualAddress() == vm_addr) {
+ decorated_name = symbol_up->getRawSymbol().getName();
+ break;
+ }
+ }
+ }
+ }
+ if (!decorated_name.empty())
+ return decorated_name;
+
+ return std::string();
+}
+
+VariableSP SymbolFilePDB::ParseVariableForPDBData(
+ const lldb_private::SymbolContext &sc,
+ const llvm::pdb::PDBSymbolData &pdb_data) {
+ VariableSP var_sp;
+ uint32_t var_uid = pdb_data.getSymIndexId();
+ auto result = m_variables.find(var_uid);
+ if (result != m_variables.end())
+ return result->second;
+
+ ValueType scope = eValueTypeInvalid;
+ bool is_static_member = false;
+ bool is_external = false;
+ bool is_artificial = false;
+
+ switch (pdb_data.getDataKind()) {
+ case PDB_DataKind::Global:
+ scope = eValueTypeVariableGlobal;
+ is_external = true;
+ break;
+ case PDB_DataKind::Local:
+ scope = eValueTypeVariableLocal;
+ break;
+ case PDB_DataKind::FileStatic:
+ scope = eValueTypeVariableStatic;
+ break;
+ case PDB_DataKind::StaticMember:
+ is_static_member = true;
+ scope = eValueTypeVariableStatic;
+ break;
+ case PDB_DataKind::Member:
+ scope = eValueTypeVariableStatic;
+ break;
+ case PDB_DataKind::Param:
+ scope = eValueTypeVariableArgument;
+ break;
+ case PDB_DataKind::Constant:
+ scope = eValueTypeConstResult;
+ break;
+ default:
+ break;
+ }
+
+ switch (pdb_data.getLocationType()) {
+ case PDB_LocType::TLS:
+ scope = eValueTypeVariableThreadLocal;
+ break;
+ case PDB_LocType::RegRel: {
+ // It is a `this` pointer.
+ if (pdb_data.getDataKind() == PDB_DataKind::ObjectPtr) {
+ scope = eValueTypeVariableArgument;
+ is_artificial = true;
+ }
+ } break;
+ default:
+ break;
+ }
+
+ Declaration decl;
+ if (!is_artificial && !pdb_data.isCompilerGenerated()) {
+ if (auto lines = pdb_data.getLineNumbers()) {
+ if (auto first_line = lines->getNext()) {
+ uint32_t src_file_id = first_line->getSourceFileId();
+ auto src_file = m_session_up->getSourceFileById(src_file_id);
+ if (src_file) {
+ FileSpec spec(src_file->getFileName(), /*resolve_path*/ false);
+ decl.SetFile(spec);
+ decl.SetColumn(first_line->getColumnNumber());
+ decl.SetLine(first_line->getLineNumber());
+ }
+ }
+ }
+ }
+
+ Variable::RangeList ranges;
+ SymbolContextScope *context_scope = sc.comp_unit;
+ if (scope == eValueTypeVariableLocal) {
+ if (sc.function) {
+ context_scope = sc.function->GetBlock(true).FindBlockByID(
+ pdb_data.getClassParentId());
+ if (context_scope == nullptr)
+ context_scope = sc.function;
+ }
+ }
+
+ SymbolFileTypeSP type_sp =
+ std::make_shared<SymbolFileType>(*this, pdb_data.getTypeId());
+
+ auto var_name = pdb_data.getName();
+ auto mangled = GetMangledForPDBData(pdb_data);
+ auto mangled_cstr = mangled.empty() ? nullptr : mangled.c_str();
+
+ bool is_constant;
+ DWARFExpression location = ConvertPDBLocationToDWARFExpression(
+ GetObjectFile()->GetModule(), pdb_data, is_constant);
+
+ var_sp = std::make_shared<Variable>(
+ var_uid, var_name.c_str(), mangled_cstr, type_sp, scope, context_scope,
+ ranges, &decl, location, is_external, is_artificial, is_static_member);
+ var_sp->SetLocationIsConstantValueData(is_constant);
+
+ m_variables.insert(std::make_pair(var_uid, var_sp));
+ return var_sp;
+}
+
+size_t
+SymbolFilePDB::ParseVariables(const lldb_private::SymbolContext &sc,
+ const llvm::pdb::PDBSymbol &pdb_symbol,
+ lldb_private::VariableList *variable_list) {
+ size_t num_added = 0;
+
+ if (auto pdb_data = llvm::dyn_cast<PDBSymbolData>(&pdb_symbol)) {
+ VariableListSP local_variable_list_sp;
+
+ auto result = m_variables.find(pdb_data->getSymIndexId());
+ if (result != m_variables.end()) {
+ if (variable_list)
+ variable_list->AddVariableIfUnique(result->second);
+ } else {
+ // Prepare right VariableList for this variable.
+ if (auto lexical_parent = pdb_data->getLexicalParent()) {
+ switch (lexical_parent->getSymTag()) {
+ case PDB_SymType::Exe:
+ assert(sc.comp_unit);
+ LLVM_FALLTHROUGH;
+ case PDB_SymType::Compiland: {
+ if (sc.comp_unit) {
+ local_variable_list_sp = sc.comp_unit->GetVariableList(false);
+ if (!local_variable_list_sp) {
+ local_variable_list_sp = std::make_shared<VariableList>();
+ sc.comp_unit->SetVariableList(local_variable_list_sp);
+ }
+ }
+ } break;
+ case PDB_SymType::Block:
+ case PDB_SymType::Function: {
+ if (sc.function) {
+ Block *block = sc.function->GetBlock(true).FindBlockByID(
+ lexical_parent->getSymIndexId());
+ if (block) {
+ local_variable_list_sp = block->GetBlockVariableList(false);
+ if (!local_variable_list_sp) {
+ local_variable_list_sp = std::make_shared<VariableList>();
+ block->SetVariableList(local_variable_list_sp);
+ }
+ }
+ }
+ } break;
+ default:
+ break;
+ }
+ }
+
+ if (local_variable_list_sp) {
+ if (auto var_sp = ParseVariableForPDBData(sc, *pdb_data)) {
+ local_variable_list_sp->AddVariableIfUnique(var_sp);
+ if (variable_list)
+ variable_list->AddVariableIfUnique(var_sp);
+ ++num_added;
+ }
+ }
}
}
- return sc_list.GetSize();
+
+ if (auto results = pdb_symbol.findAllChildren()) {
+ while (auto result = results->getNext())
+ num_added += ParseVariables(sc, *result, variable_list);
+ }
+
+ return num_added;
}
uint32_t SymbolFilePDB::FindGlobalVariables(
const lldb_private::ConstString &name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches, lldb_private::VariableList &variables) {
- return uint32_t();
+ if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
+ return 0;
+ if (name.IsEmpty())
+ return 0;
+
+ auto results =
+ m_global_scope_up->findChildren(PDB_SymType::Data, name.GetStringRef(),
+ PDB_NameSearchFlags::NS_CaseSensitive);
+ if (!results)
+ return 0;
+
+ uint32_t matches = 0;
+ size_t old_size = variables.GetSize();
+ while (auto result = results->getNext()) {
+ auto pdb_data = llvm::dyn_cast<PDBSymbolData>(result.get());
+ if (max_matches > 0 && matches >= max_matches)
+ break;
+
+ SymbolContext sc;
+ sc.module_sp = m_obj_file->GetModule();
+ lldbassert(sc.module_sp.get());
+
+ sc.comp_unit = ParseCompileUnitForUID(pdb_data->getCompilandId()).get();
+ // FIXME: We are not able to determine the compile unit.
+ if (sc.comp_unit == nullptr)
+ continue;
+
+ ParseVariables(sc, *pdb_data, &variables);
+ matches = variables.GetSize() - old_size;
+ }
+
+ return matches;
}
uint32_t
SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression &regex,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
lldb_private::VariableList &variables) {
- return uint32_t();
+ if (!regex.IsValid())
+ return 0;
+ auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();
+ if (!results)
+ return 0;
+
+ uint32_t matches = 0;
+ size_t old_size = variables.GetSize();
+ while (auto pdb_data = results->getNext()) {
+ if (max_matches > 0 && matches >= max_matches)
+ break;
+
+ auto var_name = pdb_data->getName();
+ if (var_name.empty())
+ continue;
+ if (!regex.Execute(var_name))
+ continue;
+ SymbolContext sc;
+ sc.module_sp = m_obj_file->GetModule();
+ lldbassert(sc.module_sp.get());
+
+ sc.comp_unit = ParseCompileUnitForUID(pdb_data->getCompilandId()).get();
+ // FIXME: We are not able to determine the compile unit.
+ if (sc.comp_unit == nullptr)
+ continue;
+
+ ParseVariables(sc, *pdb_data, &variables);
+ matches = variables.GetSize() - old_size;
+ }
+
+ return matches;
+}
+
+bool SymbolFilePDB::ResolveFunction(const llvm::pdb::PDBSymbolFunc &pdb_func,
+ bool include_inlines,
+ lldb_private::SymbolContextList &sc_list) {
+ lldb_private::SymbolContext sc;
+ sc.comp_unit = ParseCompileUnitForUID(pdb_func.getCompilandId()).get();
+ if (!sc.comp_unit)
+ return false;
+ sc.module_sp = sc.comp_unit->GetModule();
+ sc.function = ParseCompileUnitFunctionForPDBFunc(pdb_func, sc);
+ if (!sc.function)
+ return false;
+
+ sc_list.Append(sc);
+ return true;
+}
+
+bool SymbolFilePDB::ResolveFunction(uint32_t uid, bool include_inlines,
+ lldb_private::SymbolContextList &sc_list) {
+ auto pdb_func_up = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(uid);
+ if (!pdb_func_up && !(include_inlines && pdb_func_up->hasInlineAttribute()))
+ return false;
+ return ResolveFunction(*pdb_func_up, include_inlines, sc_list);
+}
+
+void SymbolFilePDB::CacheFunctionNames() {
+ if (!m_func_full_names.IsEmpty())
+ return;
+
+ std::map<uint64_t, uint32_t> addr_ids;
+
+ if (auto results_up = m_global_scope_up->findAllChildren<PDBSymbolFunc>()) {
+ while (auto pdb_func_up = results_up->getNext()) {
+ if (pdb_func_up->isCompilerGenerated())
+ continue;
+
+ auto name = pdb_func_up->getName();
+ auto demangled_name = pdb_func_up->getUndecoratedName();
+ if (name.empty() && demangled_name.empty())
+ continue;
+
+ auto uid = pdb_func_up->getSymIndexId();
+ if (!demangled_name.empty() && pdb_func_up->getVirtualAddress())
+ addr_ids.insert(std::make_pair(pdb_func_up->getVirtualAddress(), uid));
+
+ if (auto parent = pdb_func_up->getClassParent()) {
+
+ // PDB have symbols for class/struct methods or static methods in Enum
+ // Class. We won't bother to check if the parent is UDT or Enum here.
+ m_func_method_names.Append(ConstString(name), uid);
+
+ ConstString cstr_name(name);
+
+ // To search a method name, like NS::Class:MemberFunc, LLDB searches
+ // its base name, i.e. MemberFunc by default. Since PDBSymbolFunc does
+ // not have inforamtion of this, we extract base names and cache them
+ // by our own effort.
+ llvm::StringRef basename;
+ CPlusPlusLanguage::MethodName cpp_method(cstr_name);
+ if (cpp_method.IsValid()) {
+ llvm::StringRef context;
+ basename = cpp_method.GetBasename();
+ if (basename.empty())
+ CPlusPlusLanguage::ExtractContextAndIdentifier(name.c_str(),
+ context, basename);
+ }
+
+ if (!basename.empty())
+ m_func_base_names.Append(ConstString(basename), uid);
+ else {
+ m_func_base_names.Append(ConstString(name), uid);
+ }
+
+ if (!demangled_name.empty())
+ m_func_full_names.Append(ConstString(demangled_name), uid);
+
+ } else {
+ // Handle not-method symbols.
+
+ // The function name might contain namespace, or its lexical scope. It
+ // is not safe to get its base name by applying same scheme as we deal
+ // with the method names.
+ // FIXME: Remove namespace if function is static in a scope.
+ m_func_base_names.Append(ConstString(name), uid);
+
+ if (name == "main") {
+ m_func_full_names.Append(ConstString(name), uid);
+
+ if (!demangled_name.empty() && name != demangled_name) {
+ m_func_full_names.Append(ConstString(demangled_name), uid);
+ m_func_base_names.Append(ConstString(demangled_name), uid);
+ }
+ } else if (!demangled_name.empty()) {
+ m_func_full_names.Append(ConstString(demangled_name), uid);
+ } else {
+ m_func_full_names.Append(ConstString(name), uid);
+ }
+ }
+ }
+ }
+
+ if (auto results_up =
+ m_global_scope_up->findAllChildren<PDBSymbolPublicSymbol>()) {
+ while (auto pub_sym_up = results_up->getNext()) {
+ if (!pub_sym_up->isFunction())
+ continue;
+ auto name = pub_sym_up->getName();
+ if (name.empty())
+ continue;
+
+ if (CPlusPlusLanguage::IsCPPMangledName(name.c_str())) {
+ auto vm_addr = pub_sym_up->getVirtualAddress();
+
+ // PDB public symbol has mangled name for its associated function.
+ if (vm_addr && addr_ids.find(vm_addr) != addr_ids.end()) {
+ // Cache mangled name.
+ m_func_full_names.Append(ConstString(name), addr_ids[vm_addr]);
+ }
+ }
+ }
+ }
+ // Sort them before value searching is working properly
+ m_func_full_names.Sort();
+ m_func_full_names.SizeToFit();
+ m_func_method_names.Sort();
+ m_func_method_names.SizeToFit();
+ m_func_base_names.Sort();
+ m_func_base_names.SizeToFit();
}
uint32_t SymbolFilePDB::FindFunctions(
@@ -399,14 +1159,77 @@ uint32_t SymbolFilePDB::FindFunctions(
const lldb_private::CompilerDeclContext *parent_decl_ctx,
uint32_t name_type_mask, bool include_inlines, bool append,
lldb_private::SymbolContextList &sc_list) {
- return uint32_t();
+ if (!append)
+ sc_list.Clear();
+ lldbassert((name_type_mask & eFunctionNameTypeAuto) == 0);
+
+ if (name_type_mask == eFunctionNameTypeNone)
+ return 0;
+ if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
+ return 0;
+ if (name.IsEmpty())
+ return 0;
+
+ auto old_size = sc_list.GetSize();
+ if (name_type_mask & eFunctionNameTypeFull ||
+ name_type_mask & eFunctionNameTypeBase ||
+ name_type_mask & eFunctionNameTypeMethod) {
+ CacheFunctionNames();
+
+ std::set<uint32_t> resolved_ids;
+ auto ResolveFn = [include_inlines, &name, &sc_list, &resolved_ids,
+ this](UniqueCStringMap<uint32_t> &Names) {
+ std::vector<uint32_t> ids;
+ if (Names.GetValues(name, ids)) {
+ for (auto id : ids) {
+ if (resolved_ids.find(id) == resolved_ids.end()) {
+ if (ResolveFunction(id, include_inlines, sc_list))
+ resolved_ids.insert(id);
+ }
+ }
+ }
+ };
+ if (name_type_mask & eFunctionNameTypeFull) {
+ ResolveFn(m_func_full_names);
+ }
+ if (name_type_mask & eFunctionNameTypeBase) {
+ ResolveFn(m_func_base_names);
+ }
+ if (name_type_mask & eFunctionNameTypeMethod) {
+ ResolveFn(m_func_method_names);
+ }
+ }
+ return sc_list.GetSize() - old_size;
}
uint32_t
SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression &regex,
bool include_inlines, bool append,
lldb_private::SymbolContextList &sc_list) {
- return uint32_t();
+ if (!append)
+ sc_list.Clear();
+ if (!regex.IsValid())
+ return 0;
+
+ auto old_size = sc_list.GetSize();
+ CacheFunctionNames();
+
+ std::set<uint32_t> resolved_ids;
+ auto ResolveFn = [&regex, include_inlines, &sc_list, &resolved_ids,
+ this](UniqueCStringMap<uint32_t> &Names) {
+ std::vector<uint32_t> ids;
+ if (Names.GetValues(regex, ids)) {
+ for (auto id : ids) {
+ if (resolved_ids.find(id) == resolved_ids.end())
+ if (ResolveFunction(id, include_inlines, sc_list))
+ resolved_ids.insert(id);
+ }
+ }
+ };
+ ResolveFn(m_func_full_names);
+ ResolveFn(m_func_base_names);
+
+ return sc_list.GetSize() - old_size;
}
void SymbolFilePDB::GetMangledNamesForFunction(
@@ -424,6 +1247,8 @@ uint32_t SymbolFilePDB::FindTypes(
types.Clear();
if (!name)
return 0;
+ if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
+ return 0;
searched_symbol_files.clear();
searched_symbol_files.insert(this);
@@ -432,14 +1257,13 @@ uint32_t SymbolFilePDB::FindTypes(
// There is an assumption 'name' is not a regex
FindTypesByName(name_str, max_matches, types);
-
+
return types.GetSize();
}
-void
-SymbolFilePDB::FindTypesByRegex(const lldb_private::RegularExpression &regex,
- uint32_t max_matches,
- lldb_private::TypeMap &types) {
+void SymbolFilePDB::FindTypesByRegex(
+ const lldb_private::RegularExpression &regex, uint32_t max_matches,
+ lldb_private::TypeMap &types) {
// When searching by regex, we need to go out of our way to limit the search
// space as much as possible since this searches EVERYTHING in the PDB,
// manually doing regex comparisons. PDB library isn't optimized for regex
@@ -448,13 +1272,15 @@ SymbolFilePDB::FindTypesByRegex(const lldb_private::RegularExpression &regex,
// and do a regex comparison against each of them.
PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef,
PDB_SymType::UDT};
- auto global = m_session_up->getGlobalScope();
std::unique_ptr<IPDBEnumSymbols> results;
uint32_t matches = 0;
for (auto tag : tags_to_search) {
- results = global->findAllChildren(tag);
+ results = m_global_scope_up->findAllChildren(tag);
+ if (!results)
+ continue;
+
while (auto result = results->getNext()) {
if (max_matches > 0 && matches >= max_matches)
break;
@@ -493,10 +1319,13 @@ SymbolFilePDB::FindTypesByRegex(const lldb_private::RegularExpression &regex,
void SymbolFilePDB::FindTypesByName(const std::string &name,
uint32_t max_matches,
lldb_private::TypeMap &types) {
- auto global = m_session_up->getGlobalScope();
std::unique_ptr<IPDBEnumSymbols> results;
- results = global->findChildren(PDB_SymType::None, name,
- PDB_NameSearchFlags::NS_Default);
+ if (name.empty())
+ return;
+ results = m_global_scope_up->findChildren(PDB_SymType::None, name,
+ PDB_NameSearchFlags::NS_Default);
+ if (!results)
+ return;
uint32_t matches = 0;
@@ -509,8 +1338,8 @@ void SymbolFilePDB::FindTypesByName(const std::string &name,
case PDB_SymType::Typedef:
break;
default:
- // We're looking only for types that have names. Skip symbols, as well as
- // unnamed types such as arrays, pointers, etc.
+ // We're looking only for types that have names. Skip symbols, as well
+ // as unnamed types such as arrays, pointers, etc.
continue;
}
@@ -533,12 +1362,87 @@ size_t SymbolFilePDB::FindTypes(
return 0;
}
-lldb_private::TypeList *SymbolFilePDB::GetTypeList() { return nullptr; }
+lldb_private::TypeList *SymbolFilePDB::GetTypeList() {
+ return m_obj_file->GetModule()->GetTypeList();
+}
+
+void SymbolFilePDB::GetTypesForPDBSymbol(const llvm::pdb::PDBSymbol &pdb_symbol,
+ uint32_t type_mask,
+ TypeCollection &type_collection) {
+ bool can_parse = false;
+ switch (pdb_symbol.getSymTag()) {
+ case PDB_SymType::ArrayType:
+ can_parse = ((type_mask & eTypeClassArray) != 0);
+ break;
+ case PDB_SymType::BuiltinType:
+ can_parse = ((type_mask & eTypeClassBuiltin) != 0);
+ break;
+ case PDB_SymType::Enum:
+ can_parse = ((type_mask & eTypeClassEnumeration) != 0);
+ break;
+ case PDB_SymType::Function:
+ case PDB_SymType::FunctionSig:
+ can_parse = ((type_mask & eTypeClassFunction) != 0);
+ break;
+ case PDB_SymType::PointerType:
+ can_parse = ((type_mask & (eTypeClassPointer | eTypeClassBlockPointer |
+ eTypeClassMemberPointer)) != 0);
+ break;
+ case PDB_SymType::Typedef:
+ can_parse = ((type_mask & eTypeClassTypedef) != 0);
+ break;
+ case PDB_SymType::UDT: {
+ auto *udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&pdb_symbol);
+ assert(udt);
+ can_parse = (udt->getUdtKind() != PDB_UdtType::Interface &&
+ ((type_mask & (eTypeClassClass | eTypeClassStruct |
+ eTypeClassUnion)) != 0));
+ } break;
+ default:
+ break;
+ }
+
+ if (can_parse) {
+ if (auto *type = ResolveTypeUID(pdb_symbol.getSymIndexId())) {
+ auto result =
+ std::find(type_collection.begin(), type_collection.end(), type);
+ if (result == type_collection.end())
+ type_collection.push_back(type);
+ }
+ }
+
+ auto results_up = pdb_symbol.findAllChildren();
+ while (auto symbol_up = results_up->getNext())
+ GetTypesForPDBSymbol(*symbol_up, type_mask, type_collection);
+}
size_t SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
uint32_t type_mask,
lldb_private::TypeList &type_list) {
- return size_t();
+ TypeCollection type_collection;
+ uint32_t old_size = type_list.GetSize();
+ CompileUnit *cu =
+ sc_scope ? sc_scope->CalculateSymbolContextCompileUnit() : nullptr;
+ if (cu) {
+ auto compiland_up = GetPDBCompilandByUID(cu->GetID());
+ if (!compiland_up)
+ return 0;
+ GetTypesForPDBSymbol(*compiland_up, type_mask, type_collection);
+ } else {
+ for (uint32_t cu_idx = 0; cu_idx < GetNumCompileUnits(); ++cu_idx) {
+ auto cu_sp = ParseCompileUnitAtIndex(cu_idx);
+ if (cu_sp) {
+ if (auto compiland_up = GetPDBCompilandByUID(cu_sp->GetID()))
+ GetTypesForPDBSymbol(*compiland_up, type_mask, type_collection);
+ }
+ }
+ }
+
+ for (auto type : type_collection) {
+ type->GetForwardCompilerType();
+ type_list.Insert(type->shared_from_this());
+ }
+ return type_list.GetSize() - old_size;
}
lldb_private::TypeSystem *
@@ -570,65 +1474,78 @@ const IPDBSession &SymbolFilePDB::GetPDBSession() const {
return *m_session_up;
}
-lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitForSymIndex(uint32_t id) {
+lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitForUID(uint32_t id,
+ uint32_t index) {
auto found_cu = m_comp_units.find(id);
if (found_cu != m_comp_units.end())
return found_cu->second;
- auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(id);
-
- // `getSourceFileName` returns the basename of the original source file used
- // to generate this compiland. It does not return the full path. Currently
- // the only way to get that is to do a basename lookup to get the
- // IPDBSourceFile, but this is ambiguous in the case of two source files with
- // the same name contributing to the same compiland. This is a moderately
- // extreme edge case, so we consider this OK for now, although we need to find
- // a long-term solution.
- auto file =
- m_session_up->findOneSourceFile(cu.get(), cu->getSourceFileName(),
- PDB_NameSearchFlags::NS_CaseInsensitive);
- std::string path = file->getFileName();
+ auto compiland_up = GetPDBCompilandByUID(id);
+ if (!compiland_up)
+ return CompUnitSP();
lldb::LanguageType lang;
- auto details = cu->findOneChild<PDBSymbolCompilandDetails>();
+ auto details = compiland_up->findOneChild<PDBSymbolCompilandDetails>();
if (!details)
lang = lldb::eLanguageTypeC_plus_plus;
else
lang = TranslateLanguage(details->getLanguage());
+ if (lang == lldb::LanguageType::eLanguageTypeUnknown)
+ return CompUnitSP();
+
+ std::string path = compiland_up->getSourceFileFullPath();
+ if (path.empty())
+ return CompUnitSP();
+
// Don't support optimized code for now, DebugInfoPDB does not return this
// information.
LazyBool optimized = eLazyBoolNo;
- auto result = std::make_shared<CompileUnit>(
- m_obj_file->GetModule(), nullptr, path.c_str(), id, lang, optimized);
- m_comp_units.insert(std::make_pair(id, result));
- return result;
+ auto cu_sp = std::make_shared<CompileUnit>(m_obj_file->GetModule(), nullptr,
+ path.c_str(), id, lang, optimized);
+
+ if (!cu_sp)
+ return CompUnitSP();
+
+ m_comp_units.insert(std::make_pair(id, cu_sp));
+ if (index == UINT32_MAX)
+ GetCompileUnitIndex(*compiland_up, index);
+ lldbassert(index != UINT32_MAX);
+ m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(index,
+ cu_sp);
+ return cu_sp;
}
bool SymbolFilePDB::ParseCompileUnitLineTable(
const lldb_private::SymbolContext &sc, uint32_t match_line) {
- auto global = m_session_up->getGlobalScope();
- auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(
- sc.comp_unit->GetID());
+ lldbassert(sc.comp_unit);
+
+ auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID());
+ if (!compiland_up)
+ return false;
// LineEntry needs the *index* of the file into the list of support files
// returned by ParseCompileUnitSupportFiles. But the underlying SDK gives us
- // a globally unique idenfitifier in the namespace of the PDB. So, we have to
- // do a mapping so that we can hand out indices.
+ // a globally unique idenfitifier in the namespace of the PDB. So, we have
+ // to do a mapping so that we can hand out indices.
llvm::DenseMap<uint32_t, uint32_t> index_map;
- BuildSupportFileIdToSupportFileIndexMap(*cu, index_map);
+ BuildSupportFileIdToSupportFileIndexMap(*compiland_up, index_map);
auto line_table = llvm::make_unique<LineTable>(sc.comp_unit);
- // Find contributions to `cu` from all source and header files.
+ // Find contributions to `compiland` from all source and header files.
std::string path = sc.comp_unit->GetPath();
- auto files = m_session_up->getSourceFilesForCompiland(*cu);
+ auto files = m_session_up->getSourceFilesForCompiland(*compiland_up);
+ if (!files)
+ return false;
- // For each source and header file, create a LineSequence for contributions to
- // the cu from that file, and add the sequence.
+ // For each source and header file, create a LineSequence for contributions
+ // to the compiland from that file, and add the sequence.
while (auto file = files->getNext()) {
std::unique_ptr<LineSequence> sequence(
line_table->CreateLineSequenceContainer());
- auto lines = m_session_up->findLineNumbers(*cu, *file);
+ auto lines = m_session_up->findLineNumbers(*compiland_up, *file);
+ if (!lines)
+ continue;
int entry_count = lines->getChildCount();
uint64_t prev_addr;
@@ -646,8 +1563,8 @@ bool SymbolFilePDB::ParseCompileUnitLineTable(
uint32_t col = line->getColumnNumber();
uint32_t source_idx = index_map[source_id];
- // There was a gap between the current entry and the previous entry if the
- // addresses don't perfectly line up.
+ // There was a gap between the current entry and the previous entry if
+ // the addresses don't perfectly line up.
bool is_gap = (i > 0) && (prev_addr + prev_length < addr);
// Before inserting the current entry, insert a terminal entry at the end
@@ -657,6 +1574,9 @@ bool SymbolFilePDB::ParseCompileUnitLineTable(
line_table->AppendLineEntryToSequence(
sequence.get(), prev_addr + prev_length, prev_line, 0,
prev_source_idx, false, false, false, false, true);
+
+ line_table->InsertSequence(sequence.release());
+ sequence.reset(line_table->CreateLineSequenceContainer());
}
if (ShouldAddLine(match_line, lno, length)) {
@@ -667,10 +1587,12 @@ bool SymbolFilePDB::ParseCompileUnitLineTable(
m_session_up->findSymbolByAddress(addr, PDB_SymType::Function);
if (func) {
auto prologue = func->findOneChild<PDBSymbolFuncDebugStart>();
- is_prologue = (addr == prologue->getVirtualAddress());
+ if (prologue)
+ is_prologue = (addr == prologue->getVirtualAddress());
auto epilogue = func->findOneChild<PDBSymbolFuncDebugEnd>();
- is_epilogue = (addr == epilogue->getVirtualAddress());
+ if (epilogue)
+ is_epilogue = (addr == epilogue->getVirtualAddress());
}
line_table->AppendLineEntryToSequence(sequence.get(), addr, lno, col,
@@ -694,23 +1616,134 @@ bool SymbolFilePDB::ParseCompileUnitLineTable(
line_table->InsertSequence(sequence.release());
}
- sc.comp_unit->SetLineTable(line_table.release());
- return true;
+ if (line_table->GetSize()) {
+ sc.comp_unit->SetLineTable(line_table.release());
+ return true;
+ }
+ return false;
}
void SymbolFilePDB::BuildSupportFileIdToSupportFileIndexMap(
- const PDBSymbolCompiland &cu,
+ const PDBSymbolCompiland &compiland,
llvm::DenseMap<uint32_t, uint32_t> &index_map) const {
- // This is a hack, but we need to convert the source id into an index into the
- // support files array. We don't want to do path comparisons to avoid
+ // This is a hack, but we need to convert the source id into an index into
+ // the support files array. We don't want to do path comparisons to avoid
// basename / full path issues that may or may not even be a problem, so we
// use the globally unique source file identifiers. Ideally we could use the
// global identifiers everywhere, but LineEntry currently assumes indices.
- auto source_files = m_session_up->getSourceFilesForCompiland(cu);
- int index = 0;
+ auto source_files = m_session_up->getSourceFilesForCompiland(compiland);
+ if (!source_files)
+ return;
+
+ // LLDB uses the DWARF-like file numeration (one based)
+ int index = 1;
while (auto file = source_files->getNext()) {
uint32_t source_id = file->getUniqueId();
index_map[source_id] = index++;
}
}
+
+lldb::CompUnitSP SymbolFilePDB::GetCompileUnitContainsAddress(
+ const lldb_private::Address &so_addr) {
+ lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
+ if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0)
+ return nullptr;
+
+ // If it is a PDB function's vm addr, this is the first sure bet.
+ if (auto lines =
+ m_session_up->findLineNumbersByAddress(file_vm_addr, /*Length=*/1)) {
+ if (auto first_line = lines->getNext())
+ return ParseCompileUnitForUID(first_line->getCompilandId());
+ }
+
+ // Otherwise we resort to section contributions.
+ if (auto sec_contribs = m_session_up->getSectionContribs()) {
+ while (auto section = sec_contribs->getNext()) {
+ auto va = section->getVirtualAddress();
+ if (file_vm_addr >= va && file_vm_addr < va + section->getLength())
+ return ParseCompileUnitForUID(section->getCompilandId());
+ }
+ }
+ return nullptr;
+}
+
+Mangled
+SymbolFilePDB::GetMangledForPDBFunc(const llvm::pdb::PDBSymbolFunc &pdb_func) {
+ Mangled mangled;
+ auto func_name = pdb_func.getName();
+ auto func_undecorated_name = pdb_func.getUndecoratedName();
+ std::string func_decorated_name;
+
+ // Seek from public symbols for non-static function's decorated name if any.
+ // For static functions, they don't have undecorated names and aren't exposed
+ // in Public Symbols either.
+ if (!func_undecorated_name.empty()) {
+ auto result_up = m_global_scope_up->findChildren(
+ PDB_SymType::PublicSymbol, func_undecorated_name,
+ PDB_NameSearchFlags::NS_UndecoratedName);
+ if (result_up) {
+ while (auto symbol_up = result_up->getNext()) {
+ // For a public symbol, it is unique.
+ lldbassert(result_up->getChildCount() == 1);
+ if (auto *pdb_public_sym =
+ llvm::dyn_cast_or_null<PDBSymbolPublicSymbol>(
+ symbol_up.get())) {
+ if (pdb_public_sym->isFunction()) {
+ func_decorated_name = pdb_public_sym->getName();
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (!func_decorated_name.empty()) {
+ mangled.SetMangledName(ConstString(func_decorated_name));
+
+ // For MSVC, format of C funciton's decorated name depends on calling
+ // conventon. Unfortunately none of the format is recognized by current
+ // LLDB. For example, `_purecall` is a __cdecl C function. From PDB,
+ // `__purecall` is retrieved as both its decorated and undecorated name
+ // (using PDBSymbolFunc::getUndecoratedName method). However `__purecall`
+ // string is not treated as mangled in LLDB (neither `?` nor `_Z` prefix).
+ // Mangled::GetDemangledName method will fail internally and caches an
+ // empty string as its undecorated name. So we will face a contradition
+ // here for the same symbol:
+ // non-empty undecorated name from PDB
+ // empty undecorated name from LLDB
+ if (!func_undecorated_name.empty() &&
+ mangled.GetDemangledName(mangled.GuessLanguage()).IsEmpty())
+ mangled.SetDemangledName(ConstString(func_undecorated_name));
+
+ // LLDB uses several flags to control how a C++ decorated name is
+ // undecorated for MSVC. See `safeUndecorateName` in Class Mangled. So the
+ // yielded name could be different from what we retrieve from
+ // PDB source unless we also apply same flags in getting undecorated
+ // name through PDBSymbolFunc::getUndecoratedNameEx method.
+ if (!func_undecorated_name.empty() &&
+ mangled.GetDemangledName(mangled.GuessLanguage()) !=
+ ConstString(func_undecorated_name))
+ mangled.SetDemangledName(ConstString(func_undecorated_name));
+ } else if (!func_undecorated_name.empty()) {
+ mangled.SetDemangledName(ConstString(func_undecorated_name));
+ } else if (!func_name.empty())
+ mangled.SetValue(ConstString(func_name), false);
+
+ return mangled;
+}
+
+bool SymbolFilePDB::DeclContextMatchesThisSymbolFile(
+ const lldb_private::CompilerDeclContext *decl_ctx) {
+ if (decl_ctx == nullptr || !decl_ctx->IsValid())
+ return true;
+
+ TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem();
+ if (!decl_ctx_type_system)
+ return false;
+ TypeSystem *type_system = GetTypeSystemForLanguage(
+ decl_ctx_type_system->GetMinimumLanguage(nullptr));
+ if (decl_ctx_type_system == type_system)
+ return true; // The type systems match, return true
+
+ return false;
+}
diff --git a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
index eef96be8d1fe..96b62d68a6c2 100644
--- a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
+++ b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
@@ -10,12 +10,15 @@
#ifndef lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_
#define lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_
+#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/VariableList.h"
#include "lldb/Utility/UserID.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/DebugInfo/PDB/IPDBSession.h"
#include "llvm/DebugInfo/PDB/PDB.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
class SymbolFilePDB : public lldb_private::SymbolFile {
public:
@@ -108,11 +111,11 @@ public:
uint32_t
FindGlobalVariables(const lldb_private::ConstString &name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
lldb_private::VariableList &variables) override;
uint32_t FindGlobalVariables(const lldb_private::RegularExpression &regex,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
lldb_private::VariableList &variables) override;
uint32_t
@@ -141,8 +144,7 @@ public:
bool append, lldb_private::TypeMap &types) override;
void FindTypesByRegex(const lldb_private::RegularExpression &regex,
- uint32_t max_matches,
- lldb_private::TypeMap &types);
+ uint32_t max_matches, lldb_private::TypeMap &types);
lldb_private::TypeList *GetTypeList() override;
@@ -167,25 +169,76 @@ public:
const llvm::pdb::IPDBSession &GetPDBSession() const;
private:
- lldb::CompUnitSP ParseCompileUnitForSymIndex(uint32_t id);
+ lldb::CompUnitSP ParseCompileUnitForUID(uint32_t id,
+ uint32_t index = UINT32_MAX);
bool ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc,
uint32_t match_line);
void BuildSupportFileIdToSupportFileIndexMap(
- const llvm::pdb::PDBSymbolCompiland &cu,
+ const llvm::pdb::PDBSymbolCompiland &pdb_compiland,
llvm::DenseMap<uint32_t, uint32_t> &index_map) const;
void FindTypesByName(const std::string &name, uint32_t max_matches,
lldb_private::TypeMap &types);
+ std::string GetMangledForPDBData(const llvm::pdb::PDBSymbolData &pdb_data);
+
+ lldb::VariableSP
+ ParseVariableForPDBData(const lldb_private::SymbolContext &sc,
+ const llvm::pdb::PDBSymbolData &pdb_data);
+
+ size_t ParseVariables(const lldb_private::SymbolContext &sc,
+ const llvm::pdb::PDBSymbol &pdb_data,
+ lldb_private::VariableList *variable_list = nullptr);
+
+ lldb::CompUnitSP
+ GetCompileUnitContainsAddress(const lldb_private::Address &so_addr);
+
+ typedef std::vector<lldb_private::Type *> TypeCollection;
+
+ void GetTypesForPDBSymbol(const llvm::pdb::PDBSymbol &pdb_symbol,
+ uint32_t type_mask,
+ TypeCollection &type_collection);
+
+ lldb_private::Function *
+ ParseCompileUnitFunctionForPDBFunc(const llvm::pdb::PDBSymbolFunc &pdb_func,
+ const lldb_private::SymbolContext &sc);
+
+ void GetCompileUnitIndex(const llvm::pdb::PDBSymbolCompiland &pdb_compiland,
+ uint32_t &index);
+
+ std::unique_ptr<llvm::pdb::PDBSymbolCompiland>
+ GetPDBCompilandByUID(uint32_t uid);
+
+ lldb_private::Mangled
+ GetMangledForPDBFunc(const llvm::pdb::PDBSymbolFunc &pdb_func);
+
+ bool ResolveFunction(const llvm::pdb::PDBSymbolFunc &pdb_func,
+ bool include_inlines,
+ lldb_private::SymbolContextList &sc_list);
+
+ bool ResolveFunction(uint32_t uid, bool include_inlines,
+ lldb_private::SymbolContextList &sc_list);
+
+ void CacheFunctionNames();
+
+ bool DeclContextMatchesThisSymbolFile(
+ const lldb_private::CompilerDeclContext *decl_ctx);
+
llvm::DenseMap<uint32_t, lldb::CompUnitSP> m_comp_units;
llvm::DenseMap<uint32_t, lldb::TypeSP> m_types;
+ llvm::DenseMap<uint32_t, lldb::VariableSP> m_variables;
std::vector<lldb::TypeSP> m_builtin_types;
std::unique_ptr<llvm::pdb::IPDBSession> m_session_up;
+ std::unique_ptr<llvm::pdb::PDBSymbolExe> m_global_scope_up;
uint32_t m_cached_compile_unit_count;
std::unique_ptr<lldb_private::CompilerDeclContext> m_tu_decl_ctx_up;
+
+ lldb_private::UniqueCStringMap<uint32_t> m_func_full_names;
+ lldb_private::UniqueCStringMap<uint32_t> m_func_base_names;
+ lldb_private::UniqueCStringMap<uint32_t> m_func_method_names;
};
#endif // lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_
diff --git a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
index dbc1b9ee5470..64e2daf60ee5 100644
--- a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
+++ b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
@@ -63,9 +63,9 @@ uint32_t SymbolFileSymtab::CalculateAbilities() {
const Symtab *symtab = m_obj_file->GetSymtab();
if (symtab) {
//----------------------------------------------------------------------
- // The snippet of code below will get the indexes the module symbol
- // table entries that are code, data, or function related (debug info),
- // sort them by value (address) and dump the sorted symbols.
+ // The snippet of code below will get the indexes the module symbol table
+ // entries that are code, data, or function related (debug info), sort
+ // them by value (address) and dump the sorted symbols.
//----------------------------------------------------------------------
if (symtab->AppendSymbolIndexesWithType(eSymbolTypeSourceFile,
m_source_indexes)) {
@@ -105,24 +105,21 @@ uint32_t SymbolFileSymtab::CalculateAbilities() {
}
uint32_t SymbolFileSymtab::GetNumCompileUnits() {
- // If we don't have any source file symbols we will just have one compile unit
- // for
- // the entire object file
+ // If we don't have any source file symbols we will just have one compile
+ // unit for the entire object file
if (m_source_indexes.empty())
return 0;
// If we have any source file symbols we will logically organize the object
- // symbols
- // using these.
+ // symbols using these.
return m_source_indexes.size();
}
CompUnitSP SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx) {
CompUnitSP cu_sp;
- // If we don't have any source file symbols we will just have one compile unit
- // for
- // the entire object file
+ // If we don't have any source file symbols we will just have one compile
+ // unit for the entire object file
if (idx < m_source_indexes.size()) {
const Symbol *cu_symbol =
m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
@@ -152,13 +149,12 @@ size_t SymbolFileSymtab::ParseCompileUnitFunctions(const SymbolContext &sc) {
//
// const uint32_t prefix_len = strlen(prefix);
- // If we don't have any source file symbols we will just have one compile unit
- // for
- // the entire object file
+ // If we don't have any source file symbols we will just have one compile
+ // unit for the entire object file
if (m_source_indexes.empty()) {
- // The only time we will have a user ID of zero is when we don't have
- // and source file symbols and we declare one compile unit for the
- // entire object file
+ // The only time we will have a user ID of zero is when we don't have and
+ // source file symbols and we declare one compile unit for the entire
+ // object file
if (!m_func_indexes.empty()) {
}
diff --git a/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp b/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
index a25119684c28..d24510966878 100644
--- a/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
+++ b/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
@@ -57,9 +57,9 @@ const char *SymbolVendorELF::GetPluginDescriptionStatic() {
//----------------------------------------------------------------------
// CreateInstance
//
-// Platforms can register a callback to use when creating symbol
-// vendors to allow for complex debug information file setups, and to
-// also allow for finding separate debug information files.
+// Platforms can register a callback to use when creating symbol vendors to
+// allow for complex debug information file setups, and to also allow for
+// finding separate debug information files.
//----------------------------------------------------------------------
SymbolVendor *
SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
@@ -112,11 +112,9 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
module_sp, &dsym_fspec, 0, dsym_fspec.GetByteSize(),
dsym_file_data_sp, dsym_file_data_offset);
if (dsym_objfile_sp) {
- // This objfile is for debugging purposes. Sadly, ObjectFileELF won't be
- // able
- // to figure this out consistently as the symbol file may not have
- // stripped the
- // code sections, etc.
+ // This objfile is for debugging purposes. Sadly, ObjectFileELF won't
+ // be able to figure this out consistently as the symbol file may not
+ // have stripped the code sections, etc.
dsym_objfile_sp->SetType(ObjectFile::eTypeDebugInfo);
SymbolVendorELF *symbol_vendor = new SymbolVendorELF(module_sp);
@@ -134,7 +132,7 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
eSectionTypeDWARFDebugMacInfo, eSectionTypeDWARFDebugPubNames,
eSectionTypeDWARFDebugPubTypes, eSectionTypeDWARFDebugRanges,
eSectionTypeDWARFDebugStr, eSectionTypeDWARFDebugStrOffsets,
- eSectionTypeELFSymbolTable,
+ eSectionTypeELFSymbolTable, eSectionTypeDWARFGNUDebugAltLink,
};
for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]);
++idx) {
diff --git a/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp b/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
index b3fb05e652d9..c69eb7fd51c7 100644
--- a/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
+++ b/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
@@ -94,9 +94,9 @@ const char *SymbolVendorMacOSX::GetPluginDescriptionStatic() {
//----------------------------------------------------------------------
// CreateInstance
//
-// Platforms can register a callback to use when creating symbol
-// vendors to allow for complex debug information file setups, and to
-// also allow for finding separate debug information files.
+// Platforms can register a callback to use when creating symbol vendors to
+// allow for complex debug information file setups, and to also allow for
+// finding separate debug information files.
//----------------------------------------------------------------------
SymbolVendor *
SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
@@ -130,14 +130,14 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
"SymbolVendorMacOSX::CreateInstance (module = %s) locate dSYM",
module_sp->GetFileSpec().GetPath().c_str());
- // First check to see if the module has a symbol file in mind already.
- // If it does, then we MUST use that.
+ // First check to see if the module has a symbol file in mind already. If
+ // it does, then we MUST use that.
FileSpec dsym_fspec(module_sp->GetSymbolFileFileSpec());
ObjectFileSP dsym_objfile_sp;
if (!dsym_fspec) {
- // No symbol file was specified in the module, lets try and find
- // one ourselves.
+ // No symbol file was specified in the module, lets try and find one
+ // ourselves.
FileSpec file_spec = obj_file->GetFileSpec();
if (!file_spec)
file_spec = module_sp->GetFileSpec();
@@ -179,24 +179,8 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
std::string DBGBuildSourcePath;
std::string DBGSourcePath;
- plist.GetValueAsString("DBGBuildSourcePath",
- DBGBuildSourcePath);
- plist.GetValueAsString("DBGSourcePath", DBGSourcePath);
- if (!DBGBuildSourcePath.empty() &&
- !DBGSourcePath.empty()) {
- if (DBGSourcePath[0] == '~') {
- FileSpec resolved_source_path(DBGSourcePath.c_str(),
- true);
- DBGSourcePath = resolved_source_path.GetPath();
- }
- module_sp->GetSourceMappingList().Append(
- ConstString(DBGBuildSourcePath),
- ConstString(DBGSourcePath), true);
- }
-
// DBGSourcePathRemapping is a dictionary in the plist
- // with
- // keys which are DBGBuildSourcePath file paths and
+ // with keys which are DBGBuildSourcePath file paths and
// values which are DBGSourcePath file paths
StructuredData::ObjectSP plist_sp =
@@ -208,17 +192,14 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
->GetValueForKey("DBGSourcePathRemapping")
->GetAsDictionary()) {
- // In an early version of DBGSourcePathRemapping, the
- // DBGSourcePath
- // values were incorrect. If we have a newer style
- // DBGSourcePathRemapping, there will be a DBGVersion
- // key in the plist with version 2 or higher.
+ // If DBGVersion 1 or DBGVersion missing, ignore DBGSourcePathRemapping.
+ // If DBGVersion 2, strip last two components of path remappings from
+ // entries to fix an issue with a specific set of
+ // DBGSourcePathRemapping entries that lldb worked
+ // with.
+ // If DBGVersion 3, trust & use the source path remappings as-is.
//
- // If this is an old style DBGSourcePathRemapping,
- // ignore the
- // value half of the key-value remappings and use reuse
- // the original
- // gloal DBGSourcePath string.
+
bool new_style_source_remapping_dictionary = false;
bool do_truncate_remapping_names = false;
std::string original_DBGSourcePath_value =
@@ -268,10 +249,12 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
}
module_sp->GetSourceMappingList().Append(
key, ConstString(DBGSourcePath), true);
- // With version 2 of DBGSourcePathRemapping, we can chop off the
- // last two filename parts from the source remapping and get a
- // more general source remapping that still works. Add this as
- // another option in addition to the full source path remap.
+ // With version 2 of DBGSourcePathRemapping, we
+ // can chop off the last two filename parts
+ // from the source remapping and get a more
+ // general source remapping that still works.
+ // Add this as another option in addition to
+ // the full source path remap.
if (do_truncate_remapping_names) {
FileSpec build_path(key.AsCString(), false);
FileSpec source_path(DBGSourcePath.c_str(), false);
@@ -287,6 +270,24 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
return true;
});
}
+
+ // If we have a DBGBuildSourcePath + DBGSourcePath pair,
+ // append those to the source path remappings.
+
+ plist.GetValueAsString("DBGBuildSourcePath",
+ DBGBuildSourcePath);
+ plist.GetValueAsString("DBGSourcePath", DBGSourcePath);
+ if (!DBGBuildSourcePath.empty() &&
+ !DBGSourcePath.empty()) {
+ if (DBGSourcePath[0] == '~') {
+ FileSpec resolved_source_path(DBGSourcePath.c_str(),
+ true);
+ DBGSourcePath = resolved_source_path.GetPath();
+ }
+ module_sp->GetSourceMappingList().Append(
+ ConstString(DBGBuildSourcePath),
+ ConstString(DBGSourcePath), true);
+ }
}
}
}
@@ -300,9 +301,9 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
}
}
- // Just create our symbol vendor using the current objfile as this is either
- // an executable with no dSYM (that we could locate), an executable with
- // a dSYM that has a UUID that doesn't match.
+ // Just create our symbol vendor using the current objfile as this is
+ // either an executable with no dSYM (that we could locate), an executable
+ // with a dSYM that has a UUID that doesn't match.
symbol_vendor->AddSymbolFileRepresentation(obj_file->shared_from_this());
}
return symbol_vendor;
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp b/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
index 3f0c7db676f3..007a59378fc5 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
@@ -119,20 +119,18 @@ void AppleGetItemInfoHandler::Detach() {
}
// Compile our __lldb_backtrace_recording_get_item_info() function (from the
-// source above in g_get_item_info_function_code) if we don't find that function
-// in the inferior
-// already with USE_BUILTIN_FUNCTION defined. (e.g. this would be the case for
-// testing.)
+// source above in g_get_item_info_function_code) if we don't find that
+// function in the inferior already with USE_BUILTIN_FUNCTION defined. (e.g.
+// this would be the case for testing.)
//
-// Insert the __lldb_backtrace_recording_get_item_info into the inferior process
-// if needed.
+// Insert the __lldb_backtrace_recording_get_item_info into the inferior
+// process if needed.
//
// Write the get_item_info_arglist into the inferior's memory space to prepare
// for the call.
//
// Returns the address of the arguments written down in the inferior process,
-// which can be used to
-// make the function call.
+// which can be used to make the function call.
lldb::addr_t AppleGetItemInfoHandler::SetupGetItemInfoFunction(
Thread &thread, ValueList &get_item_info_arglist) {
@@ -146,7 +144,8 @@ lldb::addr_t AppleGetItemInfoHandler::SetupGetItemInfoFunction(
{
std::lock_guard<std::mutex> guard(m_get_item_info_function_mutex);
- // First stage is to make the UtilityFunction to hold our injected function:
+ // First stage is to make the UtilityFunction to hold our injected
+ // function:
if (!m_get_item_info_impl_code.get()) {
if (g_get_item_info_function_code != NULL) {
@@ -209,10 +208,9 @@ lldb::addr_t AppleGetItemInfoHandler::SetupGetItemInfoFunction(
diagnostics.Clear();
// Now write down the argument values for this particular call. This looks
- // like it might be a race condition
- // if other threads were calling into here, but actually it isn't because we
- // allocate a new args structure for
- // this call by passing args_addr = LLDB_INVALID_ADDRESS...
+ // like it might be a race condition if other threads were calling into here,
+ // but actually it isn't because we allocate a new args structure for this
+ // call by passing args_addr = LLDB_INVALID_ADDRESS...
if (!get_item_info_caller->WriteFunctionArguments(
exe_ctx, args_addr, get_item_info_arglist, diagnostics)) {
@@ -272,8 +270,7 @@ AppleGetItemInfoHandler::GetItemInfo(Thread &thread, uint64_t item,
// uint64_t page_to_free_size)
// Where the return_buffer argument points to a 24 byte region of memory
- // already allocated by lldb in
- // the inferior process.
+ // already allocated by lldb in the inferior process.
CompilerType clang_void_ptr_type =
clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp b/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
index e3d03a6f9484..0de32bf11416 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
@@ -121,11 +121,10 @@ void AppleGetPendingItemsHandler::Detach() {
}
}
-// Compile our __lldb_backtrace_recording_get_pending_items() function (from the
-// source above in g_get_pending_items_function_code) if we don't find that
-// function in the inferior
-// already with USE_BUILTIN_FUNCTION defined. (e.g. this would be the case for
-// testing.)
+// Compile our __lldb_backtrace_recording_get_pending_items() function (from
+// the source above in g_get_pending_items_function_code) if we don't find that
+// function in the inferior already with USE_BUILTIN_FUNCTION defined. (e.g.
+// this would be the case for testing.)
//
// Insert the __lldb_backtrace_recording_get_pending_items into the inferior
// process if needed.
@@ -134,8 +133,7 @@ void AppleGetPendingItemsHandler::Detach() {
// prepare for the call.
//
// Returns the address of the arguments written down in the inferior process,
-// which can be used to
-// make the function call.
+// which can be used to make the function call.
lldb::addr_t AppleGetPendingItemsHandler::SetupGetPendingItemsFunction(
Thread &thread, ValueList &get_pending_items_arglist) {
@@ -212,10 +210,9 @@ lldb::addr_t AppleGetPendingItemsHandler::SetupGetPendingItemsFunction(
}
// Now write down the argument values for this particular call. This looks
- // like it might be a race condition
- // if other threads were calling into here, but actually it isn't because we
- // allocate a new args structure for
- // this call by passing args_addr = LLDB_INVALID_ADDRESS...
+ // like it might be a race condition if other threads were calling into here,
+ // but actually it isn't because we allocate a new args structure for this
+ // call by passing args_addr = LLDB_INVALID_ADDRESS...
if (!get_pending_items_caller->WriteFunctionArguments(
exe_ctx, args_addr, get_pending_items_arglist, diagnostics)) {
@@ -279,8 +276,7 @@ AppleGetPendingItemsHandler::GetPendingItems(Thread &thread, addr_t queue,
// uint64_t page_to_free_size)
// Where the return_buffer argument points to a 24 byte region of memory
- // already allocated by lldb in
- // the inferior process.
+ // already allocated by lldb in the inferior process.
CompilerType clang_void_ptr_type =
clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp b/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
index c1654eb62ccc..7855b3603a3a 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
@@ -118,9 +118,9 @@ void AppleGetQueuesHandler::Detach() {
}
// Construct a CompilerType for the structure that
-// g_get_current_queues_function_code will return by value
-// so we can extract the fields after performing the function call.
-// i.e. we are getting this struct returned to us:
+// g_get_current_queues_function_code will return by value so we can extract
+// the fields after performing the function call. i.e. we are getting this
+// struct returned to us:
//
// struct get_current_queues_return_values
// {
@@ -130,11 +130,9 @@ void AppleGetQueuesHandler::Detach() {
// };
// Compile our __lldb_backtrace_recording_get_current_queues() function (from
-// the
-// source above in g_get_current_queues_function_code) if we don't find that
-// function in the inferior
-// already with USE_BUILTIN_FUNCTION defined. (e.g. this would be the case for
-// testing.)
+// the source above in g_get_current_queues_function_code) if we don't find
+// that function in the inferior already with USE_BUILTIN_FUNCTION defined.
+// (e.g. this would be the case for testing.)
//
// Insert the __lldb_backtrace_recording_get_current_queues into the inferior
// process if needed.
@@ -143,8 +141,7 @@ void AppleGetQueuesHandler::Detach() {
// the call.
//
// Returns the address of the arguments written down in the inferior process,
-// which can be used to
-// make the function call.
+// which can be used to make the function call.
lldb::addr_t
AppleGetQueuesHandler::SetupGetQueuesFunction(Thread &thread,
@@ -217,10 +214,9 @@ AppleGetQueuesHandler::SetupGetQueuesFunction(Thread &thread,
diagnostics.Clear();
// Now write down the argument values for this particular call. This looks
- // like it might be a race condition
- // if other threads were calling into here, but actually it isn't because we
- // allocate a new args structure for
- // this call by passing args_addr = LLDB_INVALID_ADDRESS...
+ // like it might be a race condition if other threads were calling into here,
+ // but actually it isn't because we allocate a new args structure for this
+ // call by passing args_addr = LLDB_INVALID_ADDRESS...
if (!get_queues_caller->WriteFunctionArguments(
exe_ctx, args_addr, get_queues_arglist, diagnostics)) {
@@ -280,8 +276,7 @@ AppleGetQueuesHandler::GetCurrentQueues(Thread &thread, addr_t page_to_free,
// uint64_t page_to_free_size);
// Where the return_buffer argument points to a 24 byte region of memory
- // already allocated by lldb in
- // the inferior process.
+ // already allocated by lldb in the inferior process.
CompilerType clang_void_ptr_type =
clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp b/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
index 8d83922af1e7..09ab6600a9f0 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
@@ -128,11 +128,9 @@ void AppleGetThreadItemInfoHandler::Detach() {
}
// Compile our __lldb_backtrace_recording_get_thread_item_info() function (from
-// the
-// source above in g_get_thread_item_info_function_code) if we don't find that
-// function in the inferior
-// already with USE_BUILTIN_FUNCTION defined. (e.g. this would be the case for
-// testing.)
+// the source above in g_get_thread_item_info_function_code) if we don't find
+// that function in the inferior already with USE_BUILTIN_FUNCTION defined.
+// (e.g. this would be the case for testing.)
//
// Insert the __lldb_backtrace_recording_get_thread_item_info into the inferior
// process if needed.
@@ -141,8 +139,7 @@ void AppleGetThreadItemInfoHandler::Detach() {
// prepare for the call.
//
// Returns the address of the arguments written down in the inferior process,
-// which can be used to
-// make the function call.
+// which can be used to make the function call.
lldb::addr_t AppleGetThreadItemInfoHandler::SetupGetThreadItemInfoFunction(
Thread &thread, ValueList &get_thread_item_info_arglist) {
@@ -221,10 +218,9 @@ lldb::addr_t AppleGetThreadItemInfoHandler::SetupGetThreadItemInfoFunction(
diagnostics.Clear();
// Now write down the argument values for this particular call. This looks
- // like it might be a race condition
- // if other threads were calling into here, but actually it isn't because we
- // allocate a new args structure for
- // this call by passing args_addr = LLDB_INVALID_ADDRESS...
+ // like it might be a race condition if other threads were calling into here,
+ // but actually it isn't because we allocate a new args structure for this
+ // call by passing args_addr = LLDB_INVALID_ADDRESS...
if (!get_thread_item_info_caller->WriteFunctionArguments(
exe_ctx, args_addr, get_thread_item_info_arglist, diagnostics)) {
@@ -266,8 +262,7 @@ AppleGetThreadItemInfoHandler::GetThreadItemInfo(Thread &thread,
// Set up the arguments for a call to
- // struct get_thread_item_info_return_values
- // {
+ // struct get_thread_item_info_return_values {
// uint64_t item_info_buffer_ptr; /* the address of the items buffer
// from libBacktraceRecording */
// uint64_t item_info_buffer_size; /* the size of the items buffer from
@@ -283,8 +278,7 @@ AppleGetThreadItemInfoHandler::GetThreadItemInfo(Thread &thread,
// uint64_t page_to_free_size)
// Where the return_buffer argument points to a 24 byte region of memory
- // already allocated by lldb in
- // the inferior process.
+ // already allocated by lldb in the inferior process.
CompilerType clang_void_ptr_type =
clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
diff --git a/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp b/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
index 1a538b236c15..4748d5e8622e 100644
--- a/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
+++ b/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
@@ -34,9 +34,9 @@ using namespace lldb;
using namespace lldb_private;
//----------------------------------------------------------------------
-// Create an instance of this class. This function is filled into
-// the plugin info class that gets handed out by the plugin factory and
-// allows the lldb to instantiate an instance of this class.
+// Create an instance of this class. This function is filled into the plugin
+// info class that gets handed out by the plugin factory and allows the lldb to
+// instantiate an instance of this class.
//----------------------------------------------------------------------
SystemRuntime *SystemRuntimeMacOSX::CreateInstance(Process *process) {
bool create = false;
@@ -125,17 +125,15 @@ SystemRuntimeMacOSX::GetQueueNameFromThreadQAddress(addr_t dispatch_qaddr) {
ReadLibdispatchOffsets();
if (m_libdispatch_offsets.IsValid()) {
// dispatch_qaddr is from a thread_info(THREAD_IDENTIFIER_INFO) call for a
- // thread -
- // deref it to get the address of the dispatch_queue_t structure for this
- // thread's
- // queue.
+ // thread - deref it to get the address of the dispatch_queue_t structure
+ // for this thread's queue.
Status error;
addr_t dispatch_queue_addr =
m_process->ReadPointerFromMemory(dispatch_qaddr, error);
if (error.Success()) {
if (m_libdispatch_offsets.dqo_version >= 4) {
- // libdispatch versions 4+, pointer to dispatch name is in the
- // queue structure.
+ // libdispatch versions 4+, pointer to dispatch name is in the queue
+ // structure.
addr_t pointer_to_label_address =
dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
addr_t label_addr =
@@ -248,10 +246,8 @@ SystemRuntimeMacOSX::GetQueueIDFromThreadQAddress(lldb::addr_t dispatch_qaddr) {
ReadLibdispatchOffsets();
if (m_libdispatch_offsets.IsValid()) {
// dispatch_qaddr is from a thread_info(THREAD_IDENTIFIER_INFO) call for a
- // thread -
- // deref it to get the address of the dispatch_queue_t structure for this
- // thread's
- // queue.
+ // thread - deref it to get the address of the dispatch_queue_t structure
+ // for this thread's queue.
Status error;
uint64_t dispatch_queue_addr =
m_process->ReadPointerFromMemory(dispatch_qaddr, error);
@@ -287,8 +283,8 @@ void SystemRuntimeMacOSX::ReadLibdispatchOffsetsAddress() {
dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType(
g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
- // libdispatch symbols are in their own dylib as of Mac OS X 10.7 ("Lion") and
- // later
+ // libdispatch symbols are in their own dylib as of Mac OS X 10.7 ("Lion")
+ // and later
if (dispatch_queue_offsets_symbol == NULL) {
ModuleSpec libdispatch_module_spec(FileSpec("libdispatch.dylib", false));
module_sp = m_process->GetTarget().GetImages().FindFirstModule(
@@ -320,8 +316,7 @@ void SystemRuntimeMacOSX::ReadLibdispatchOffsets() {
lldb::offset_t data_offset = 0;
// The struct LibdispatchOffsets is a series of uint16_t's - extract them
- // all
- // in one big go.
+ // all in one big go.
data.GetU16(&data_offset, &m_libdispatch_offsets.dqo_version,
sizeof(struct LibdispatchOffsets) / sizeof(uint16_t));
}
@@ -368,8 +363,7 @@ void SystemRuntimeMacOSX::ReadLibpthreadOffsets() {
lldb::offset_t data_offset = 0;
// The struct LibpthreadOffsets is a series of uint16_t's - extract them
- // all
- // in one big go.
+ // all in one big go.
data.GetU16(&data_offset, &m_libpthread_offsets.plo_version,
sizeof(struct LibpthreadOffsets) / sizeof(uint16_t));
}
@@ -407,10 +401,8 @@ void SystemRuntimeMacOSX::ReadLibdispatchTSDIndexes() {
if (m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS) {
// We don't need to check the version number right now, it will be at least 2,
-// but
-// keep this code around to fetch just the version # for the future where we
-// need
-// to fetch alternate versions of the struct.
+// but keep this code around to fetch just the version # for the future where
+// we need to fetch alternate versions of the struct.
#if 0
uint16_t dti_version = 2;
Address dti_struct_addr;
@@ -473,12 +465,9 @@ ThreadSP SystemRuntimeMacOSX::GetExtendedBacktraceThread(ThreadSP real_thread,
Status error;
// real_thread is either an actual, live thread (in which case we need to
- // call into
- // libBacktraceRecording to find its originator) or it is an extended
- // backtrace itself,
- // in which case we get the token from it and call into
- // libBacktraceRecording to find
- // the originator of that token.
+ // call into libBacktraceRecording to find its originator) or it is an
+ // extended backtrace itself, in which case we get the token from it and
+ // call into libBacktraceRecording to find the originator of that token.
if (real_thread->GetExtendedBacktraceToken() != LLDB_INVALID_ADDRESS) {
originating_thread_sp = GetExtendedBacktraceFromItemRef(
@@ -735,13 +724,11 @@ void SystemRuntimeMacOSX::PopulateQueueList(
}
// We either didn't have libBacktraceRecording (and need to create the queues
- // list based on threads)
- // or we did get the queues list from libBacktraceRecording but some special
- // queues may not be
- // included in its information. This is needed because libBacktraceRecording
- // will only list queues with pending or running items by default - but the
- // magic com.apple.main-thread
- // queue on thread 1 is always around.
+ // list based on threads) or we did get the queues list from
+ // libBacktraceRecording but some special queues may not be included in its
+ // information. This is needed because libBacktraceRecording will only list
+ // queues with pending or running items by default - but the magic com.apple
+ // .main-thread queue on thread 1 is always around.
for (ThreadSP thread_sp : m_process->Threads()) {
if (thread_sp->GetAssociatedWithLibdispatchQueue() != eLazyBoolNo) {
@@ -769,12 +756,10 @@ void SystemRuntimeMacOSX::PopulateQueueList(
}
// Returns either an array of introspection_dispatch_item_info_ref's for the
-// pending items on
-// a queue or an array introspection_dispatch_item_info_ref's and code addresses
-// for the
-// pending items on a queue. The information about each of these pending items
-// then needs to
-// be fetched individually by passing the ref to libBacktraceRecording.
+// pending items on a queue or an array introspection_dispatch_item_info_ref's
+// and code addresses for the pending items on a queue. The information about
+// each of these pending items then needs to be fetched individually by passing
+// the ref to libBacktraceRecording.
SystemRuntimeMacOSX::PendingItemsForQueue
SystemRuntimeMacOSX::GetPendingItemRefsForQueue(lldb::addr_t queue) {
@@ -927,8 +912,8 @@ void SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR(
offset_t offset = 0;
uint64_t queues_read = 0;
- // The information about the queues is stored in this format (v1):
- // typedef struct introspection_dispatch_queue_info_s {
+ // The information about the queues is stored in this format (v1): typedef
+ // struct introspection_dispatch_queue_info_s {
// uint32_t offset_to_next;
// dispatch_queue_t queue;
// uint64_t serialnum; // queue's serialnum in the process, as
diff --git a/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp b/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
index f8aca4d1283b..54e182b30b6f 100644
--- a/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
+++ b/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
@@ -12,6 +12,7 @@
#include "lldb/Core/Address.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/DumpDataExtractor.h"
+#include "lldb/Core/DumpRegisterValue.h"
#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Target/ExecutionContext.h"
@@ -58,8 +59,8 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid() &&
m_inst_emulator_ap.get()) {
- // The instruction emulation subclass setup the unwind plan for the
- // first instruction.
+ // The instruction emulation subclass setup the unwind plan for the first
+ // instruction.
m_inst_emulator_ap->CreateFunctionEntryUnwind(unwind_plan);
// CreateFunctionEntryUnwind should have created the first row. If it
@@ -90,9 +91,9 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
m_register_values.clear();
m_pushed_regs.clear();
- // Initialize the CFA with a known value. In the 32 bit case
- // it will be 0x80000000, and in the 64 bit case 0x8000000000000000.
- // We use the address byte size to be safe for any future address sizes
+ // Initialize the CFA with a known value. In the 32 bit case it will be
+ // 0x80000000, and in the 64 bit case 0x8000000000000000. We use the
+ // address byte size to be safe for any future address sizes
m_initial_sp = (1ull << ((addr_byte_size * 8) - 1));
RegisterValue cfa_reg_value;
cfa_reg_value.SetUInt(m_initial_sp, m_cfa_reg_info.byte_size);
@@ -105,14 +106,12 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
Instruction *inst = inst_list.GetInstructionAtIndex(0).get();
const lldb::addr_t base_addr = inst->GetAddress().GetFileAddress();
- // Map for storing the unwind plan row and the value of the registers at
- // a given offset.
- // When we see a forward branch we add a new entry to this map with the
- // actual unwind plan
- // row and register context for the target address of the branch as the
- // current data have
- // to be valid for the target address of the branch too if we are in the
- // same function.
+ // Map for storing the unwind plan row and the value of the registers
+ // at a given offset. When we see a forward branch we add a new entry
+ // to this map with the actual unwind plan row and register context for
+ // the target address of the branch as the current data have to be
+ // valid for the target address of the branch too if we are in the same
+ // function.
std::map<lldb::addr_t, std::pair<UnwindPlan::RowSP, RegisterValueMap>>
saved_unwind_states;
@@ -128,15 +127,14 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
saved_unwind_states.insert({0, {last_row, m_register_values}});
// cache the pc register number (in whatever register numbering this
- // UnwindPlan uses) for
- // quick reference during instruction parsing.
+ // UnwindPlan uses) for quick reference during instruction parsing.
RegisterInfo pc_reg_info;
m_inst_emulator_ap->GetRegisterInfo(
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc_reg_info);
// cache the return address register number (in whatever register
- // numbering this UnwindPlan uses) for
- // quick reference during instruction parsing.
+ // numbering this UnwindPlan uses) for quick reference during
+ // instruction parsing.
RegisterInfo ra_reg_info;
m_inst_emulator_ap->GetRegisterInfo(
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, ra_reg_info);
@@ -160,12 +158,11 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
"Unwind row for the function entry missing");
--it; // Move it to the row corresponding to the current offset
- // If the offset of m_curr_row don't match with the offset we see in
- // saved_unwind_states
- // then we have to update m_curr_row and m_register_values based on
- // the saved values. It
- // is happenning after we processed an epilogue and a return to
- // caller instruction.
+ // If the offset of m_curr_row don't match with the offset we see
+ // in saved_unwind_states then we have to update m_curr_row and
+ // m_register_values based on the saved values. It is happening
+ // after we processed an epilogue and a return to caller
+ // instruction.
if (it->second.first->GetOffset() != m_curr_row->GetOffset()) {
UnwindPlan::Row *newrow = new UnwindPlan::Row;
*newrow = *it->second.first;
@@ -181,10 +178,9 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
if (m_inst_emulator_ap->GetInstructionCondition() !=
EmulateInstruction::UnconditionalCondition &&
saved_unwind_states.count(current_offset) == 0) {
- // If we don't have a saved row for the current offset then save
- // our
- // current state because we will have to restore it after the
- // conditional block.
+ // If we don't have a saved row for the current offset then
+ // save our current state because we will have to restore it
+ // after the conditional block.
auto new_row =
std::make_shared<UnwindPlan::Row>(*m_curr_row.get());
saved_unwind_states.insert(
@@ -192,8 +188,8 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
}
// If the last instruction was conditional with a different
- // condition
- // then the then current condition then restore the condition.
+ // condition then the then current condition then restore the
+ // condition.
if (last_condition !=
EmulateInstruction::UnconditionalCondition) {
const auto &saved_state =
@@ -211,7 +207,7 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
replace_existing);
}
- // We are starting a new conditional block at the catual offset
+ // We are starting a new conditional block at the actual offset
condition_block_start_offset = current_offset;
}
@@ -230,8 +226,7 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
eEmulateInstructionOptionIgnoreConditions);
// If the current instruction is a branch forward then save the
- // current CFI information
- // for the offset where we are branching.
+ // current CFI information for the offset where we are branching.
if (m_forward_branch_offset != 0 &&
range.ContainsFileAddress(inst->GetAddress().GetFileAddress() +
m_forward_branch_offset)) {
@@ -247,8 +242,8 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
// Were there any changes to the CFI while evaluating this
// instruction?
if (m_curr_row_modified) {
- // Save the modified row if we don't already have a CFI row in the
- // currennt address
+ // Save the modified row if we don't already have a CFI row in
+ // the current address
if (saved_unwind_states.count(
current_offset + inst->GetOpcode().GetByteSize()) == 0) {
m_curr_row->SetOffset(current_offset +
@@ -492,7 +487,7 @@ bool UnwindAssemblyInstEmulation::ReadRegister(EmulateInstruction *instruction,
strm.Printf("UnwindAssemblyInstEmulation::ReadRegister (name = \"%s\") => "
"synthetic_value = %i, value = ",
reg_info->name, synthetic);
- reg_value.Dump(&strm, reg_info, false, false, eFormatDefault);
+ DumpRegisterValue(reg_value, &strm, reg_info, false, false, eFormatDefault);
log->PutString(strm.GetString());
}
return true;
@@ -518,7 +513,7 @@ bool UnwindAssemblyInstEmulation::WriteRegister(
strm.Printf(
"UnwindAssemblyInstEmulation::WriteRegister (name = \"%s\", value = ",
reg_info->name);
- reg_value.Dump(&strm, reg_info, false, false, eFormatDefault);
+ DumpRegisterValue(reg_value, &strm, reg_info, false, false, eFormatDefault);
strm.PutCString(", context = ");
context.Dump(strm, instruction);
log->PutString(strm.GetString());
diff --git a/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp b/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
index b8dcd99a53e7..327d0b0e4f71 100644
--- a/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
+++ b/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
@@ -86,12 +86,10 @@ bool UnwindAssembly_x86::AugmentUnwindPlanFromCallSite(
LLDB_REGNUM_GENERIC_PC);
// Does this UnwindPlan describe the prologue? I want to see that the CFA is
- // set
- // in terms of the stack pointer plus an offset, and I want to see that rip is
- // retrieved at the CFA-wordsize.
- // If there is no description of the prologue, don't try to augment this
- // eh_frame
- // unwinder code, fall back to assembly parsing instead.
+ // set in terms of the stack pointer plus an offset, and I want to see that
+ // rip is retrieved at the CFA-wordsize. If there is no description of the
+ // prologue, don't try to augment this eh_frame unwinder code, fall back to
+ // assembly parsing instead.
if (first_row->GetCFAValue().GetValueType() !=
UnwindPlan::Row::CFAValue::isRegisterPlusOffset ||
@@ -110,14 +108,13 @@ bool UnwindAssembly_x86::AugmentUnwindPlanFromCallSite(
return false;
}
- // It looks like the prologue is described.
- // Is the epilogue described? If it is, no need to do any augmentation.
+ // It looks like the prologue is described. Is the epilogue described? If it
+ // is, no need to do any augmentation.
if (first_row != last_row &&
first_row->GetOffset() != last_row->GetOffset()) {
- // The first & last row have the same CFA register
- // and the same CFA offset value
- // and the CFA register is esp/rsp (the stack pointer).
+ // The first & last row have the same CFA register and the same CFA offset
+ // value and the CFA register is esp/rsp (the stack pointer).
// We're checking that both of them have an unwind rule like "CFA=esp+4" or
// CFA+rsp+8".
@@ -128,8 +125,8 @@ bool UnwindAssembly_x86::AugmentUnwindPlanFromCallSite(
last_row->GetCFAValue().GetRegisterNumber() &&
first_row->GetCFAValue().GetOffset() ==
last_row->GetCFAValue().GetOffset()) {
- // Get the register locations for eip/rip from the first & last rows.
- // Are they both CFA plus an offset? Is it the same offset?
+ // Get the register locations for eip/rip from the first & last rows. Are
+ // they both CFA plus an offset? Is it the same offset?
UnwindPlan::Row::RegisterLocation last_row_pc_loc;
if (last_row->GetRegisterInfo(
@@ -139,12 +136,10 @@ bool UnwindAssembly_x86::AugmentUnwindPlanFromCallSite(
first_row_pc_loc.GetOffset() == last_row_pc_loc.GetOffset()) {
// One last sanity check: Is the unwind rule for getting the caller
- // pc value
- // "deref the CFA-4" or "deref the CFA-8"?
+ // pc value "deref the CFA-4" or "deref the CFA-8"?
// If so, we have an UnwindPlan that already describes the epilogue
- // and we don't need
- // to modify it at all.
+ // and we don't need to modify it at all.
if (first_row_pc_loc.GetOffset() == -wordsize) {
do_augment_unwindplan = false;
diff --git a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
index aa15063ac0dc..10a56980594f 100644
--- a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
+++ b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
@@ -246,8 +246,7 @@ void x86AssemblyInspectionEngine::Initialize(
}
// This function expects an x86 native register number (i.e. the bits stripped
-// out of the
-// actual instruction), not an lldb register number.
+// out of the actual instruction), not an lldb register number.
//
// FIXME: This is ABI dependent, it shouldn't be hardcoded here.
@@ -321,15 +320,14 @@ bool x86AssemblyInspectionEngine::push_imm_pattern_p() {
// pushl imm8(%esp)
//
-// e.g. 0xff 0x74 0x24 0x20 - 'pushl 0x20(%esp)'
-// (same byte pattern for 'pushq 0x20(%rsp)' in an x86_64 program)
+// e.g. 0xff 0x74 0x24 0x20 - 'pushl 0x20(%esp)' (same byte pattern for 'pushq
+// 0x20(%rsp)' in an x86_64 program)
//
-// 0xff (with opcode bits '6' in next byte, PUSH r/m32)
-// 0x74 (ModR/M byte with three bits used to specify the opcode)
+// 0xff (with opcode bits '6' in next byte, PUSH r/m32) 0x74 (ModR/M byte with
+// three bits used to specify the opcode)
// mod == b01, opcode == b110, R/M == b100
// "+disp8"
-// 0x24 (SIB byte - scaled index = 0, r32 == esp)
-// 0x20 imm8 value
+// 0x24 (SIB byte - scaled index = 0, r32 == esp) 0x20 imm8 value
bool x86AssemblyInspectionEngine::push_extended_pattern_p() {
if (*m_cur_insn == 0xff) {
@@ -337,9 +335,8 @@ bool x86AssemblyInspectionEngine::push_extended_pattern_p() {
uint8_t opcode = (*(m_cur_insn + 1) >> 3) & 7;
if (opcode == 6) {
// I'm only looking for 0xff /6 here - I
- // don't really care what value is being pushed,
- // just that we're pushing a 32/64 bit value on
- // to the stack is enough.
+ // don't really care what value is being pushed, just that we're pushing
+ // a 32/64 bit value on to the stack is enough.
return true;
}
}
@@ -377,8 +374,8 @@ bool x86AssemblyInspectionEngine::push_reg_p(int &regno) {
return false;
}
-// movq %rsp, %rbp [0x48 0x8b 0xec] or [0x48 0x89 0xe5]
-// movl %esp, %ebp [0x8b 0xec] or [0x89 0xe5]
+// movq %rsp, %rbp [0x48 0x8b 0xec] or [0x48 0x89 0xe5] movl %esp, %ebp [0x8b
+// 0xec] or [0x89 0xe5]
bool x86AssemblyInspectionEngine::mov_rsp_rbp_pattern_p() {
uint8_t *p = m_cur_insn;
if (m_wordsize == 8 && *p == 0x48)
@@ -529,16 +526,16 @@ bool x86AssemblyInspectionEngine::call_next_insn_pattern_p() {
(*(p + 3) == 0x0) && (*(p + 4) == 0x0);
}
-// Look for an instruction sequence storing a nonvolatile register
-// on to the stack frame.
+// Look for an instruction sequence storing a nonvolatile register on to the
+// stack frame.
// movq %rax, -0x10(%rbp) [0x48 0x89 0x45 0xf0]
// movl %eax, -0xc(%ebp) [0x89 0x45 0xf4]
-// The offset value returned in rbp_offset will be positive --
-// but it must be subtraced from the frame base register to get
-// the actual location. The positive value returned for the offset
-// is a convention used elsewhere for CFA offsets et al.
+// The offset value returned in rbp_offset will be positive -- but it must be
+// subtraced from the frame base register to get the actual location. The
+// positive value returned for the offset is a convention used elsewhere for
+// CFA offsets et al.
bool x86AssemblyInspectionEngine::mov_reg_to_local_stack_frame_p(
int &regno, int &rbp_offset) {
@@ -550,8 +547,8 @@ bool x86AssemblyInspectionEngine::mov_reg_to_local_stack_frame_p(
src_reg_prefix_bit = REX_W_SRCREG(*p) << 3;
target_reg_prefix_bit = REX_W_DSTREG(*p) << 3;
if (target_reg_prefix_bit == 1) {
- // rbp/ebp don't need a prefix bit - we know this isn't the
- // reg we care about.
+ // rbp/ebp don't need a prefix bit - we know this isn't the reg we care
+ // about.
return false;
}
p++;
@@ -671,18 +668,16 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
*newrow = *row.get();
row.reset(newrow);
- // Track which registers have been saved so far in the prologue.
- // If we see another push of that register, it's not part of the prologue.
- // The register numbers used here are the machine register #'s
- // (i386_register_numbers, x86_64_register_numbers).
+ // Track which registers have been saved so far in the prologue. If we see
+ // another push of that register, it's not part of the prologue. The register
+ // numbers used here are the machine register #'s (i386_register_numbers,
+ // x86_64_register_numbers).
std::vector<bool> saved_registers(32, false);
// Once the prologue has completed we'll save a copy of the unwind
- // instructions
- // If there is an epilogue in the middle of the function, after that epilogue
- // we'll reinstate
- // the unwind setup -- we assume that some code path jumps over the
- // mid-function epilogue
+ // instructions If there is an epilogue in the middle of the function, after
+ // that epilogue we'll reinstate the unwind setup -- we assume that some code
+ // path jumps over the mid-function epilogue
UnwindPlan::RowSP prologue_completed_row; // copy of prologue row of CFI
int prologue_completed_sp_bytes_offset_from_cfa; // The sp value before the
@@ -723,9 +718,8 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
}
// This is the start() function (or a pthread equivalent), it starts with a
- // pushl $0x0 which puts the
- // saved pc value of 0 on the stack. In this case we want to pretend we
- // didn't see a stack movement at all --
+ // pushl $0x0 which puts the saved pc value of 0 on the stack. In this
+ // case we want to pretend we didn't see a stack movement at all --
// normally the saved pc value is already on the stack by the time the
// function starts executing.
else if (push_0_pattern_p()) {
@@ -733,9 +727,9 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
else if (push_reg_p(machine_regno)) {
current_sp_bytes_offset_from_cfa += m_wordsize;
- // the PUSH instruction has moved the stack pointer - if the CFA is set in
- // terms of the stack pointer,
- // we need to add a new row of instructions.
+ // the PUSH instruction has moved the stack pointer - if the CFA is set
+ // in terms of the stack pointer, we need to add a new row of
+ // instructions.
if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
row_updated = true;
@@ -772,8 +766,7 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
}
// the POP instruction has moved the stack pointer - if the CFA is set in
- // terms of the stack pointer,
- // we need to add a new row of instructions.
+ // terms of the stack pointer, we need to add a new row of instructions.
if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
row->GetCFAValue().SetIsRegisterPlusOffset(
m_lldb_sp_regnum, current_sp_bytes_offset_from_cfa);
@@ -790,13 +783,13 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
}
}
- // The LEAVE instruction moves the value from rbp into rsp and pops
- // a value off the stack into rbp (restoring the caller's rbp value).
- // It is the opposite of ENTER, or 'push rbp, mov rsp rbp'.
+ // The LEAVE instruction moves the value from rbp into rsp and pops a value
+ // off the stack into rbp (restoring the caller's rbp value). It is the
+ // opposite of ENTER, or 'push rbp, mov rsp rbp'.
else if (leave_pattern_p()) {
// We're going to copy the value in rbp into rsp, so re-set the sp offset
- // based on the CFAValue. Also, adjust it to recognize that we're popping
- // the saved rbp value off the stack.
+ // based on the CFAValue. Also, adjust it to recognize that we're
+ // popping the saved rbp value off the stack.
current_sp_bytes_offset_from_cfa = row->GetCFAValue().GetOffset();
current_sp_bytes_offset_from_cfa -= m_wordsize;
row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
@@ -822,12 +815,11 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
UnwindPlan::Row::RegisterLocation regloc;
- // stack_offset for 'movq %r15, -80(%rbp)' will be 80.
- // In the Row, we want to express this as the offset from the CFA. If the
- // frame base
- // is rbp (like the above instruction), the CFA offset for rbp is probably
- // 16. So we
- // want to say that the value is stored at the CFA address - 96.
+ // stack_offset for 'movq %r15, -80(%rbp)' will be 80. In the Row, we
+ // want to express this as the offset from the CFA. If the frame base is
+ // rbp (like the above instruction), the CFA offset for rbp is probably
+ // 16. So we want to say that the value is stored at the CFA address -
+ // 96.
regloc.SetAtCFAPlusOffset(
-(stack_offset + row->GetCFAValue().GetOffset()));
@@ -879,8 +871,8 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
}
else if (ret_pattern_p() && prologue_completed_row.get()) {
- // Reinstate the saved prologue setup for any instructions
- // that come after the ret instruction
+ // Reinstate the saved prologue setup for any instructions that come
+ // after the ret instruction
UnwindPlan::Row *newrow = new UnwindPlan::Row;
*newrow = *prologue_completed_row.get();
@@ -960,16 +952,15 @@ bool x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite(
if (!addr_start.IsValid())
return false;
- // We either need a live RegisterContext, or we need the UnwindPlan to already
- // be in the lldb register numbering scheme.
+ // We either need a live RegisterContext, or we need the UnwindPlan to
+ // already be in the lldb register numbering scheme.
if (reg_ctx.get() == nullptr &&
unwind_plan.GetRegisterKind() != eRegisterKindLLDB)
return false;
// Is original unwind_plan valid?
- // unwind_plan should have at least one row which is ABI-default (CFA register
- // is sp),
- // and another row in mid-function.
+ // unwind_plan should have at least one row which is ABI-default (CFA
+ // register is sp), and another row in mid-function.
if (unwind_plan.GetRowCount() < 2)
return false;
@@ -994,11 +985,9 @@ bool x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite(
UnwindPlan::RowSP row(new UnwindPlan::Row(*first_row));
m_cur_insn = data + offset;
- // After a mid-function epilogue we will need to re-insert the original unwind
- // rules
- // so unwinds work for the remainder of the function. These aren't common
- // with clang/gcc
- // on x86 but it is possible.
+ // After a mid-function epilogue we will need to re-insert the original
+ // unwind rules so unwinds work for the remainder of the function. These
+ // aren't common with clang/gcc on x86 but it is possible.
bool reinstate_unwind_state = false;
while (offset < size) {
@@ -1015,8 +1004,7 @@ bool x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite(
offset += insn_len;
m_cur_insn = data + offset;
- // offset is pointing beyond the bounds of the
- // function; stop looping.
+ // offset is pointing beyond the bounds of the function; stop looping.
if (offset >= size)
continue;
@@ -1044,9 +1032,8 @@ bool x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite(
}
if (row_id == 0) {
- // If we are here, compiler didn't generate CFI for prologue.
- // This won't happen to GCC or clang.
- // In this case, bail out directly.
+ // If we are here, compiler didn't generate CFI for prologue. This won't
+ // happen to GCC or clang. In this case, bail out directly.
return false;
}
@@ -1086,10 +1073,9 @@ bool x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite(
}
if (pop_reg_p(regno)) {
// Technically, this might be a nonvolatile register recover in
- // epilogue.
- // We should reset RegisterInfo for the register.
- // But in practice, previous rule for the register is still valid...
- // So we ignore this case.
+ // epilogue. We should reset RegisterInfo for the register. But in
+ // practice, previous rule for the register is still valid... So we
+ // ignore this case.
row->SetOffset(offset);
row->GetCFAValue().IncOffset(-m_wordsize);
diff --git a/source/Symbol/ArmUnwindInfo.cpp b/source/Symbol/ArmUnwindInfo.cpp
index 4da307bf0c32..6dcad62f2f9d 100644
--- a/source/Symbol/ArmUnwindInfo.cpp
+++ b/source/Symbol/ArmUnwindInfo.cpp
@@ -65,17 +65,16 @@ ArmUnwindInfo::ArmUnwindInfo(ObjectFile &objfile, SectionSP &arm_exidx,
}
// Sort the entries in the exidx section. The entries should be sorted inside
- // the section but
- // some old compiler isn't sorted them.
+ // the section but some old compiler isn't sorted them.
std::sort(m_exidx_entries.begin(), m_exidx_entries.end());
}
ArmUnwindInfo::~ArmUnwindInfo() {}
-// Read a byte from the unwind instruction stream with the given offset.
-// Custom function is required because have to red in order of significance
-// within their containing
-// word (most significant byte first) and in increasing word address order.
+// Read a byte from the unwind instruction stream with the given offset. Custom
+// function is required because have to red in order of significance within
+// their containing word (most significant byte first) and in increasing word
+// address order.
uint8_t ArmUnwindInfo::GetByteAtOffset(const uint32_t *data,
uint16_t offset) const {
uint32_t value = data[offset / 4];
@@ -276,8 +275,8 @@ bool ArmUnwindInfo::GetUnwindPlan(Target &target, const Address &addr,
return false;
} else if ((byte1 & 0xff) == 0xc8) {
// 11001000 sssscccc
- // Pop VFP double precision registers D[16+ssss]-D[16+ssss+cccc] saved (as
- // if) by FSTMFDD (see remarks d,e)
+ // Pop VFP double precision registers D[16+ssss]-D[16+ssss+cccc] saved
+ // (as if) by FSTMFDD (see remarks d,e)
if (byte_offset >= byte_count)
return false;
diff --git a/source/Symbol/Block.cpp b/source/Symbol/Block.cpp
index 648d8ee48bf5..46f875fca776 100644
--- a/source/Symbol/Block.cpp
+++ b/source/Symbol/Block.cpp
@@ -60,8 +60,7 @@ void Block::Dump(Stream *s, addr_t base_addr, int32_t depth,
if (depth < 0) {
Block *parent = GetParent();
if (parent) {
- // We have a depth that is less than zero, print our parent blocks
- // first
+ // We have a depth that is less than zero, print our parent blocks first
parent->Dump(s, base_addr, depth + 1, show_context);
}
}
diff --git a/source/Symbol/CMakeLists.txt b/source/Symbol/CMakeLists.txt
index 69a2b5a1699c..6f8a8cb9f9f2 100644
--- a/source/Symbol/CMakeLists.txt
+++ b/source/Symbol/CMakeLists.txt
@@ -50,7 +50,6 @@ add_lldb_library(lldbSymbol
lldbPluginExpressionParserGo
lldbPluginSymbolFileDWARF
lldbPluginSymbolFilePDB
- lldbPluginObjectContainerBSDArchive
lldbPluginCPlusPlusLanguage
lldbPluginObjCLanguage
diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp
index 673124cc0de5..95e7f8a68d44 100644
--- a/source/Symbol/ClangASTContext.cpp
+++ b/source/Symbol/ClangASTContext.cpp
@@ -138,8 +138,8 @@ static ClangASTMap &GetASTMap() {
return *g_map_ptr;
}
-static bool IsOperator(const char *name,
- clang::OverloadedOperatorKind &op_kind) {
+bool ClangASTContext::IsOperator(const char *name,
+ clang::OverloadedOperatorKind &op_kind) {
if (name == nullptr || name[0] == '\0')
return false;
@@ -163,8 +163,8 @@ static bool IsOperator(const char *name,
#undef OPERATOR_PREFIX
#undef OPERATOR_PREFIX_LENGTH
- // This is an operator, set the overloaded operator kind to invalid
- // in case this is a conversion operator...
+ // This is an operator, set the overloaded operator kind to invalid in case
+ // this is a conversion operator...
op_kind = clang::NUM_OVERLOADED_OPERATORS;
switch (post_op_name[0]) {
@@ -375,9 +375,9 @@ ClangASTContext::ConvertAccessTypeToAccessSpecifier(AccessType access) {
static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) {
// FIXME: Cleanup per-file based stuff.
- // Set some properties which depend solely on the input kind; it would be nice
- // to move these to the language standard, and have the driver resolve the
- // input kind + language standard.
+ // Set some properties which depend solely on the input kind; it would be
+ // nice to move these to the language standard, and have the driver resolve
+ // the input kind + language standard.
if (IK.getLanguage() == InputKind::Asm) {
Opts.AsmPreprocessor = 1;
} else if (IK.isObjectiveC()) {
@@ -408,6 +408,9 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) {
case InputKind::ObjCXX:
LangStd = LangStandard::lang_gnucxx98;
break;
+ case InputKind::HIP:
+ LangStd = LangStandard::lang_hip;
+ break;
}
}
@@ -437,8 +440,8 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) {
Opts.setValueVisibilityMode(DefaultVisibility);
- // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
- // is specified, or -std is set to a conforming mode.
+ // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs is
+ // specified, or -std is set to a conforming mode.
Opts.Trigraphs = !Opts.GNUMode;
Opts.CharIsSigned = ArchSpec(triple).CharIsSignedByDefault();
Opts.OptimizeSize = 0;
@@ -659,8 +662,8 @@ ASTContext *ClangASTContext::getASTContext() {
m_ast_ap->getDiagnostics().setClient(getDiagnosticConsumer(), false);
// This can be NULL if we don't know anything about the architecture or if
- // the
- // target for an architecture isn't enabled in the llvm/clang that we built
+ // the target for an architecture isn't enabled in the llvm/clang that we
+ // built
TargetInfo *target_info = getTargetInfo();
if (target_info)
m_ast_ap->InitBuiltinTypes(*target_info);
@@ -1251,8 +1254,8 @@ CompilerType ClangASTContext::GetTypeForDecl(clang::NamedDecl *decl) {
}
CompilerType ClangASTContext::GetTypeForDecl(TagDecl *decl) {
- // No need to call the getASTContext() accessor (which can create the AST
- // if it isn't created yet, because we can't have created a decl in this
+ // No need to call the getASTContext() accessor (which can create the AST if
+ // it isn't created yet, because we can't have created a decl in this
// AST if our AST didn't already exist...
ASTContext *ast = &decl->getASTContext();
if (ast)
@@ -1261,8 +1264,8 @@ CompilerType ClangASTContext::GetTypeForDecl(TagDecl *decl) {
}
CompilerType ClangASTContext::GetTypeForDecl(ObjCInterfaceDecl *decl) {
- // No need to call the getASTContext() accessor (which can create the AST
- // if it isn't created yet, because we can't have created a decl in this
+ // No need to call the getASTContext() accessor (which can create the AST if
+ // it isn't created yet, because we can't have created a decl in this
// AST if our AST didn't already exist...
ASTContext *ast = &decl->getASTContext();
if (ast)
@@ -1291,9 +1294,9 @@ CompilerType ClangASTContext::CreateRecordType(DeclContext *decl_ctx,
}
// NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
- // we will need to update this code. I was told to currently always use
- // the CXXRecordDecl class since we often don't know from debug information
- // if something is struct or a class, so we default to always use the more
+ // we will need to update this code. I was told to currently always use the
+ // CXXRecordDecl class since we often don't know from debug information if
+ // something is struct or a class, so we default to always use the more
// complete definition just in case.
bool is_anonymous = (!name) || (!name[0]);
@@ -1388,7 +1391,7 @@ static TemplateParameterList *CreateTemplateParameterList(
clang::FunctionTemplateDecl *ClangASTContext::CreateFunctionTemplateDecl(
clang::DeclContext *decl_ctx, clang::FunctionDecl *func_decl,
const char *name, const TemplateParameterInfos &template_param_infos) {
- // /// \brief Create a function template node.
+ // /// Create a function template node.
ASTContext *ast = getASTContext();
llvm::SmallVector<NamedDecl *, 8> template_param_decls;
@@ -1482,6 +1485,29 @@ ClassTemplateDecl *ClangASTContext::CreateClassTemplateDecl(
return class_template_decl;
}
+TemplateTemplateParmDecl *
+ClangASTContext::CreateTemplateTemplateParmDecl(const char *template_name) {
+ ASTContext *ast = getASTContext();
+
+ auto *decl_ctx = ast->getTranslationUnitDecl();
+
+ IdentifierInfo &identifier_info = ast->Idents.get(template_name);
+ llvm::SmallVector<NamedDecl *, 8> template_param_decls;
+
+ ClangASTContext::TemplateParameterInfos template_param_infos;
+ TemplateParameterList *template_param_list = CreateTemplateParameterList(
+ ast, template_param_infos, template_param_decls);
+
+ // LLDB needs to create those decls only to be able to display a
+ // type that includes a template template argument. Only the name matters for
+ // this purpose, so we use dummy values for the other characterisitcs of the
+ // type.
+ return TemplateTemplateParmDecl::Create(
+ *ast, decl_ctx, SourceLocation(),
+ /*Depth*/ 0, /*Position*/ 0,
+ /*IsParameterPack*/ false, &identifier_info, template_param_list);
+}
+
ClassTemplateSpecializationDecl *
ClangASTContext::CreateClassTemplateSpecializationDecl(
DeclContext *decl_ctx, ClassTemplateDecl *class_template_decl, int kind,
@@ -1623,7 +1649,7 @@ bool ClangASTContext::RecordHasFields(const RecordDecl *record_decl) {
return false;
}
-#pragma mark Objective C Classes
+#pragma mark Objective-C Classes
CompilerType ClangASTContext::CreateObjCClass(const char *name,
DeclContext *decl_ctx,
@@ -1907,11 +1933,10 @@ ClangASTContext::GetDeclarationName(const char *name,
return DeclarationName(&getASTContext()->Idents.get(
name)); // Not operator, but a regular function.
- // Check the number of operator parameters. Sometimes we have
- // seen bad DWARF that doesn't correctly describe operators and
- // if we try to create a method and add it to the class, clang
- // will assert and crash, so we need to make sure things are
- // acceptable.
+ // Check the number of operator parameters. Sometimes we have seen bad DWARF
+ // that doesn't correctly describe operators and if we try to create a method
+ // and add it to the class, clang will assert and crash, so we need to make
+ // sure things are acceptable.
clang::QualType method_qual_type(ClangUtil::GetQualType(function_clang_type));
const clang::FunctionProtoType *function_type =
llvm::dyn_cast<clang::FunctionProtoType>(method_qual_type.getTypePtr());
@@ -2121,51 +2146,6 @@ ClangASTContext::CreateEnumerationType(const char *name, DeclContext *decl_ctx,
return CompilerType();
}
-// Disable this for now since I can't seem to get a nicely formatted float
-// out of the APFloat class without just getting the float, double or quad
-// and then using a formatted print on it which defeats the purpose. We ideally
-// would like to get perfect string values for any kind of float semantics
-// so we can support remote targets. The code below also requires a patch to
-// llvm::APInt.
-// bool
-// ClangASTContext::ConvertFloatValueToString (ASTContext *ast,
-// lldb::opaque_compiler_type_t clang_type, const uint8_t* bytes, size_t
-// byte_size, int apint_byte_order, std::string &float_str)
-//{
-// uint32_t count = 0;
-// bool is_complex = false;
-// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
-// {
-// unsigned num_bytes_per_float = byte_size / count;
-// unsigned num_bits_per_float = num_bytes_per_float * 8;
-//
-// float_str.clear();
-// uint32_t i;
-// for (i=0; i<count; i++)
-// {
-// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float,
-// (APInt::ByteOrder)apint_byte_order);
-// bool is_ieee = false;
-// APFloat ap_float(ap_int, is_ieee);
-// char s[1024];
-// unsigned int hex_digits = 0;
-// bool upper_case = false;
-//
-// if (ap_float.convertToHexString(s, hex_digits, upper_case,
-// APFloat::rmNearestTiesToEven) > 0)
-// {
-// if (i > 0)
-// float_str.append(", ");
-// float_str.append(s);
-// if (i == 1 && is_complex)
-// float_str.append(1, 'i');
-// }
-// }
-// return !float_str.empty();
-// }
-// return false;
-//}
-
CompilerType ClangASTContext::GetIntTypeFromBitSize(clang::ASTContext *ast,
size_t bit_size,
bool is_signed) {
@@ -2266,8 +2246,8 @@ bool ClangASTContext::DeclsAreEquivalent(clang::Decl *lhs_decl,
if (lhs_decl_kind == rhs_decl_kind) {
//------------------------------------------------------------------
- // Now check that the decl contexts kinds are all equivalent
- // before we have to check any names of the decl contexts...
+ // Now check that the decl contexts kinds are all equivalent before we
+ // have to check any names of the decl contexts...
//------------------------------------------------------------------
clang::DeclContext *lhs_decl_ctx = lhs_decl->getDeclContext();
clang::DeclContext *rhs_decl_ctx = rhs_decl->getDeclContext();
@@ -2309,8 +2289,8 @@ bool ClangASTContext::DeclsAreEquivalent(clang::Decl *lhs_decl,
return false;
//--------------------------------------------------------------
- // We know that the decl context kinds all match, so now we need
- // to make sure the names match as well
+ // We know that the decl context kinds all match, so now we need to
+ // make sure the names match as well
//--------------------------------------------------------------
lhs_decl_ctx = lhs_decl->getDeclContext();
rhs_decl_ctx = rhs_decl->getDeclContext();
@@ -2580,8 +2560,7 @@ static bool GetCompleteQualType(clang::ASTContext *ast,
clang::ObjCInterfaceDecl *class_interface_decl =
objc_class_type->getInterface();
// We currently can't complete objective C types through the newly added
- // ASTContext
- // because it only supports TagDecl objects right now...
+ // ASTContext because it only supports TagDecl objects right now...
if (class_interface_decl) {
if (class_interface_decl->getDefinition())
return true;
@@ -2901,8 +2880,8 @@ bool ClangASTContext::IsCStringType(lldb::opaque_compiler_type_t type,
if (type_flags.AnySet(eTypeIsArray | eTypeIsPointer)) {
if (pointee_or_element_clang_type.IsCharType()) {
if (type_flags.Test(eTypeIsArray)) {
- // We know the size of the array and it could be a C string
- // since it is an array of characters
+ // We know the size of the array and it could be a C string since it is
+ // an array of characters
length = llvm::cast<clang::ConstantArrayType>(
GetCanonicalQualType(type).getTypePtr())
->getSize()
@@ -3642,9 +3621,8 @@ bool ClangASTContext::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
if (success) {
// Check to make sure what we are pointing too is a possible dynamic C++
- // type
- // We currently accept any "void *" (in case we have a class that has been
- // watered down to an opaque pointer) and virtual C++ classes.
+ // type We currently accept any "void *" (in case we have a class that
+ // has been watered down to an opaque pointer) and virtual C++ classes.
const clang::Type::TypeClass pointee_type_class =
pointee_qual_type.getCanonicalType()->getTypeClass();
switch (pointee_type_class) {
@@ -3964,7 +3942,10 @@ ClangASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type,
case clang::Type::DependentTemplateSpecialization:
return eTypeIsTemplate;
case clang::Type::Decltype:
- return 0;
+ return CompilerType(
+ getASTContext(),
+ llvm::cast<clang::DecltypeType>(qual_type)->getUnderlyingType())
+ .GetTypeInfo(pointee_or_element_clang_type);
case clang::Type::Enum:
if (pointee_or_element_clang_type)
@@ -4046,9 +4027,16 @@ ClangASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type,
->getUnderlyingType())
.GetTypeInfo(pointee_or_element_clang_type);
case clang::Type::TypeOfExpr:
- return 0;
+ return CompilerType(getASTContext(),
+ llvm::cast<clang::TypeOfExprType>(qual_type)
+ ->getUnderlyingExpr()
+ ->getType())
+ .GetTypeInfo(pointee_or_element_clang_type);
case clang::Type::TypeOf:
- return 0;
+ return CompilerType(
+ getASTContext(),
+ llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType())
+ .GetTypeInfo(pointee_or_element_clang_type);
case clang::Type::UnresolvedUsing:
return 0;
@@ -4178,6 +4166,8 @@ ClangASTContext::GetTypeClass(lldb::opaque_compiler_type_t type) {
return lldb::eTypeClassArray;
case clang::Type::DependentSizedExtVector:
return lldb::eTypeClassVector;
+ case clang::Type::DependentVector:
+ return lldb::eTypeClassVector;
case clang::Type::ExtVector:
return lldb::eTypeClassVector;
case clang::Type::Vector:
@@ -4255,11 +4245,21 @@ ClangASTContext::GetTypeClass(lldb::opaque_compiler_type_t type) {
break;
case clang::Type::TypeOfExpr:
- break;
+ return CompilerType(getASTContext(),
+ llvm::cast<clang::TypeOfExprType>(qual_type)
+ ->getUnderlyingExpr()
+ ->getType())
+ .GetTypeClass();
case clang::Type::TypeOf:
- break;
+ return CompilerType(
+ getASTContext(),
+ llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType())
+ .GetTypeClass();
case clang::Type::Decltype:
- break;
+ return CompilerType(
+ getASTContext(),
+ llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType())
+ .GetTypeClass();
case clang::Type::TemplateSpecialization:
break;
case clang::Type::DeducedTemplateSpecialization:
@@ -4776,9 +4776,8 @@ ClangASTContext::CreateTypedef(lldb::opaque_compiler_type_t type,
}
// Check whether this declaration is an anonymous struct, union, or enum,
- // hidden behind a typedef. If so, we
- // try to check whether we have a typedef tag to attach to the original
- // record declaration
+ // hidden behind a typedef. If so, we try to check whether we have a
+ // typedef tag to attach to the original record declaration
if (tdecl && !tdecl->getIdentifier() && !tdecl->getTypedefNameForAnonDecl())
tdecl->setTypedefNameForAnonDecl(decl);
@@ -4903,6 +4902,7 @@ lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
case clang::Type::ConstantArray:
break;
+ case clang::Type::DependentVector:
case clang::Type::ExtVector:
case clang::Type::Vector:
// TODO: Set this to more than one???
@@ -4917,8 +4917,6 @@ lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
case clang::BuiltinType::Char_S:
case clang::BuiltinType::SChar:
case clang::BuiltinType::WChar_S:
- case clang::BuiltinType::Char16:
- case clang::BuiltinType::Char32:
case clang::BuiltinType::Short:
case clang::BuiltinType::Int:
case clang::BuiltinType::Long:
@@ -4929,6 +4927,9 @@ lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
case clang::BuiltinType::Char_U:
case clang::BuiltinType::UChar:
case clang::BuiltinType::WChar_U:
+ case clang::BuiltinType::Char8:
+ case clang::BuiltinType::Char16:
+ case clang::BuiltinType::Char32:
case clang::BuiltinType::UShort:
case clang::BuiltinType::UInt:
case clang::BuiltinType::ULong:
@@ -4936,6 +4937,33 @@ lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
case clang::BuiltinType::UInt128:
return lldb::eEncodingUint;
+ // Fixed point types. Note that they are currently ignored.
+ case clang::BuiltinType::ShortAccum:
+ case clang::BuiltinType::Accum:
+ case clang::BuiltinType::LongAccum:
+ case clang::BuiltinType::UShortAccum:
+ case clang::BuiltinType::UAccum:
+ case clang::BuiltinType::ULongAccum:
+ case clang::BuiltinType::ShortFract:
+ case clang::BuiltinType::Fract:
+ case clang::BuiltinType::LongFract:
+ case clang::BuiltinType::UShortFract:
+ case clang::BuiltinType::UFract:
+ case clang::BuiltinType::ULongFract:
+ case clang::BuiltinType::SatShortAccum:
+ case clang::BuiltinType::SatAccum:
+ case clang::BuiltinType::SatLongAccum:
+ case clang::BuiltinType::SatUShortAccum:
+ case clang::BuiltinType::SatUAccum:
+ case clang::BuiltinType::SatULongAccum:
+ case clang::BuiltinType::SatShortFract:
+ case clang::BuiltinType::SatFract:
+ case clang::BuiltinType::SatLongFract:
+ case clang::BuiltinType::SatUShortFract:
+ case clang::BuiltinType::SatUFract:
+ case clang::BuiltinType::SatULongFract:
+ break;
+
case clang::BuiltinType::Half:
case clang::BuiltinType::Float:
case clang::BuiltinType::Float16:
@@ -5004,9 +5032,8 @@ lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
break;
}
break;
- // All pointer types are represented as unsigned integer encodings.
- // We may nee to add a eEncodingPointer if we ever need to know the
- // difference
+ // All pointer types are represented as unsigned integer encodings. We may
+ // nee to add a eEncodingPointer if we ever need to know the difference
case clang::Type::ObjCObjectPointer:
case clang::Type::BlockPointer:
case clang::Type::Pointer:
@@ -5060,7 +5087,22 @@ lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
return CompilerType(getASTContext(),
llvm::cast<clang::ParenType>(qual_type)->desugar())
.GetEncoding(count);
-
+ case clang::Type::TypeOfExpr:
+ return CompilerType(getASTContext(),
+ llvm::cast<clang::TypeOfExprType>(qual_type)
+ ->getUnderlyingExpr()
+ ->getType())
+ .GetEncoding(count);
+ case clang::Type::TypeOf:
+ return CompilerType(
+ getASTContext(),
+ llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType())
+ .GetEncoding(count);
+ case clang::Type::Decltype:
+ return CompilerType(
+ getASTContext(),
+ llvm::cast<clang::DecltypeType>(qual_type)->getUnderlyingType())
+ .GetEncoding(count);
case clang::Type::DependentSizedArray:
case clang::Type::DependentSizedExtVector:
case clang::Type::UnresolvedUsing:
@@ -5074,9 +5116,6 @@ lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
case clang::Type::PackExpansion:
case clang::Type::ObjCObject:
- case clang::Type::TypeOfExpr:
- case clang::Type::TypeOf:
- case clang::Type::Decltype:
case clang::Type::TemplateSpecialization:
case clang::Type::DeducedTemplateSpecialization:
case clang::Type::Atomic:
@@ -5118,6 +5157,7 @@ lldb::Format ClangASTContext::GetFormat(lldb::opaque_compiler_type_t type) {
case clang::Type::ConstantArray:
return lldb::eFormatVoid; // no value
+ case clang::Type::DependentVector:
case clang::Type::ExtVector:
case clang::Type::Vector:
break;
@@ -5214,6 +5254,22 @@ lldb::Format ClangASTContext::GetFormat(lldb::opaque_compiler_type_t type) {
getASTContext(),
llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
.GetFormat();
+ case clang::Type::TypeOfExpr:
+ return CompilerType(getASTContext(),
+ llvm::cast<clang::TypeOfExprType>(qual_type)
+ ->getUnderlyingExpr()
+ ->getType())
+ .GetFormat();
+ case clang::Type::TypeOf:
+ return CompilerType(
+ getASTContext(),
+ llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType())
+ .GetFormat();
+ case clang::Type::Decltype:
+ return CompilerType(
+ getASTContext(),
+ llvm::cast<clang::DecltypeType>(qual_type)->getUnderlyingType())
+ .GetFormat();
case clang::Type::DependentSizedArray:
case clang::Type::DependentSizedExtVector:
case clang::Type::UnresolvedUsing:
@@ -5227,9 +5283,6 @@ lldb::Format ClangASTContext::GetFormat(lldb::opaque_compiler_type_t type) {
case clang::Type::PackExpansion:
case clang::Type::ObjCObject:
- case clang::Type::TypeOfExpr:
- case clang::Type::TypeOf:
- case clang::Type::Decltype:
case clang::Type::TemplateSpecialization:
case clang::Type::DeducedTemplateSpecialization:
case clang::Type::Atomic:
@@ -5298,10 +5351,9 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
if (cxx_record_decl) {
if (omit_empty_base_classes) {
- // Check each base classes to see if it or any of its
- // base classes contain any fields. This can help
- // limit the noise in variable views by not having to
- // show base classes that contain no members.
+ // Check each base classes to see if it or any of its base classes
+ // contain any fields. This can help limit the noise in variable
+ // views by not having to show base classes that contain no members.
clang::CXXRecordDecl::base_class_const_iterator base_class,
base_class_end;
for (base_class = cxx_record_decl->bases_begin(),
@@ -5394,8 +5446,8 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
CompilerType(getASTContext(), pointee_type)
.GetNumChildren(omit_empty_base_classes);
if (num_pointee_children == 0) {
- // We have a pointer to a pointee type that claims it has no children.
- // We will want to look at
+ // We have a pointer to a pointee type that claims it has no children. We
+ // will want to look at
num_children = GetNumPointeeChildren(pointee_type);
} else
num_children = num_pointee_children;
@@ -6264,11 +6316,15 @@ uint32_t ClangASTContext::GetNumPointeeChildren(clang::QualType type) {
return GetNumPointeeChildren(
llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType());
case clang::Type::TypeOfExpr:
- return 0;
+ return GetNumPointeeChildren(llvm::cast<clang::TypeOfExprType>(qual_type)
+ ->getUnderlyingExpr()
+ ->getType());
case clang::Type::TypeOf:
- return 0;
+ return GetNumPointeeChildren(
+ llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType());
case clang::Type::Decltype:
- return 0;
+ return GetNumPointeeChildren(
+ llvm::cast<clang::DecltypeType>(qual_type)->getUnderlyingType());
case clang::Type::Record:
return 0;
case clang::Type::Enum:
@@ -6585,15 +6641,12 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
child_byte_size = ivar_type_info.Width / 8;
// Figure out the field offset within the current
- // struct/union/class type
- // For ObjC objects, we can't trust the bit offset we get from
- // the Clang AST, since
- // that doesn't account for the space taken up by unbacked
- // properties, or from
- // the changing size of base classes that are newer than this
- // class.
- // So if we have a process around that we can ask about this
- // object, do so.
+ // struct/union/class type For ObjC objects, we can't trust the
+ // bit offset we get from the Clang AST, since that doesn't
+ // account for the space taken up by unbacked properties, or
+ // from the changing size of base classes that are newer than
+ // this class. So if we have a process around that we can ask
+ // about this object, do so.
child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
Process *process = nullptr;
if (exe_ctx)
@@ -6621,9 +6674,8 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
}
// Note, the ObjC Ivar Byte offset is just that, it doesn't
- // account for the bit offset
- // of a bitfield within its containing object. So regardless of
- // where we get the byte
+ // account for the bit offset of a bitfield within its
+ // containing object. So regardless of where we get the byte
// offset from, we still need to get the bit offset for
// bitfields from the layout.
@@ -6895,8 +6947,8 @@ static uint32_t GetIndexForRecordChild(const clang::RecordDecl *record_decl,
}
// Look for a child member (doesn't include base classes, but it does include
-// their members) in the type hierarchy. Returns an index path into "clang_type"
-// on how to reach the appropriate member.
+// their members) in the type hierarchy. Returns an index path into
+// "clang_type" on how to reach the appropriate member.
//
// class A
// {
@@ -6919,16 +6971,13 @@ static uint32_t GetIndexForRecordChild(const clang::RecordDecl *record_decl,
// "m_b" in it:
//
// With omit_empty_base_classes == false we would get an integer array back
-// with:
-// { 1, 1 }
-// The first index 1 is the child index for "class A" within class C
-// The second index 1 is the child index for "m_b" within class A
+// with: { 1, 1 } The first index 1 is the child index for "class A" within
+// class C The second index 1 is the child index for "m_b" within class A
//
-// With omit_empty_base_classes == true we would get an integer array back with:
-// { 0, 1 }
-// The first index 0 is the child index for "class A" within class C (since
-// class B doesn't have any members it doesn't count)
-// The second index 1 is the child index for "m_b" within class A
+// With omit_empty_base_classes == true we would get an integer array back
+// with: { 0, 1 } The first index 0 is the child index for "class A" within
+// class C (since class B doesn't have any members it doesn't count) The second
+// index 1 is the child index for "m_b" within class A
size_t ClangASTContext::GetIndexOfChildMemberWithName(
lldb::opaque_compiler_type_t type, const char *name,
@@ -7063,9 +7112,9 @@ size_t ClangASTContext::GetIndexOfChildMemberWithName(
}
if (superclass_interface_decl) {
- // The super class index is always zero for ObjC classes,
- // so we push it onto the child indexes in case we find
- // an ivar in our superclass...
+ // The super class index is always zero for ObjC classes, so we
+ // push it onto the child indexes in case we find an ivar in our
+ // superclass...
child_indexes.push_back(0);
CompilerType superclass_clang_type(
@@ -7073,14 +7122,13 @@ size_t ClangASTContext::GetIndexOfChildMemberWithName(
superclass_interface_decl));
if (superclass_clang_type.GetIndexOfChildMemberWithName(
name, omit_empty_base_classes, child_indexes)) {
- // We did find an ivar in a superclass so just
- // return the results!
+ // We did find an ivar in a superclass so just return the
+ // results!
return child_indexes.size();
}
- // We didn't find an ivar matching "name" in our
- // superclass, pop the superclass zero index that
- // we pushed on above.
+ // We didn't find an ivar matching "name" in our superclass, pop
+ // the superclass zero index that we pushed on above.
child_indexes.pop_back();
}
}
@@ -7673,8 +7721,8 @@ clang::FieldDecl *ClangASTContext::AddFieldToRecordType(
clang::ICIS_NoInit); // HasInit
if (!name) {
- // Determine whether this field corresponds to an anonymous
- // struct or union.
+ // Determine whether this field corresponds to an anonymous struct or
+ // union.
if (const clang::TagType *TagT =
field->getType()->getAs<clang::TagType>()) {
if (clang::RecordDecl *Rec =
@@ -7818,8 +7866,8 @@ void ClangASTContext::BuildIndirectFields(const CompilerType &type) {
}
}
- // Check the last field to see if it has an incomplete array type as its
- // last member and if it does, the tell the record decl about it
+ // Check the last field to see if it has an incomplete array type as its last
+ // member and if it does, the tell the record decl about it
if (last_field_pos != field_end_pos) {
if (last_field_pos->getType()->isIncompleteArrayType())
record_decl->hasFlexibleArrayMember();
@@ -7885,7 +7933,7 @@ clang::VarDecl *ClangASTContext::AddVariableToRecordType(
}
clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType(
- lldb::opaque_compiler_type_t type, const char *name,
+ lldb::opaque_compiler_type_t type, const char *name, const char *mangled_name,
const CompilerType &method_clang_type, lldb::AccessType access,
bool is_virtual, bool is_static, bool is_inline, bool is_explicit,
bool is_attr_used, bool is_artificial) {
@@ -7953,11 +8001,10 @@ clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType(
if (IsOperator(name, op_kind)) {
if (op_kind != clang::NUM_OVERLOADED_OPERATORS) {
- // Check the number of operator parameters. Sometimes we have
- // seen bad DWARF that doesn't correctly describe operators and
- // if we try to create a method and add it to the class, clang
- // will assert and crash, so we need to make sure things are
- // acceptable.
+ // Check the number of operator parameters. Sometimes we have seen bad
+ // DWARF that doesn't correctly describe operators and if we try to
+ // create a method and add it to the class, clang will assert and
+ // crash, so we need to make sure things are acceptable.
const bool is_method = true;
if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount(
is_method, op_kind, num_params))
@@ -8005,6 +8052,11 @@ clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType(
if (is_attr_used)
cxx_method_decl->addAttr(clang::UsedAttr::CreateImplicit(*getASTContext()));
+ if (mangled_name != NULL) {
+ cxx_method_decl->addAttr(
+ clang::AsmLabelAttr::CreateImplicit(*getASTContext(), mangled_name));
+ }
+
// Populate the method decl with parameter decls
llvm::SmallVector<clang::ParmVarDecl *, 12> params;
@@ -8632,8 +8684,8 @@ bool ClangASTContext::CompleteTagDeclarationDefinition(
clang::QualType qual_type(ClangUtil::GetQualType(type));
if (!qual_type.isNull()) {
// Make sure we use the same methodology as
- // ClangASTContext::StartTagDeclarationDefinition()
- // as to how we start/end the definition. Previously we were calling
+ // ClangASTContext::StartTagDeclarationDefinition() as to how we start/end
+ // the definition. Previously we were calling
const clang::TagType *tag_type = qual_type->getAs<clang::TagType>();
if (tag_type) {
clang::TagDecl *tag_decl = tag_type->getDecl();
@@ -8903,9 +8955,8 @@ void ClangASTContext::DumpValue(
for (field = record_decl->field_begin(),
field_end = record_decl->field_end();
field != field_end; ++field, ++field_idx, ++child_idx) {
- // Print the starting squiggly bracket (if this is the
- // first member) or comma (for member 2 and beyond) for
- // the struct/union/class member.
+ // Print the starting squiggly bracket (if this is the first member) or
+ // comma (for member 2 and beyond) for the struct/union/class member.
if (child_idx == 0)
s->PutChar('{');
else
@@ -8916,8 +8967,8 @@ void ClangASTContext::DumpValue(
clang::QualType field_type = field->getType();
// Print the member type if requested
- // Figure out the type byte size (field_type_info.first) and
- // alignment (field_type_info.second) from the AST context.
+ // Figure out the type byte size (field_type_info.first) and alignment
+ // (field_type_info.second) from the AST context.
clang::TypeInfo field_type_info =
getASTContext()->getTypeInfo(field_type);
assert(field_idx < record_layout.getFieldCount());
@@ -8988,8 +9039,8 @@ void ClangASTContext::DumpValue(
return;
}
}
- // If we have gotten here we didn't get find the enumerator in the
- // enum decl, so just print the integer.
+ // If we have gotten here we didn't get find the enumerator in the enum
+ // decl, so just print the integer.
s->Printf("%" PRIi64, enum_value);
}
return;
@@ -9027,9 +9078,8 @@ void ClangASTContext::DumpValue(
lldb::Format element_format = element_clang_type.GetFormat();
for (element_idx = 0; element_idx < element_count; ++element_idx) {
- // Print the starting squiggly bracket (if this is the
- // first member) or comman (for member 2 and beyong) for
- // the struct/union/class member.
+ // Print the starting squiggly bracket (if this is the first member) or
+ // comman (for member 2 and beyong) for the struct/union/class member.
if (element_idx == 0)
s->PutChar('{');
else
@@ -9225,8 +9275,8 @@ bool ClangASTContext::DumpTypeValue(
} break;
case clang::Type::Enum:
- // If our format is enum or default, show the enumeration value as
- // its enumeration string value, else just display it as requested.
+ // If our format is enum or default, show the enumeration value as its
+ // enumeration string value, else just display it as requested.
if ((format == eFormatEnum || format == eFormatDefault) &&
GetCompleteType(type)) {
const clang::EnumType *enutype =
@@ -9518,9 +9568,9 @@ void ClangASTContext::DumpTypeName(const CompilerType &type) {
if (objc_class_type) {
clang::ObjCInterfaceDecl *class_interface_decl =
objc_class_type->getInterface();
- // We currently can't complete objective C types through the newly added
- // ASTContext
- // because it only supports TagDecl objects right now...
+ // We currently can't complete objective C types through the newly
+ // added ASTContext because it only supports TagDecl objects right
+ // now...
if (class_interface_decl)
printf("@class %s", class_interface_decl->getName().str().c_str());
}
@@ -9778,15 +9828,12 @@ std::vector<CompilerDecl> ClangASTContext::DeclContextFindDeclByName(
// Look for child_decl_ctx's lookup scope in frame_decl_ctx and its parents,
// and return the number of levels it took to find it, or
-// LLDB_INVALID_DECL_LEVEL
-// if not found. If the decl was imported via a using declaration, its name
-// and/or
-// type, if set, will be used to check that the decl found in the scope is a
-// match.
+// LLDB_INVALID_DECL_LEVEL if not found. If the decl was imported via a using
+// declaration, its name and/or type, if set, will be used to check that the
+// decl found in the scope is a match.
//
// The optional name is required by languages (like C++) to handle using
-// declarations
-// like:
+// declarations like:
//
// void poo();
// namespace ns {
@@ -9815,14 +9862,10 @@ std::vector<CompilerDecl> ClangASTContext::DeclContextFindDeclByName(
//
// NOTE: Because file statics are at the TranslationUnit along with globals, a
// function at file scope will return the same level as a function at global
-// scope.
-// Ideally we'd like to treat the file scope as an additional scope just below
-// the
-// global scope. More work needs to be done to recognise that, if the decl
-// we're
-// trying to look up is static, we should compare its source file with that of
-// the
-// current scope and return a lower number for it.
+// scope. Ideally we'd like to treat the file scope as an additional scope just
+// below the global scope. More work needs to be done to recognise that, if
+// the decl we're trying to look up is static, we should compare its source
+// file with that of the current scope and return a lower number for it.
uint32_t ClangASTContext::CountDeclLevels(clang::DeclContext *frame_decl_ctx,
clang::DeclContext *child_decl_ctx,
ConstString *child_name,
@@ -9851,10 +9894,8 @@ uint32_t ClangASTContext::CountDeclLevels(clang::DeclContext *frame_decl_ctx,
continue;
// Currently DWARF has one shared translation unit for all Decls at top
- // level, so this
- // would erroneously find using statements anywhere. So don't look at
- // the top-level
- // translation unit.
+ // level, so this would erroneously find using statements anywhere. So
+ // don't look at the top-level translation unit.
// TODO fix this and add a testcase that depends on it.
if (llvm::isa<clang::TranslationUnitDecl>(it->second))
@@ -10086,4 +10127,3 @@ ClangASTContextForExpressions::GetMergerUnchecked() {
lldbassert(m_scratch_ast_source_ap != nullptr);
return m_scratch_ast_source_ap->GetMergerUnchecked();
}
-
diff --git a/source/Symbol/ClangASTImporter.cpp b/source/Symbol/ClangASTImporter.cpp
index 72ccaed43eaa..ea3b141c9e74 100644
--- a/source/Symbol/ClangASTImporter.cpp
+++ b/source/Symbol/ClangASTImporter.cpp
@@ -354,8 +354,7 @@ bool ClangASTImporter::CanImport(const CompilerType &type) {
clang::ObjCInterfaceDecl *class_interface_decl =
objc_class_type->getInterface();
// We currently can't complete objective C types through the newly added
- // ASTContext
- // because it only supports TagDecl objects right now...
+ // ASTContext because it only supports TagDecl objects right now...
if (class_interface_decl) {
if (ResolveDeclOrigin(class_interface_decl, NULL, NULL))
return true;
@@ -431,8 +430,7 @@ bool ClangASTImporter::Import(const CompilerType &type) {
clang::ObjCInterfaceDecl *class_interface_decl =
objc_class_type->getInterface();
// We currently can't complete objective C types through the newly added
- // ASTContext
- // because it only supports TagDecl objects right now...
+ // ASTContext because it only supports TagDecl objects right now...
if (class_interface_decl) {
if (ResolveDeclOrigin(class_interface_decl, NULL, NULL))
return CompleteAndFetchChildren(qual_type);
@@ -896,9 +894,9 @@ void ClangASTImporter::Minion::ImportDefinitionTo(clang::Decl *to,
}
}
- // If we're dealing with an Objective-C class, ensure that the inheritance has
- // been set up correctly. The ASTImporter may not do this correctly if the
- // class was originally sourced from symbols.
+ // If we're dealing with an Objective-C class, ensure that the inheritance
+ // has been set up correctly. The ASTImporter may not do this correctly if
+ // the class was originally sourced from symbols.
if (ObjCInterfaceDecl *to_objc_interface = dyn_cast<ObjCInterfaceDecl>(to)) {
do {
diff --git a/source/Symbol/CompactUnwindInfo.cpp b/source/Symbol/CompactUnwindInfo.cpp
index df71b17c09d0..7dda877582cc 100644
--- a/source/Symbol/CompactUnwindInfo.cpp
+++ b/source/Symbol/CompactUnwindInfo.cpp
@@ -262,8 +262,7 @@ void CompactUnwindInfo::ScanIndex(const ProcessSP &process_sp) {
if (m_unwindinfo_data_computed == false) {
if (m_section_sp->IsEncrypted()) {
// Can't get section contents of a protected/encrypted section until we
- // have a live
- // process and can read them out of memory.
+ // have a live process and can read them out of memory.
if (process_sp.get() == nullptr)
return;
m_section_contents_if_encrypted.reset(
@@ -329,11 +328,10 @@ void CompactUnwindInfo::ScanIndex(const ProcessSP &process_sp) {
return;
}
- // Parse the basic information from the indexes
- // We wait to scan the second level page info until it's needed
+ // Parse the basic information from the indexes We wait to scan the second
+ // level page info until it's needed
- // struct unwind_info_section_header_index_entry
- // {
+ // struct unwind_info_section_header_index_entry {
// uint32_t functionOffset;
// uint32_t secondLevelPagesSectionOffset;
// uint32_t lsdaIndexArraySectionOffset;
@@ -388,8 +386,7 @@ void CompactUnwindInfo::ScanIndex(const ProcessSP &process_sp) {
uint32_t CompactUnwindInfo::GetLSDAForFunctionOffset(uint32_t lsda_offset,
uint32_t lsda_count,
uint32_t function_offset) {
- // struct unwind_info_section_header_lsda_index_entry
- // {
+ // struct unwind_info_section_header_lsda_index_entry {
// uint32_t functionOffset;
// uint32_t lsdaOffset;
// };
@@ -419,8 +416,7 @@ lldb::offset_t CompactUnwindInfo::BinarySearchRegularSecondPage(
uint32_t entry_page_offset, uint32_t entry_count, uint32_t function_offset,
uint32_t *entry_func_start_offset, uint32_t *entry_func_end_offset) {
// typedef uint32_t compact_unwind_encoding_t;
- // struct unwind_info_regular_second_level_entry
- // {
+ // struct unwind_info_regular_second_level_entry {
// uint32_t functionOffset;
// compact_unwind_encoding_t encoding;
@@ -539,9 +535,9 @@ bool CompactUnwindInfo::GetCompactUnwindInfoForFunction(
auto next_it = it + 1;
if (next_it != m_indexes.end()) {
- // initialize the function offset end range to be the start of the
- // next index offset. If we find an entry which is at the end of
- // the index table, this will establish the range end.
+ // initialize the function offset end range to be the start of the next
+ // index offset. If we find an entry which is at the end of the index
+ // table, this will establish the range end.
unwind_info.valid_range_offset_end = next_it->function_offset;
}
@@ -554,15 +550,13 @@ bool CompactUnwindInfo::GetCompactUnwindInfoForFunction(
&offset); // UNWIND_SECOND_LEVEL_REGULAR or UNWIND_SECOND_LEVEL_COMPRESSED
if (kind == UNWIND_SECOND_LEVEL_REGULAR) {
- // struct unwind_info_regular_second_level_page_header
- // {
+ // struct unwind_info_regular_second_level_page_header {
// uint32_t kind; // UNWIND_SECOND_LEVEL_REGULAR
// uint16_t entryPageOffset;
// uint16_t entryCount;
// typedef uint32_t compact_unwind_encoding_t;
- // struct unwind_info_regular_second_level_entry
- // {
+ // struct unwind_info_regular_second_level_entry {
// uint32_t functionOffset;
// compact_unwind_encoding_t encoding;
@@ -612,8 +606,7 @@ bool CompactUnwindInfo::GetCompactUnwindInfoForFunction(
}
return true;
} else if (kind == UNWIND_SECOND_LEVEL_COMPRESSED) {
- // struct unwind_info_compressed_second_level_page_header
- // {
+ // struct unwind_info_compressed_second_level_page_header {
// uint32_t kind; // UNWIND_SECOND_LEVEL_COMPRESSED
// uint16_t entryPageOffset; // offset from this 2nd lvl page
// idx to array of entries
@@ -721,8 +714,8 @@ enum x86_64_eh_regnum {
// enough
};
-// Convert the compact_unwind_info.h register numbering scheme
-// to eRegisterKindEHFrame (eh_frame) register numbering scheme.
+// Convert the compact_unwind_info.h register numbering scheme to
+// eRegisterKindEHFrame (eh_frame) register numbering scheme.
uint32_t translate_to_eh_frame_regnum_x86_64(uint32_t unwind_regno) {
switch (unwind_regno) {
case UNWIND_X86_64_REG_RBX:
@@ -802,9 +795,8 @@ bool CompactUnwindInfo::CreateUnwindPlan_x86_64(Target &target,
case UNWIND_X86_64_MODE_STACK_IND: {
// The clang in Xcode 6 is emitting incorrect compact unwind encodings for
- // this
- // style of unwind. It was fixed in llvm r217020.
- // The clang in Xcode 7 has this fixed.
+ // this style of unwind. It was fixed in llvm r217020. The clang in Xcode
+ // 7 has this fixed.
return false;
} break;
@@ -861,17 +853,17 @@ bool CompactUnwindInfo::CreateUnwindPlan_x86_64(Target &target,
if (register_count > 0) {
- // We need to include (up to) 6 registers in 10 bits.
- // That would be 18 bits if we just used 3 bits per reg to indicate
- // the order they're saved on the stack.
+ // We need to include (up to) 6 registers in 10 bits. That would be 18
+ // bits if we just used 3 bits per reg to indicate the order they're
+ // saved on the stack.
//
// This is done with Lehmer code permutation, e.g. see
- // http://stackoverflow.com/questions/1506078/fast-permutation-number-permutation-mapping-algorithms
+ // http://stackoverflow.com/questions/1506078/fast-permutation-number-
+ // permutation-mapping-algorithms
int permunreg[6] = {0, 0, 0, 0, 0, 0};
- // This decodes the variable-base number in the 10 bits
- // and gives us the Lehmer code sequence which can then
- // be decoded.
+ // This decodes the variable-base number in the 10 bits and gives us the
+ // Lehmer code sequence which can then be decoded.
switch (register_count) {
case 6:
@@ -923,8 +915,8 @@ bool CompactUnwindInfo::CreateUnwindPlan_x86_64(Target &target,
break;
}
- // Decode the Lehmer code for this permutation of
- // the registers v. http://en.wikipedia.org/wiki/Lehmer_code
+ // Decode the Lehmer code for this permutation of the registers v.
+ // http://en.wikipedia.org/wiki/Lehmer_code
int registers[6] = {UNWIND_X86_64_REG_NONE, UNWIND_X86_64_REG_NONE,
UNWIND_X86_64_REG_NONE, UNWIND_X86_64_REG_NONE,
@@ -993,8 +985,8 @@ enum i386_eh_regnum {
// enough
};
-// Convert the compact_unwind_info.h register numbering scheme
-// to eRegisterKindEHFrame (eh_frame) register numbering scheme.
+// Convert the compact_unwind_info.h register numbering scheme to
+// eRegisterKindEHFrame (eh_frame) register numbering scheme.
uint32_t translate_to_eh_frame_regnum_i386(uint32_t unwind_regno) {
switch (unwind_regno) {
case UNWIND_X86_REG_EBX:
@@ -1123,17 +1115,17 @@ bool CompactUnwindInfo::CreateUnwindPlan_i386(Target &target,
if (register_count > 0) {
- // We need to include (up to) 6 registers in 10 bits.
- // That would be 18 bits if we just used 3 bits per reg to indicate
- // the order they're saved on the stack.
+ // We need to include (up to) 6 registers in 10 bits. That would be 18
+ // bits if we just used 3 bits per reg to indicate the order they're
+ // saved on the stack.
//
// This is done with Lehmer code permutation, e.g. see
- // http://stackoverflow.com/questions/1506078/fast-permutation-number-permutation-mapping-algorithms
+ // http://stackoverflow.com/questions/1506078/fast-permutation-number-
+ // permutation-mapping-algorithms
int permunreg[6] = {0, 0, 0, 0, 0, 0};
- // This decodes the variable-base number in the 10 bits
- // and gives us the Lehmer code sequence which can then
- // be decoded.
+ // This decodes the variable-base number in the 10 bits and gives us the
+ // Lehmer code sequence which can then be decoded.
switch (register_count) {
case 6:
@@ -1185,8 +1177,8 @@ bool CompactUnwindInfo::CreateUnwindPlan_i386(Target &target,
break;
}
- // Decode the Lehmer code for this permutation of
- // the registers v. http://en.wikipedia.org/wiki/Lehmer_code
+ // Decode the Lehmer code for this permutation of the registers v.
+ // http://en.wikipedia.org/wiki/Lehmer_code
int registers[6] = {UNWIND_X86_REG_NONE, UNWIND_X86_REG_NONE,
UNWIND_X86_REG_NONE, UNWIND_X86_REG_NONE,
@@ -1260,14 +1252,10 @@ enum arm64_eh_regnum {
pc = 32,
// Compact unwind encodes d8-d15 but we don't have eh_frame / dwarf reg #'s
- // for the 64-bit
- // fp regs. Normally in DWARF it's context sensitive - so it knows it is
- // fetching a
- // 32- or 64-bit quantity from reg v8 to indicate s0 or d0 - but the unwinder
- // is operating
- // at a lower level and we'd try to fetch 128 bits if we were told that v8
- // were stored on
- // the stack...
+ // for the 64-bit fp regs. Normally in DWARF it's context sensitive - so it
+ // knows it is fetching a 32- or 64-bit quantity from reg v8 to indicate s0
+ // or d0 - but the unwinder is operating at a lower level and we'd try to
+ // fetch 128 bits if we were told that v8 were stored on the stack...
v8 = 72,
v9 = 73,
v10 = 74,
diff --git a/source/Symbol/CompileUnit.cpp b/source/Symbol/CompileUnit.cpp
index 8ba83d438803..a4f0d4231e2f 100644
--- a/source/Symbol/CompileUnit.cpp
+++ b/source/Symbol/CompileUnit.cpp
@@ -67,10 +67,10 @@ void CompileUnit::GetDescription(Stream *s,
}
//----------------------------------------------------------------------
-// Dump the current contents of this object. No functions that cause on
-// demand parsing of functions, globals, statics are called, so this
-// is a good function to call to get an idea of the current contents of
-// the CompileUnit object.
+// Dump the current contents of this object. No functions that cause on demand
+// parsing of functions, globals, statics are called, so this is a good
+// function to call to get an idea of the current contents of the CompileUnit
+// object.
//----------------------------------------------------------------------
void CompileUnit::Dump(Stream *s, bool show_context) const {
const char *language = Language::GetNameForLanguageType(m_language);
@@ -118,28 +118,27 @@ FunctionSP CompileUnit::GetFunctionAtIndex(size_t idx) {
}
//----------------------------------------------------------------------
-// Find functions using the Mangled::Tokens token list. This
-// function currently implements an interactive approach designed to find
-// all instances of certain functions. It isn't designed to the
-// quickest way to lookup functions as it will need to iterate through
-// all functions and see if they match, though it does provide a powerful
-// and context sensitive way to search for all functions with a certain
-// name, all functions in a namespace, or all functions of a template
-// type. See Mangled::Tokens::Parse() comments for more information.
+// Find functions using the Mangled::Tokens token list. This function currently
+// implements an interactive approach designed to find all instances of certain
+// functions. It isn't designed to the quickest way to lookup functions as it
+// will need to iterate through all functions and see if they match, though it
+// does provide a powerful and context sensitive way to search for all
+// functions with a certain name, all functions in a namespace, or all
+// functions of a template type. See Mangled::Tokens::Parse() comments for more
+// information.
//
-// The function prototype will need to change to return a list of
-// results. It was originally used to help debug the Mangled class
-// and the Mangled::Tokens::MatchesQuery() function and it currently
-// will print out a list of matching results for the functions that
-// are currently in this compile unit.
+// The function prototype will need to change to return a list of results. It
+// was originally used to help debug the Mangled class and the
+// Mangled::Tokens::MatchesQuery() function and it currently will print out a
+// list of matching results for the functions that are currently in this
+// compile unit.
//
// A FindFunctions method should be called prior to this that takes
-// a regular function name (const char * or ConstString as a parameter)
-// before resorting to this slower but more complete function. The
-// other FindFunctions method should be able to take advantage of any
-// accelerator tables available in the debug information (which is
-// parsed by the SymbolFile parser plug-ins and registered with each
-// Module).
+// a regular function name (const char * or ConstString as a parameter) before
+// resorting to this slower but more complete function. The other FindFunctions
+// method should be able to take advantage of any accelerator tables available
+// in the debug information (which is parsed by the SymbolFile parser plug-ins
+// and registered with each Module).
//----------------------------------------------------------------------
// void
// CompileUnit::FindFunctions(const Mangled::Tokens& tokens)
@@ -283,13 +282,12 @@ uint32_t CompileUnit::ResolveSymbolContext(const FileSpec &file_spec,
bool exact, uint32_t resolve_scope,
SymbolContextList &sc_list) {
// First find all of the file indexes that match our "file_spec". If
- // "file_spec" has an empty directory, then only compare the basenames
- // when finding file indexes
+ // "file_spec" has an empty directory, then only compare the basenames when
+ // finding file indexes
std::vector<uint32_t> file_indexes;
const bool full_match = (bool)file_spec.GetDirectory();
- const bool remove_backup_dots = true;
bool file_spec_matches_cu_file_spec =
- FileSpec::Equal(file_spec, *this, full_match, remove_backup_dots);
+ FileSpec::Equal(file_spec, *this, full_match);
// If we are not looking for inlined functions and our file spec doesn't
// match then we are done...
@@ -297,11 +295,10 @@ uint32_t CompileUnit::ResolveSymbolContext(const FileSpec &file_spec,
return 0;
uint32_t file_idx =
- GetSupportFiles().FindFileIndex(1, file_spec, true, remove_backup_dots);
+ GetSupportFiles().FindFileIndex(1, file_spec, true);
while (file_idx != UINT32_MAX) {
file_indexes.push_back(file_idx);
- file_idx = GetSupportFiles().FindFileIndex(file_idx + 1, file_spec, true,
- remove_backup_dots);
+ file_idx = GetSupportFiles().FindFileIndex(file_idx + 1, file_spec, true);
}
const size_t num_file_indexes = file_indexes.size();
@@ -321,23 +318,23 @@ uint32_t CompileUnit::ResolveSymbolContext(const FileSpec &file_spec,
uint32_t line_idx;
if (num_file_indexes == 1) {
- // We only have a single support file that matches, so use
- // the line table function that searches for a line entries
- // that match a single support file index
+ // We only have a single support file that matches, so use the line
+ // table function that searches for a line entries that match a single
+ // support file index
LineEntry line_entry;
line_idx = line_table->FindLineEntryIndexByFileIndex(
0, file_indexes.front(), line, exact, &line_entry);
- // If "exact == true", then "found_line" will be the same
- // as "line". If "exact == false", the "found_line" will be the
- // closest line entry with a line number greater than "line" and
- // we will use this for our subsequent line exact matches below.
+ // If "exact == true", then "found_line" will be the same as "line". If
+ // "exact == false", the "found_line" will be the closest line entry
+ // with a line number greater than "line" and we will use this for our
+ // subsequent line exact matches below.
found_line = line_entry.line;
while (line_idx != UINT32_MAX) {
- // If they only asked for the line entry, then we're done, we can just
- // copy that over.
- // But if they wanted more than just the line number, fill it in.
+ // If they only asked for the line entry, then we're done, we can
+ // just copy that over. But if they wanted more than just the line
+ // number, fill it in.
if (resolve_scope == eSymbolContextLineEntry) {
sc.line_entry = line_entry;
} else {
@@ -351,17 +348,17 @@ uint32_t CompileUnit::ResolveSymbolContext(const FileSpec &file_spec,
&line_entry);
}
} else {
- // We found multiple support files that match "file_spec" so use
- // the line table function that searches for a line entries
- // that match a multiple support file indexes.
+ // We found multiple support files that match "file_spec" so use the
+ // line table function that searches for a line entries that match a
+ // multiple support file indexes.
LineEntry line_entry;
line_idx = line_table->FindLineEntryIndexByFileIndex(
0, file_indexes, line, exact, &line_entry);
- // If "exact == true", then "found_line" will be the same
- // as "line". If "exact == false", the "found_line" will be the
- // closest line entry with a line number greater than "line" and
- // we will use this for our subsequent line exact matches below.
+ // If "exact == true", then "found_line" will be the same as "line". If
+ // "exact == false", the "found_line" will be the closest line entry
+ // with a line number greater than "line" and we will use this for our
+ // subsequent line exact matches below.
found_line = line_entry.line;
while (line_idx != UINT32_MAX) {
@@ -379,8 +376,8 @@ uint32_t CompileUnit::ResolveSymbolContext(const FileSpec &file_spec,
}
}
} else if (file_spec_matches_cu_file_spec && !check_inlines) {
- // only append the context if we aren't looking for inline call sites
- // by file and line and if the file spec matches that of the compile unit
+ // only append the context if we aren't looking for inline call sites by
+ // file and line and if the file spec matches that of the compile unit
sc_list.Append(sc);
}
return sc_list.GetSize() - prev_size;
diff --git a/source/Symbol/CompilerType.cpp b/source/Symbol/CompilerType.cpp
index 5d845361b03c..2dd1d3ebd04b 100644
--- a/source/Symbol/CompilerType.cpp
+++ b/source/Symbol/CompilerType.cpp
@@ -638,8 +638,8 @@ CompilerType CompilerType::GetChildCompilerTypeAtIndex(
}
// Look for a child member (doesn't include base classes, but it does include
-// their members) in the type hierarchy. Returns an index path into "clang_type"
-// on how to reach the appropriate member.
+// their members) in the type hierarchy. Returns an index path into
+// "clang_type" on how to reach the appropriate member.
//
// class A
// {
@@ -662,16 +662,13 @@ CompilerType CompilerType::GetChildCompilerTypeAtIndex(
// "m_b" in it:
//
// With omit_empty_base_classes == false we would get an integer array back
-// with:
-// { 1, 1 }
-// The first index 1 is the child index for "class A" within class C
-// The second index 1 is the child index for "m_b" within class A
+// with: { 1, 1 } The first index 1 is the child index for "class A" within
+// class C The second index 1 is the child index for "m_b" within class A
//
-// With omit_empty_base_classes == true we would get an integer array back with:
-// { 0, 1 }
-// The first index 0 is the child index for "class A" within class C (since
-// class B doesn't have any members it doesn't count)
-// The second index 1 is the child index for "m_b" within class A
+// With omit_empty_base_classes == true we would get an integer array back
+// with: { 0, 1 } The first index 0 is the child index for "class A" within
+// class C (since class B doesn't have any members it doesn't count) The second
+// index 1 is the child index for "m_b" within class A
size_t CompilerType::GetIndexOfChildMemberWithName(
const char *name, bool omit_empty_base_classes,
@@ -987,8 +984,8 @@ bool CompilerType::ReadFromMemory(lldb_private::ExecutionContext *exe_ctx,
if (!IsValid())
return false;
- // Can't convert a file address to anything valid without more
- // context (which Module it came from)
+ // Can't convert a file address to anything valid without more context (which
+ // Module it came from)
if (address_type == eAddressTypeFile)
return false;
@@ -1029,8 +1026,8 @@ bool CompilerType::WriteToMemory(lldb_private::ExecutionContext *exe_ctx,
if (!IsValid())
return false;
- // Can't convert a file address to anything valid without more
- // context (which Module it came from)
+ // Can't convert a file address to anything valid without more context (which
+ // Module it came from)
if (address_type == eAddressTypeFile)
return false;
diff --git a/source/Symbol/DWARFCallFrameInfo.cpp b/source/Symbol/DWARFCallFrameInfo.cpp
index 572648d05f09..1bf9ff99e015 100644
--- a/source/Symbol/DWARFCallFrameInfo.cpp
+++ b/source/Symbol/DWARFCallFrameInfo.cpp
@@ -27,8 +27,8 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// GetDwarfEHPtr
//
-// Used for calls when the value type is specified by a DWARF EH Frame
-// pointer encoding.
+// Used for calls when the value type is specified by a DWARF EH Frame pointer
+// encoding.
//----------------------------------------------------------------------
static uint64_t
GetGNUEHPointer(const DataExtractor &DE, offset_t *offset_ptr,
@@ -83,8 +83,8 @@ GetGNUEHPointer(const DataExtractor &DE, offset_t *offset_ptr,
break;
case DW_EH_PE_aligned: {
- // SetPointerSize should be called prior to extracting these so the
- // pointer size is cached
+ // SetPointerSize should be called prior to extracting these so the pointer
+ // size is cached
assert(addr_size != 0);
if (addr_size) {
// Align to a address size boundary first
@@ -154,8 +154,8 @@ DWARFCallFrameInfo::DWARFCallFrameInfo(ObjectFile &objfile,
bool DWARFCallFrameInfo::GetUnwindPlan(Address addr, UnwindPlan &unwind_plan) {
FDEEntryMap::Entry fde_entry;
- // Make sure that the Address we're searching for is the same object file
- // as this DWARFCallFrameInfo, we only store File offsets in m_fde_index.
+ // Make sure that the Address we're searching for is the same object file as
+ // this DWARFCallFrameInfo, we only store File offsets in m_fde_index.
ModuleSP module_sp = addr.GetModule();
if (module_sp.get() == nullptr || module_sp->GetObjectFile() == nullptr ||
module_sp->GetObjectFile() != &m_objfile)
@@ -168,8 +168,8 @@ bool DWARFCallFrameInfo::GetUnwindPlan(Address addr, UnwindPlan &unwind_plan) {
bool DWARFCallFrameInfo::GetAddressRange(Address addr, AddressRange &range) {
- // Make sure that the Address we're searching for is the same object file
- // as this DWARFCallFrameInfo, we only store File offsets in m_fde_index.
+ // Make sure that the Address we're searching for is the same object file as
+ // this DWARFCallFrameInfo, we only store File offsets in m_fde_index.
ModuleSP module_sp = addr.GetModule();
if (module_sp.get() == nullptr || module_sp->GetObjectFile() == nullptr ||
module_sp->GetObjectFile() != &m_objfile)
@@ -291,8 +291,8 @@ DWARFCallFrameInfo::ParseCIE(const dw_offset_t cie_offset) {
return nullptr;
}
- // m_cfi_data uses address size from target architecture of the process
- // may ignore these fields?
+ // m_cfi_data uses address size from target architecture of the process may
+ // ignore these fields?
if (m_type == DWARF && cie_sp->version >= CFI_VERSION4) {
cie_sp->address_size = m_cfi_data.GetU8(&offset);
cie_sp->segment_size = m_cfi_data.GetU8(&offset);
@@ -307,15 +307,15 @@ DWARFCallFrameInfo::ParseCIE(const dw_offset_t cie_offset) {
: m_cfi_data.GetU8(&offset);
if (cie_sp->augmentation[0]) {
- // Get the length of the eh_frame augmentation data
- // which starts with a ULEB128 length in bytes
+ // Get the length of the eh_frame augmentation data which starts with a
+ // ULEB128 length in bytes
const size_t aug_data_len = (size_t)m_cfi_data.GetULEB128(&offset);
const size_t aug_data_end = offset + aug_data_len;
const size_t aug_str_len = strlen(cie_sp->augmentation);
// A 'z' may be present as the first character of the string.
- // If present, the Augmentation Data field shall be present.
- // The contents of the Augmentation Data shall be interpreted
- // according to other characters in the Augmentation String.
+ // If present, the Augmentation Data field shall be present. The contents
+ // of the Augmentation Data shall be interpreted according to other
+ // characters in the Augmentation String.
if (cie_sp->augmentation[0] == 'z') {
// Extract the Augmentation Data
size_t aug_str_idx = 0;
@@ -323,31 +323,27 @@ DWARFCallFrameInfo::ParseCIE(const dw_offset_t cie_offset) {
char aug = cie_sp->augmentation[aug_str_idx];
switch (aug) {
case 'L':
- // Indicates the presence of one argument in the
- // Augmentation Data of the CIE, and a corresponding
- // argument in the Augmentation Data of the FDE. The
- // argument in the Augmentation Data of the CIE is
- // 1-byte and represents the pointer encoding used
- // for the argument in the Augmentation Data of the
- // FDE, which is the address of a language-specific
- // data area (LSDA). The size of the LSDA pointer is
- // specified by the pointer encoding used.
+ // Indicates the presence of one argument in the Augmentation Data
+ // of the CIE, and a corresponding argument in the Augmentation
+ // Data of the FDE. The argument in the Augmentation Data of the
+ // CIE is 1-byte and represents the pointer encoding used for the
+ // argument in the Augmentation Data of the FDE, which is the
+ // address of a language-specific data area (LSDA). The size of the
+ // LSDA pointer is specified by the pointer encoding used.
cie_sp->lsda_addr_encoding = m_cfi_data.GetU8(&offset);
break;
case 'P':
- // Indicates the presence of two arguments in the
- // Augmentation Data of the CIE. The first argument
- // is 1-byte and represents the pointer encoding
- // used for the second argument, which is the
- // address of a personality routine handler. The
- // size of the personality routine pointer is
- // specified by the pointer encoding used.
+ // Indicates the presence of two arguments in the Augmentation Data
+ // of the CIE. The first argument is 1-byte and represents the
+ // pointer encoding used for the second argument, which is the
+ // address of a personality routine handler. The size of the
+ // personality routine pointer is specified by the pointer encoding
+ // used.
//
- // The address of the personality function will
- // be stored at this location. Pre-execution, it
- // will be all zero's so don't read it until we're
- // trying to do an unwind & the reloc has been
+ // The address of the personality function will be stored at this
+ // location. Pre-execution, it will be all zero's so don't read it
+ // until we're trying to do an unwind & the reloc has been
// resolved.
{
uint8_t arg_ptr_encoding = m_cfi_data.GetU8(&offset);
@@ -360,22 +356,21 @@ DWARFCallFrameInfo::ParseCIE(const dw_offset_t cie_offset) {
case 'R':
// A 'R' may be present at any position after the
- // first character of the string. The Augmentation
- // Data shall include a 1 byte argument that
- // represents the pointer encoding for the address
- // pointers used in the FDE.
- // Example: 0x1B == DW_EH_PE_pcrel | DW_EH_PE_sdata4
+ // first character of the string. The Augmentation Data shall
+ // include a 1 byte argument that represents the pointer encoding
+ // for the address pointers used in the FDE. Example: 0x1B ==
+ // DW_EH_PE_pcrel | DW_EH_PE_sdata4
cie_sp->ptr_encoding = m_cfi_data.GetU8(&offset);
break;
}
}
} else if (strcmp(cie_sp->augmentation, "eh") == 0) {
- // If the Augmentation string has the value "eh", then
- // the EH Data field shall be present
+ // If the Augmentation string has the value "eh", then the EH Data
+ // field shall be present
}
- // Set the offset to be the end of the augmentation data just in case
- // we didn't understand any of the data.
+ // Set the offset to be the end of the augmentation data just in case we
+ // didn't understand any of the data.
offset = (uint32_t)aug_data_end;
}
@@ -408,10 +403,8 @@ void DWARFCallFrameInfo::GetCFIData() {
}
}
// Scan through the eh_frame or debug_frame section looking for FDEs and noting
-// the start/end addresses
-// of the functions and a pointer back to the function's FDE for later
-// expansion.
-// Internalize CIEs as we come across them.
+// the start/end addresses of the functions and a pointer back to the
+// function's FDE for later expansion. Internalize CIEs as we come across them.
void DWARFCallFrameInfo::GetFDEIndex() {
if (m_section_sp.get() == nullptr || m_section_sp->IsEncrypted())
@@ -469,8 +462,8 @@ void DWARFCallFrameInfo::GetFDEIndex() {
}
// An FDE entry contains CIE_pointer in debug_frame in same place as cie_id
- // in eh_frame. CIE_pointer is an offset into the .debug_frame section.
- // So, variable cie_offset should be equal to cie_id for debug_frame.
+ // in eh_frame. CIE_pointer is an offset into the .debug_frame section. So,
+ // variable cie_offset should be equal to cie_id for debug_frame.
// FDE entries with cie_id == 0 shouldn't be ignored for it.
if ((cie_id == 0 && m_type == EH) || cie_id == UINT32_MAX || len == 0) {
auto cie_sp = ParseCIE(current_entry);
@@ -556,9 +549,8 @@ bool DWARFCallFrameInfo::FDEToUnwindPlan(dw_offset_t dwarf_offset,
// FDE entries with zeroth cie_offset may occur for debug_frame.
assert(!(m_type == EH && 0 == cie_offset) && cie_offset != UINT32_MAX);
- // Translate the CIE_id from the eh_frame format, which
- // is relative to the FDE offset, into a __eh_frame section
- // offset
+ // Translate the CIE_id from the eh_frame format, which is relative to the
+ // FDE offset, into a __eh_frame section offset
if (m_type == EH) {
unwind_plan.SetSourceName("eh_frame CFI");
cie_offset = current_entry + (is_64bit ? 12 : 4) - cie_offset;
@@ -652,10 +644,10 @@ bool DWARFCallFrameInfo::FDEToUnwindPlan(dw_offset_t dwarf_offset,
case DW_CFA_advance_loc: // (Row Creation Instruction)
{ // 0x40 - high 2 bits are 0x1, lower 6 bits are delta
// takes a single argument that represents a constant delta. The
- // required action is to create a new table row with a location
- // value that is computed by taking the current entry's location
- // value and adding (delta * code_align). All other
- // values in the new row are initially identical to the current row.
+ // required action is to create a new table row with a location value
+ // that is computed by taking the current entry's location value and
+ // adding (delta * code_align). All other values in the new row are
+ // initially identical to the current row.
unwind_plan.AppendRow(row);
UnwindPlan::Row *newrow = new UnwindPlan::Row;
*newrow = *row.get();
@@ -670,11 +662,10 @@ bool DWARFCallFrameInfo::FDEToUnwindPlan(dw_offset_t dwarf_offset,
// required action is to change the rule for the indicated register
// to the rule assigned it by the initial_instructions in the CIE.
uint32_t reg_num = extended_opcode;
- // We only keep enough register locations around to
- // unwind what is in our thread, and these are organized
- // by the register index in that state, so we need to convert our
- // eh_frame register number from the EH frame info, to a register
- // index
+ // We only keep enough register locations around to unwind what is in
+ // our thread, and these are organized by the register index in that
+ // state, so we need to convert our eh_frame register number from the
+ // EH frame info, to a register index
if (unwind_plan.IsValidRowIndex(0) &&
unwind_plan.GetRowAtIndex(0)->GetRegisterInfo(reg_num,
@@ -756,8 +747,8 @@ bool DWARFCallFrameInfo::FDEToUnwindPlan(dw_offset_t dwarf_offset,
case DW_CFA_remember_state: // 0xA
{
// These instructions define a stack of information. Encountering the
- // DW_CFA_remember_state instruction means to save the rules for every
- // register on the current row on the stack. Encountering the
+ // DW_CFA_remember_state instruction means to save the rules for
+ // every register on the current row on the stack. Encountering the
// DW_CFA_restore_state instruction means to pop the set of rules off
// the stack and place them in the current row. (This operation is
// useful for compilers that move epilogue code into the body of a
@@ -772,8 +763,8 @@ bool DWARFCallFrameInfo::FDEToUnwindPlan(dw_offset_t dwarf_offset,
case DW_CFA_restore_state: // 0xB
{
// These instructions define a stack of information. Encountering the
- // DW_CFA_remember_state instruction means to save the rules for every
- // register on the current row on the stack. Encountering the
+ // DW_CFA_remember_state instruction means to save the rules for
+ // every register on the current row on the stack. Encountering the
// DW_CFA_restore_state instruction means to pop the set of rules off
// the stack and place them in the current row. (This operation is
// useful for compilers that move epilogue code into the body of a
@@ -798,10 +789,9 @@ bool DWARFCallFrameInfo::FDEToUnwindPlan(dw_offset_t dwarf_offset,
case DW_CFA_GNU_args_size: // 0x2e
{
// The DW_CFA_GNU_args_size instruction takes an unsigned LEB128
- // operand
- // representing an argument size. This instruction specifies the total
- // of
- // the size of the arguments which have been pushed onto the stack.
+ // operand representing an argument size. This instruction specifies
+ // the total of the size of the arguments which have been pushed onto
+ // the stack.
// TODO: Figure out how we should handle this.
m_cfi_data.GetULEB128(&offset);
@@ -834,9 +824,9 @@ bool DWARFCallFrameInfo::HandleCommonDwarfOpcode(uint8_t primary_opcode,
// register
// takes two arguments: an unsigned LEB128 constant representing a
// factored offset and a register number. The required action is to
- // change the rule for the register indicated by the register number
- // to be an offset(N) rule with a value of
- // (N = factored offset * data_align).
+ // change the rule for the register indicated by the register number to
+ // be an offset(N) rule with a value of (N = factored offset *
+ // data_align).
uint8_t reg_num = extended_opcode;
int32_t op_offset = (int32_t)m_cfi_data.GetULEB128(&offset) * data_align;
reg_location.SetAtCFAPlusOffset(op_offset);
@@ -851,8 +841,8 @@ bool DWARFCallFrameInfo::HandleCommonDwarfOpcode(uint8_t primary_opcode,
case DW_CFA_offset_extended: // 0x5
{
- // takes two unsigned LEB128 arguments representing a register number
- // and a factored offset. This instruction is identical to DW_CFA_offset
+ // takes two unsigned LEB128 arguments representing a register number and
+ // a factored offset. This instruction is identical to DW_CFA_offset
// except for the encoding and size of the register argument.
uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
int32_t op_offset = (int32_t)m_cfi_data.GetULEB128(&offset) * data_align;
@@ -888,9 +878,9 @@ bool DWARFCallFrameInfo::HandleCommonDwarfOpcode(uint8_t primary_opcode,
case DW_CFA_register: // 0x9
{
- // takes two unsigned LEB128 arguments representing register numbers.
- // The required action is to set the rule for the first register to be
- // the second register.
+ // takes two unsigned LEB128 arguments representing register numbers. The
+ // required action is to set the rule for the first register to be the
+ // second register.
uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
uint32_t other_reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
UnwindPlan::Row::RegisterLocation reg_location;
@@ -901,10 +891,9 @@ bool DWARFCallFrameInfo::HandleCommonDwarfOpcode(uint8_t primary_opcode,
case DW_CFA_def_cfa: // 0xC (CFA Definition Instruction)
{
- // Takes two unsigned LEB128 operands representing a register
- // number and a (non-factored) offset. The required action
- // is to define the current CFA rule to use the provided
- // register and offset.
+ // Takes two unsigned LEB128 operands representing a register number and
+ // a (non-factored) offset. The required action is to define the current
+ // CFA rule to use the provided register and offset.
uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
int32_t op_offset = (int32_t)m_cfi_data.GetULEB128(&offset);
row.GetCFAValue().SetIsRegisterPlusOffset(reg_num, op_offset);
@@ -914,8 +903,8 @@ bool DWARFCallFrameInfo::HandleCommonDwarfOpcode(uint8_t primary_opcode,
case DW_CFA_def_cfa_register: // 0xD (CFA Definition Instruction)
{
// takes a single unsigned LEB128 argument representing a register
- // number. The required action is to define the current CFA rule to
- // use the provided register (but to keep the old offset).
+ // number. The required action is to define the current CFA rule to use
+ // the provided register (but to keep the old offset).
uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
row.GetCFAValue().SetIsRegisterPlusOffset(reg_num,
row.GetCFAValue().GetOffset());
@@ -924,10 +913,9 @@ bool DWARFCallFrameInfo::HandleCommonDwarfOpcode(uint8_t primary_opcode,
case DW_CFA_def_cfa_offset: // 0xE (CFA Definition Instruction)
{
- // Takes a single unsigned LEB128 operand representing a
- // (non-factored) offset. The required action is to define
- // the current CFA rule to use the provided offset (but
- // to keep the old register).
+ // Takes a single unsigned LEB128 operand representing a (non-factored)
+ // offset. The required action is to define the current CFA rule to use
+ // the provided offset (but to keep the old register).
int32_t op_offset = (int32_t)m_cfi_data.GetULEB128(&offset);
row.GetCFAValue().SetIsRegisterPlusOffset(
row.GetCFAValue().GetRegisterNumber(), op_offset);
@@ -945,14 +933,13 @@ bool DWARFCallFrameInfo::HandleCommonDwarfOpcode(uint8_t primary_opcode,
case DW_CFA_expression: // 0x10
{
- // Takes two operands: an unsigned LEB128 value representing
- // a register number, and a DW_FORM_block value representing a DWARF
- // expression. The required action is to change the rule for the
- // register indicated by the register number to be an expression(E)
- // rule where E is the DWARF expression. That is, the DWARF
- // expression computes the address. The value of the CFA is
- // pushed on the DWARF evaluation stack prior to execution of
- // the DWARF expression.
+ // Takes two operands: an unsigned LEB128 value representing a register
+ // number, and a DW_FORM_block value representing a DWARF expression. The
+ // required action is to change the rule for the register indicated by
+ // the register number to be an expression(E) rule where E is the DWARF
+ // expression. That is, the DWARF expression computes the address. The
+ // value of the CFA is pushed on the DWARF evaluation stack prior to
+ // execution of the DWARF expression.
uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
uint32_t block_len = (uint32_t)m_cfi_data.GetULEB128(&offset);
const uint8_t *block_data =
@@ -965,10 +952,10 @@ bool DWARFCallFrameInfo::HandleCommonDwarfOpcode(uint8_t primary_opcode,
case DW_CFA_offset_extended_sf: // 0x11
{
- // takes two operands: an unsigned LEB128 value representing a
- // register number and a signed LEB128 factored offset. This
- // instruction is identical to DW_CFA_offset_extended except
- // that the second operand is signed and factored.
+ // takes two operands: an unsigned LEB128 value representing a register
+ // number and a signed LEB128 factored offset. This instruction is
+ // identical to DW_CFA_offset_extended except that the second operand is
+ // signed and factored.
uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
int32_t op_offset = (int32_t)m_cfi_data.GetSLEB128(&offset) * data_align;
UnwindPlan::Row::RegisterLocation reg_location;
@@ -979,10 +966,10 @@ bool DWARFCallFrameInfo::HandleCommonDwarfOpcode(uint8_t primary_opcode,
case DW_CFA_def_cfa_sf: // 0x12 (CFA Definition Instruction)
{
- // Takes two operands: an unsigned LEB128 value representing
- // a register number and a signed LEB128 factored offset.
- // This instruction is identical to DW_CFA_def_cfa except
- // that the second operand is signed and factored.
+ // Takes two operands: an unsigned LEB128 value representing a register
+ // number and a signed LEB128 factored offset. This instruction is
+ // identical to DW_CFA_def_cfa except that the second operand is signed
+ // and factored.
uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
int32_t op_offset = (int32_t)m_cfi_data.GetSLEB128(&offset) * data_align;
row.GetCFAValue().SetIsRegisterPlusOffset(reg_num, op_offset);
@@ -991,9 +978,9 @@ bool DWARFCallFrameInfo::HandleCommonDwarfOpcode(uint8_t primary_opcode,
case DW_CFA_def_cfa_offset_sf: // 0x13 (CFA Definition Instruction)
{
- // takes a signed LEB128 operand representing a factored
- // offset. This instruction is identical to DW_CFA_def_cfa_offset
- // except that the operand is signed and factored.
+ // takes a signed LEB128 operand representing a factored offset. This
+ // instruction is identical to DW_CFA_def_cfa_offset except that the
+ // operand is signed and factored.
int32_t op_offset = (int32_t)m_cfi_data.GetSLEB128(&offset) * data_align;
uint32_t cfa_regnum = row.GetCFAValue().GetRegisterNumber();
row.GetCFAValue().SetIsRegisterPlusOffset(cfa_regnum, op_offset);
@@ -1003,9 +990,9 @@ bool DWARFCallFrameInfo::HandleCommonDwarfOpcode(uint8_t primary_opcode,
case DW_CFA_val_expression: // 0x16
{
// takes two operands: an unsigned LEB128 value representing a register
- // number, and a DW_FORM_block value representing a DWARF expression.
- // The required action is to change the rule for the register indicated
- // by the register number to be a val_expression(E) rule where E is the
+ // number, and a DW_FORM_block value representing a DWARF expression. The
+ // required action is to change the rule for the register indicated by
+ // the register number to be a val_expression(E) rule where E is the
// DWARF expression. That is, the DWARF expression computes the value of
// the given register. The value of the CFA is pushed on the DWARF
// evaluation stack prior to execution of the DWARF expression.
diff --git a/source/Symbol/Declaration.cpp b/source/Symbol/Declaration.cpp
index 7cee6c5a3ef3..83df578da2e3 100644
--- a/source/Symbol/Declaration.cpp
+++ b/source/Symbol/Declaration.cpp
@@ -91,7 +91,7 @@ bool lldb_private::operator==(const Declaration &lhs, const Declaration &rhs) {
return lhs.GetFile() == rhs.GetFile();
#else
if (lhs.GetLine() == rhs.GetLine())
- return FileSpec::Equal(lhs.GetFile(), rhs.GetFile(), true, true);
+ return FileSpec::Equal(lhs.GetFile(), rhs.GetFile(), true);
#endif
return false;
}
diff --git a/source/Symbol/FuncUnwinders.cpp b/source/Symbol/FuncUnwinders.cpp
index b9f50cd1b12f..2384d35e3d36 100644
--- a/source/Symbol/FuncUnwinders.cpp
+++ b/source/Symbol/FuncUnwinders.cpp
@@ -174,10 +174,9 @@ UnwindPlanSP FuncUnwinders::GetEHFrameAugmentedUnwindPlan(Target &target,
m_tried_unwind_plan_eh_frame_augmented)
return m_unwind_plan_eh_frame_augmented_sp;
- // Only supported on x86 architectures where we get eh_frame from the compiler
- // that describes
- // the prologue instructions perfectly, and sometimes the epilogue
- // instructions too.
+ // Only supported on x86 architectures where we get eh_frame from the
+ // compiler that describes the prologue instructions perfectly, and sometimes
+ // the epilogue instructions too.
if (target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_32_i386 &&
target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_64_x86_64 &&
target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_64_x86_64h) {
@@ -194,8 +193,7 @@ UnwindPlanSP FuncUnwinders::GetEHFrameAugmentedUnwindPlan(Target &target,
m_unwind_plan_eh_frame_augmented_sp.reset(new UnwindPlan(*eh_frame_plan));
// Augment the eh_frame instructions with epilogue descriptions if necessary
- // so the
- // UnwindPlan can be used at any instruction in the function.
+ // so the UnwindPlan can be used at any instruction in the function.
UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target));
if (assembly_profiler_sp) {
@@ -238,7 +236,8 @@ FuncUnwinders::GetDebugFrameAugmentedUnwindPlan(Target &target, Thread &thread,
new UnwindPlan(*debug_frame_plan));
// Augment the debug_frame instructions with epilogue descriptions if
- // necessary so the UnwindPlan can be used at any instruction in the function.
+ // necessary so the UnwindPlan can be used at any instruction in the
+ // function.
UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target));
if (assembly_profiler_sp) {
@@ -275,8 +274,7 @@ UnwindPlanSP FuncUnwinders::GetAssemblyUnwindPlan(Target &target,
// This method compares the pc unwind rule in the first row of two UnwindPlans.
// If they have the same way of getting the pc value (e.g. "CFA - 8" + "CFA is
-// sp"),
-// then it will return LazyBoolTrue.
+// sp"), then it will return LazyBoolTrue.
LazyBool FuncUnwinders::CompareUnwindPlansForIdenticalInitialPCLocation(
Thread &thread, const UnwindPlanSP &a, const UnwindPlanSP &b) {
LazyBool plans_are_identical = eLazyBoolCalculate;
@@ -320,22 +318,22 @@ UnwindPlanSP FuncUnwinders::GetUnwindPlanAtNonCallSite(Target &target,
UnwindPlanSP assembly_sp =
GetAssemblyUnwindPlan(target, thread, current_offset);
- // This point of this code is to detect when a function is using a
- // non-standard ABI, and the eh_frame correctly describes that alternate ABI.
+ // This point of this code is to detect when a function is using a non-
+ // standard ABI, and the eh_frame correctly describes that alternate ABI.
// This is addressing a specific situation on x86_64 linux systems where one
// function in a library pushes a value on the stack and jumps to another
- // function. So using an assembly instruction based unwind will not work when
- // you're in the second function - the stack has been modified in a non-ABI
- // way. But we have eh_frame that correctly describes how to unwind from this
- // location. So we're looking to see if the initial pc register save location
- // from the eh_frame is different from the assembly unwind, the arch default
- // unwind, and the arch default at initial function entry.
+ // function. So using an assembly instruction based unwind will not work
+ // when you're in the second function - the stack has been modified in a non-
+ // ABI way. But we have eh_frame that correctly describes how to unwind from
+ // this location. So we're looking to see if the initial pc register save
+ // location from the eh_frame is different from the assembly unwind, the arch
+ // default unwind, and the arch default at initial function entry.
//
// We may have eh_frame that describes the entire function -- or we may have
// eh_frame that only describes the unwind after the prologue has executed --
// so we need to check both the arch default (once the prologue has executed)
- // and the arch default at initial function entry. And we may be running on a
- // target where we have only some of the assembly/arch default unwind plans
+ // and the arch default at initial function entry. And we may be running on
+ // a target where we have only some of the assembly/arch default unwind plans
// available.
if (CompareUnwindPlansForIdenticalInitialPCLocation(
diff --git a/source/Symbol/Function.cpp b/source/Symbol/Function.cpp
index 9464cef0bc73..f642c186a19f 100644
--- a/source/Symbol/Function.cpp
+++ b/source/Symbol/Function.cpp
@@ -24,9 +24,8 @@ using namespace lldb;
using namespace lldb_private;
//----------------------------------------------------------------------
-// Basic function information is contained in the FunctionInfo class.
-// It is designed to contain the name, linkage name, and declaration
-// location.
+// Basic function information is contained in the FunctionInfo class. It is
+// designed to contain the name, linkage name, and declaration location.
//----------------------------------------------------------------------
FunctionInfo::FunctionInfo(const char *name, const Declaration *decl_ptr)
: m_name(name), m_declaration(decl_ptr) {}
@@ -188,8 +187,7 @@ void Function::GetEndLineSourceInfo(FileSpec &source_file, uint32_t &line_no) {
source_file.Clear();
// The -1 is kind of cheesy, but I want to get the last line entry for the
- // given function, not the
- // first entry of the next.
+ // given function, not the first entry of the next.
Address scratch_addr(GetAddressRange().GetBaseAddress());
scratch_addr.SetOffset(scratch_addr.GetOffset() +
GetAddressRange().GetByteSize() - 1);
@@ -331,9 +329,8 @@ size_t Function::MemorySize() const {
bool Function::GetIsOptimized() {
bool result = false;
- // Currently optimization is only indicted by the
- // vendor extension DW_AT_APPLE_optimized which
- // is set on a compile unit level.
+ // Currently optimization is only indicted by the vendor extension
+ // DW_AT_APPLE_optimized which is set on a compile unit level.
if (m_comp_unit) {
result = m_comp_unit->GetIsOptimized();
}
@@ -441,11 +438,11 @@ uint32_t Function::GetPrologueByteSize() {
}
}
- // If we didn't find the end of the prologue in the line tables,
- // then just use the end address of the first line table entry
+ // If we didn't find the end of the prologue in the line tables, then
+ // just use the end address of the first line table entry
if (prologue_end_file_addr == LLDB_INVALID_ADDRESS) {
- // Check the first few instructions and look for one that has
- // a line number that's different than the first entry.
+ // Check the first few instructions and look for one that has a line
+ // number that's different than the first entry.
uint32_t last_line_entry_idx = first_line_entry_idx + 6;
for (uint32_t idx = first_line_entry_idx + 1;
idx < last_line_entry_idx; ++idx) {
@@ -498,8 +495,8 @@ uint32_t Function::GetPrologueByteSize() {
}
}
- // Verify that this prologue end file address in the function's
- // address range just to be sure
+ // Verify that this prologue end file address in the function's address
+ // range just to be sure
if (func_start_file_addr < prologue_end_file_addr &&
prologue_end_file_addr < func_end_file_addr) {
m_prologue_byte_size = prologue_end_file_addr - func_start_file_addr;
diff --git a/source/Symbol/GoASTContext.cpp b/source/Symbol/GoASTContext.cpp
index 6761a605e46b..da5c82b2cb55 100644
--- a/source/Symbol/GoASTContext.cpp
+++ b/source/Symbol/GoASTContext.cpp
@@ -667,8 +667,7 @@ GoASTContext::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) {
}
// 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.
+// prototype Returns a value >= 0 if there is a prototype.
int GoASTContext::GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) {
return GetNumberOfFunctionArguments(type);
}
@@ -1008,8 +1007,8 @@ CompilerType GoASTContext::GetChildCompilerTypeAtIndex(
return CompilerType();
}
-// Lookup a child given a name. This function will match base class names
-// and member member names in "clang_type" only, not descendants.
+// Lookup a child given a name. This function will match base class names and
+// member member names in "clang_type" only, not descendants.
uint32_t
GoASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
const char *name,
@@ -1048,8 +1047,8 @@ size_t GoASTContext::GetIndexOfChildMemberWithName(
return 1;
}
-// Converts "s" to a floating point value and place resulting floating
-// point bytes in the "dst" buffer.
+// Converts "s" to a floating point value and place resulting floating point
+// bytes in the "dst" buffer.
size_t
GoASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type,
const char *s, uint8_t *dst,
@@ -1080,9 +1079,8 @@ void GoASTContext::DumpValue(lldb::opaque_compiler_type_t type,
uint32_t field_idx = 0;
for (auto *field = st->GetField(field_idx); field != nullptr;
field_idx++) {
- // Print the starting squiggly bracket (if this is the
- // first member) or comma (for member 2 and beyond) for
- // the struct/union/class member.
+ // Print the starting squiggly bracket (if this is the first member) or
+ // comma (for member 2 and beyond) for the struct/union/class member.
if (field_idx == 0)
s->PutChar('{');
else
@@ -1137,9 +1135,8 @@ void GoASTContext::DumpValue(lldb::opaque_compiler_type_t type,
uint64_t element_idx;
for (element_idx = 0; element_idx < a->GetLength(); ++element_idx) {
- // Print the starting squiggly bracket (if this is the
- // first member) or comman (for member 2 and beyong) for
- // the struct/union/class member.
+ // Print the starting squiggly bracket (if this is the first member) or
+ // comman (for member 2 and beyong) for the struct/union/class member.
if (element_idx == 0)
s->PutChar('{');
else
diff --git a/source/Symbol/LineEntry.cpp b/source/Symbol/LineEntry.cpp
index 691afdf5ed06..21aa2557518d 100644
--- a/source/Symbol/LineEntry.cpp
+++ b/source/Symbol/LineEntry.cpp
@@ -170,9 +170,9 @@ int LineEntry::Compare(const LineEntry &a, const LineEntry &b) {
if (a_byte_size > b_byte_size)
return +1;
- // Check for an end sequence entry mismatch after we have determined
- // that the address values are equal. If one of the items is an end
- // sequence, we don't care about the line, file, or column info.
+ // Check for an end sequence entry mismatch after we have determined that the
+ // address values are equal. If one of the items is an end sequence, we don't
+ // care about the line, file, or column info.
if (a.is_terminal_entry > b.is_terminal_entry)
return -1;
if (a.is_terminal_entry < b.is_terminal_entry)
@@ -192,8 +192,8 @@ int LineEntry::Compare(const LineEntry &a, const LineEntry &b) {
}
AddressRange LineEntry::GetSameLineContiguousAddressRange() const {
- // Add each LineEntry's range to complete_line_range until we find
- // a different file / line number.
+ // Add each LineEntry's range to complete_line_range until we find a
+ // different file / line number.
AddressRange complete_line_range = range;
while (true) {
@@ -206,9 +206,8 @@ AddressRange LineEntry::GetSameLineContiguousAddressRange() const {
if (next_line_sc.line_entry.IsValid() &&
next_line_sc.line_entry.range.GetByteSize() > 0 &&
original_file == next_line_sc.line_entry.original_file) {
- // Include any line 0 entries - they indicate that this is
- // compiler-generated code
- // that does not correspond to user source code.
+ // Include any line 0 entries - they indicate that this is compiler-
+ // generated code that does not correspond to user source code.
if (next_line_sc.line_entry.line == 0) {
complete_line_range.SetByteSize(
complete_line_range.GetByteSize() +
@@ -217,10 +216,9 @@ AddressRange LineEntry::GetSameLineContiguousAddressRange() const {
}
if (line == next_line_sc.line_entry.line) {
- // next_line_sc is the same file & line as this LineEntry, so extend our
- // AddressRange by its size and continue to see if there are more
- // LineEntries
- // that we can combine.
+ // next_line_sc is the same file & line as this LineEntry, so extend
+ // our AddressRange by its size and continue to see if there are more
+ // LineEntries that we can combine.
complete_line_range.SetByteSize(
complete_line_range.GetByteSize() +
next_line_sc.line_entry.range.GetByteSize());
diff --git a/source/Symbol/LineTable.cpp b/source/Symbol/LineTable.cpp
index 3cb305302927..06e30219f09a 100644
--- a/source/Symbol/LineTable.cpp
+++ b/source/Symbol/LineTable.cpp
@@ -73,30 +73,24 @@ void LineTable::AppendLineEntryToSequence(
is_terminal_entry);
entry_collection &entries = seq->m_entries;
// Replace the last entry if the address is the same, otherwise append it. If
- // we have multiple
- // line entries at the same address, this indicates illegal DWARF so this
- // "fixes" the line table
- // to be correct. If not fixed this can cause a line entry's address that when
- // resolved back to
- // a symbol context, could resolve to a different line entry. We really want a
+ // we have multiple line entries at the same address, this indicates illegal
+ // DWARF so this "fixes" the line table to be correct. If not fixed this can
+ // cause a line entry's address that when resolved back to a symbol context,
+ // could resolve to a different line entry. We really want a
// 1 to 1 mapping
- // here to avoid these kinds of inconsistencies. We will need tor revisit this
- // if the DWARF line
- // tables are updated to allow multiple entries at the same address legally.
+ // here to avoid these kinds of inconsistencies. We will need tor revisit
+ // this if the DWARF line tables are updated to allow multiple entries at the
+ // same address legally.
if (!entries.empty() && entries.back().file_addr == file_addr) {
// GCC don't use the is_prologue_end flag to mark the first instruction
// after the prologue.
// Instead of it it is issuing a line table entry for the first instruction
- // of the prologue
- // and one for the first instruction after the prologue. If the size of the
- // prologue is 0
- // instruction then the 2 line entry will have the same file address.
- // Removing it will remove
- // our ability to properly detect the location of the end of prologe so we
- // set the prologue_end
- // flag to preserve this information (setting the prologue_end flag for an
- // entry what is after
- // the prologue end don't have any effect)
+ // of the prologue and one for the first instruction after the prologue. If
+ // the size of the prologue is 0 instruction then the 2 line entry will
+ // have the same file address. Removing it will remove our ability to
+ // properly detect the location of the end of prologe so we set the
+ // prologue_end flag to preserve this information (setting the prologue_end
+ // flag for an entry what is after the prologue end don't have any effect)
entry.is_prologue_end = entry.file_idx == entries.back().file_idx;
entries.back() = entry;
} else
@@ -200,14 +194,13 @@ bool LineTable::FindLineEntryByAddress(const Address &so_addr,
if (pos->file_addr != search_entry.file_addr)
--pos;
else if (pos->file_addr == search_entry.file_addr) {
- // If this is a termination entry, it shouldn't match since
- // entries with the "is_terminal_entry" member set to true
- // are termination entries that define the range for the
- // previous entry.
+ // If this is a termination entry, it shouldn't match since entries
+ // with the "is_terminal_entry" member set to true are termination
+ // entries that define the range for the previous entry.
if (pos->is_terminal_entry) {
- // The matching entry is a terminal entry, so we skip
- // ahead to the next entry to see if there is another
- // entry following this one whose section/offset matches.
+ // The matching entry is a terminal entry, so we skip ahead to
+ // the next entry to see if there is another entry following this
+ // one whose section/offset matches.
++pos;
if (pos != end_pos) {
if (pos->file_addr != search_entry.file_addr)
@@ -216,9 +209,8 @@ bool LineTable::FindLineEntryByAddress(const Address &so_addr,
}
if (pos != end_pos) {
- // While in the same section/offset backup to find the first
- // line entry that matches the address in case there are
- // multiple
+ // While in the same section/offset backup to find the first line
+ // entry that matches the address in case there are multiple
while (pos != begin_pos) {
entry_collection::const_iterator prev_pos = pos - 1;
if (prev_pos->file_addr == search_entry.file_addr &&
@@ -232,16 +224,15 @@ bool LineTable::FindLineEntryByAddress(const Address &so_addr,
}
else
{
- // There might be code in the containing objfile before the first line
- // table entry. Make sure that does not get considered part of the first
- // line table entry.
+ // There might be code in the containing objfile before the first
+ // line table entry. Make sure that does not get considered part of
+ // the first line table entry.
if (pos->file_addr > so_addr.GetFileAddress())
return false;
}
// Make sure we have a valid match and that the match isn't a
- // terminating
- // entry for a previous line...
+ // terminating entry for a previous line...
if (pos != end_pos && pos->is_terminal_entry == false) {
uint32_t match_idx = std::distance(begin_pos, pos);
success = ConvertEntryAtIndexToLineEntry(match_idx, line_entry);
@@ -304,8 +295,7 @@ uint32_t LineTable::FindLineEntryIndexByFileIndex(
continue;
// Exact match always wins. Otherwise try to find the closest line > the
- // desired
- // line.
+ // desired line.
// FIXME: Maybe want to find the line closest before and the line closest
// after and
// if they're not in the same function, don't return a match.
@@ -349,8 +339,7 @@ uint32_t LineTable::FindLineEntryIndexByFileIndex(uint32_t start_idx,
continue;
// Exact match always wins. Otherwise try to find the closest line > the
- // desired
- // line.
+ // desired line.
// FIXME: Maybe want to find the line closest before and the line closest
// after and
// if they're not in the same function, don't return a match.
@@ -389,8 +378,8 @@ size_t LineTable::FineLineEntriesForFileIndex(uint32_t file_idx, bool append,
SymbolContext sc(m_comp_unit);
for (size_t idx = 0; idx < count; ++idx) {
- // Skip line table rows that terminate the previous row (is_terminal_entry
- // is non-zero)
+ // Skip line table rows that terminate the previous row
+ // (is_terminal_entry is non-zero)
if (m_entries[idx].is_terminal_entry)
continue;
@@ -497,10 +486,9 @@ LineTable *LineTable::LinkLineTable(const FileRangeMap &file_range_map) {
terminate_previous_entry = prev_entry_was_linked;
}
} else if (prev_entry_was_linked) {
- // This entry doesn't have a remapping and it needs to be removed.
- // Watch out in case we need to terminate a previous entry needs to
- // be terminated now that one line entry in a sequence is not longer
- // valid.
+ // This entry doesn't have a remapping and it needs to be removed. Watch
+ // out in case we need to terminate a previous entry needs to be
+ // terminated now that one line entry in a sequence is not longer valid.
if (!sequence.m_entries.empty() &&
!sequence.m_entries.back().is_terminal_entry) {
terminate_previous_entry = true;
diff --git a/source/Symbol/ObjectFile.cpp b/source/Symbol/ObjectFile.cpp
index 2129a4463cdd..59012b1f8261 100644
--- a/source/Symbol/ObjectFile.cpp
+++ b/source/Symbol/ObjectFile.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "lldb/Symbol/ObjectFile.h"
-#include "Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
@@ -16,7 +15,6 @@
#include "lldb/Symbol/ObjectContainer.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Target/Process.h"
-#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataBuffer.h"
@@ -51,10 +49,9 @@ ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file,
const bool file_exists = file->Exists();
if (!data_sp) {
- // We have an object name which most likely means we have
- // a .o file in a static archive (.a file). Try and see if
- // we have a cached archive first without reading any data
- // first
+ // We have an object name which most likely means we have a .o file in
+ // a static archive (.a file). Try and see if we have a cached archive
+ // first without reading any data first
if (file_exists && module_sp->GetObjectName()) {
for (uint32_t idx = 0;
(create_object_container_callback =
@@ -73,10 +70,10 @@ ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file,
return object_file_sp;
}
}
- // Ok, we didn't find any containers that have a named object, now
- // lets read the first 512 bytes from the file so the object file
- // and object container plug-ins can use these bytes to see if they
- // can parse this file.
+ // Ok, we didn't find any containers that have a named object, now lets
+ // read the first 512 bytes from the file so the object file and object
+ // container plug-ins can use these bytes to see if they can parse this
+ // file.
if (file_size > 0) {
data_sp =
DataBufferLLVM::CreateSliceFromPath(file->GetPath(), 512, file_offset);
@@ -99,11 +96,12 @@ ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file,
file = &archive_file;
module_sp->SetFileSpecAndObjectName(archive_file, archive_object);
// Check if this is a object container by iterating through all
- // object
- // container plugin instances and then trying to get an object file
- // from the container plugins since we had a name. Also, don't read
+ // object container plugin instances and then trying to get an
+ // object file from the container plugins since we had a name.
+ // Also, don't read
// ANY data in case there is data cached in the container plug-ins
- // (like BSD archives caching the contained objects within an file).
+ // (like BSD archives caching the contained objects within an
+ // file).
for (uint32_t idx = 0;
(create_object_container_callback =
PluginManager::GetObjectContainerCreateCallbackAtIndex(
@@ -120,8 +118,8 @@ ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file,
if (object_file_sp.get())
return object_file_sp;
}
- // We failed to find any cached object files in the container
- // plug-ins, so lets read the first 512 bytes and try again below...
+ // We failed to find any cached object files in the container plug-
+ // ins, so lets read the first 512 bytes and try again below...
data_sp = DataBufferLLVM::CreateSliceFromPath(archive_file.GetPath(),
512, file_offset);
}
@@ -129,8 +127,8 @@ ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file,
}
if (data_sp && data_sp->GetByteSize() > 0) {
- // Check if this is a normal object file by iterating through
- // all object file plugin instances.
+ // Check if this is a normal object file by iterating through all
+ // object file plugin instances.
ObjectFileCreateInstance create_object_file_callback;
for (uint32_t idx = 0;
(create_object_file_callback =
@@ -143,9 +141,9 @@ ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file,
return object_file_sp;
}
- // Check if this is a object container by iterating through
- // all object container plugin instances and then trying to get
- // an object file from the container.
+ // Check if this is a object container by iterating through all object
+ // container plugin instances and then trying to get an object file
+ // from the container.
for (uint32_t idx = 0;
(create_object_container_callback =
PluginManager::GetObjectContainerCreateCallbackAtIndex(
@@ -164,8 +162,8 @@ ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file,
}
}
}
- // We didn't find it, so clear our shared pointer in case it
- // contains anything and return an empty shared pointer
+ // We didn't find it, so clear our shared pointer in case it contains
+ // anything and return an empty shared pointer
object_file_sp.reset();
return object_file_sp;
}
@@ -186,8 +184,8 @@ ObjectFileSP ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp,
static_cast<void *>(process_sp.get()), header_addr);
uint32_t idx;
- // Check if this is a normal object file by iterating through
- // all object file plugin instances.
+ // Check if this is a normal object file by iterating through all object
+ // file plugin instances.
ObjectFileCreateMemoryInstance create_callback;
for (idx = 0;
(create_callback =
@@ -201,8 +199,8 @@ ObjectFileSP ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp,
}
}
- // We didn't find it, so clear our shared pointer in case it
- // contains anything and return an empty shared pointer
+ // We didn't find it, so clear our shared pointer in case it contains
+ // anything and return an empty shared pointer
object_file_sp.reset();
return object_file_sp;
}
@@ -326,11 +324,11 @@ AddressClass ObjectFile::GetAddressClass(addr_t file_addr) {
const SectionType section_type = section_sp->GetType();
switch (section_type) {
case eSectionTypeInvalid:
- return eAddressClassUnknown;
+ return AddressClass::eUnknown;
case eSectionTypeCode:
- return eAddressClassCode;
+ return AddressClass::eCode;
case eSectionTypeContainer:
- return eAddressClassUnknown;
+ return AddressClass::eUnknown;
case eSectionTypeData:
case eSectionTypeDataCString:
case eSectionTypeDataCStringPointers:
@@ -343,7 +341,7 @@ AddressClass ObjectFile::GetAddressClass(addr_t file_addr) {
case eSectionTypeDataObjCMessageRefs:
case eSectionTypeDataObjCCFStrings:
case eSectionTypeGoSymtab:
- return eAddressClassData;
+ return AddressClass::eData;
case eSectionTypeDebug:
case eSectionTypeDWARFDebugAbbrev:
case eSectionTypeDWARFDebugAddr:
@@ -355,33 +353,34 @@ AddressClass ObjectFile::GetAddressClass(addr_t file_addr) {
case eSectionTypeDWARFDebugLoc:
case eSectionTypeDWARFDebugMacInfo:
case eSectionTypeDWARFDebugMacro:
+ case eSectionTypeDWARFDebugNames:
case eSectionTypeDWARFDebugPubNames:
case eSectionTypeDWARFDebugPubTypes:
case eSectionTypeDWARFDebugRanges:
case eSectionTypeDWARFDebugStr:
case eSectionTypeDWARFDebugStrOffsets:
+ case eSectionTypeDWARFDebugTypes:
case eSectionTypeDWARFAppleNames:
case eSectionTypeDWARFAppleTypes:
case eSectionTypeDWARFAppleNamespaces:
case eSectionTypeDWARFAppleObjC:
- return eAddressClassDebug;
+ case eSectionTypeDWARFGNUDebugAltLink:
+ return AddressClass::eDebug;
case eSectionTypeEHFrame:
case eSectionTypeARMexidx:
case eSectionTypeARMextab:
case eSectionTypeCompactUnwind:
- return eAddressClassRuntime;
+ return AddressClass::eRuntime;
case eSectionTypeELFSymbolTable:
case eSectionTypeELFDynamicSymbols:
case eSectionTypeELFRelocationEntries:
case eSectionTypeELFDynamicLinkInfo:
case eSectionTypeOther:
- return eAddressClassUnknown;
+ return AddressClass::eUnknown;
case eSectionTypeAbsoluteAddress:
// In case of absolute sections decide the address class based on
- // the symbol
- // type because the section type isn't specify if it is a code or a
- // data
- // section.
+ // the symbol type because the section type isn't specify if it is
+ // a code or a data section.
break;
}
}
@@ -390,67 +389,67 @@ AddressClass ObjectFile::GetAddressClass(addr_t file_addr) {
const SymbolType symbol_type = symbol->GetType();
switch (symbol_type) {
case eSymbolTypeAny:
- return eAddressClassUnknown;
+ return AddressClass::eUnknown;
case eSymbolTypeAbsolute:
- return eAddressClassUnknown;
+ return AddressClass::eUnknown;
case eSymbolTypeCode:
- return eAddressClassCode;
+ return AddressClass::eCode;
case eSymbolTypeTrampoline:
- return eAddressClassCode;
+ return AddressClass::eCode;
case eSymbolTypeResolver:
- return eAddressClassCode;
+ return AddressClass::eCode;
case eSymbolTypeData:
- return eAddressClassData;
+ return AddressClass::eData;
case eSymbolTypeRuntime:
- return eAddressClassRuntime;
+ return AddressClass::eRuntime;
case eSymbolTypeException:
- return eAddressClassRuntime;
+ return AddressClass::eRuntime;
case eSymbolTypeSourceFile:
- return eAddressClassDebug;
+ return AddressClass::eDebug;
case eSymbolTypeHeaderFile:
- return eAddressClassDebug;
+ return AddressClass::eDebug;
case eSymbolTypeObjectFile:
- return eAddressClassDebug;
+ return AddressClass::eDebug;
case eSymbolTypeCommonBlock:
- return eAddressClassDebug;
+ return AddressClass::eDebug;
case eSymbolTypeBlock:
- return eAddressClassDebug;
+ return AddressClass::eDebug;
case eSymbolTypeLocal:
- return eAddressClassData;
+ return AddressClass::eData;
case eSymbolTypeParam:
- return eAddressClassData;
+ return AddressClass::eData;
case eSymbolTypeVariable:
- return eAddressClassData;
+ return AddressClass::eData;
case eSymbolTypeVariableType:
- return eAddressClassDebug;
+ return AddressClass::eDebug;
case eSymbolTypeLineEntry:
- return eAddressClassDebug;
+ return AddressClass::eDebug;
case eSymbolTypeLineHeader:
- return eAddressClassDebug;
+ return AddressClass::eDebug;
case eSymbolTypeScopeBegin:
- return eAddressClassDebug;
+ return AddressClass::eDebug;
case eSymbolTypeScopeEnd:
- return eAddressClassDebug;
+ return AddressClass::eDebug;
case eSymbolTypeAdditional:
- return eAddressClassUnknown;
+ return AddressClass::eUnknown;
case eSymbolTypeCompiler:
- return eAddressClassDebug;
+ return AddressClass::eDebug;
case eSymbolTypeInstrumentation:
- return eAddressClassDebug;
+ return AddressClass::eDebug;
case eSymbolTypeUndefined:
- return eAddressClassUnknown;
+ return AddressClass::eUnknown;
case eSymbolTypeObjCClass:
- return eAddressClassRuntime;
+ return AddressClass::eRuntime;
case eSymbolTypeObjCMetaClass:
- return eAddressClassRuntime;
+ return AddressClass::eRuntime;
case eSymbolTypeObjCIVar:
- return eAddressClassRuntime;
+ return AddressClass::eRuntime;
case eSymbolTypeReExported:
- return eAddressClassRuntime;
+ return AddressClass::eRuntime;
}
}
}
- return eAddressClassUnknown;
+ return AddressClass::eUnknown;
}
DataBufferSP ObjectFile::ReadMemory(const ProcessSP &process_sp,
@@ -470,16 +469,14 @@ DataBufferSP ObjectFile::ReadMemory(const ProcessSP &process_sp,
size_t ObjectFile::GetData(lldb::offset_t offset, size_t length,
DataExtractor &data) const {
// The entire file has already been mmap'ed into m_data, so just copy from
- // there
- // as the back mmap buffer will be shared with shared pointers.
+ // there as the back mmap buffer will be shared with shared pointers.
return data.SetData(m_data, offset, length);
}
size_t ObjectFile::CopyData(lldb::offset_t offset, size_t length,
void *dst) const {
// The entire file has already been mmap'ed into m_data, so just copy from
- // there
- // Note that the data remains in target byte order.
+ // there Note that the data remains in target byte order.
return m_data.CopyData(offset, length, dst);
}
@@ -559,8 +556,8 @@ size_t ObjectFile::ReadSectionData(Section *section,
return GetData(section->GetFileOffset(), section->GetFileSize(),
section_data);
} else {
- // The object file now contains a full mmap'ed copy of the object file data,
- // so just use this
+ // The object file now contains a full mmap'ed copy of the object file
+ // data, so just use this
if (!section->IsRelocated())
RelocateSection(section);
@@ -581,7 +578,7 @@ bool ObjectFile::SplitArchivePathWithObject(const char *path_with_object,
std::string obj;
if (regex_match.GetMatchAtIndex(path_with_object, 1, path) &&
regex_match.GetMatchAtIndex(path_with_object, 2, obj)) {
- archive_file.SetFile(path, false);
+ archive_file.SetFile(path, false, FileSpec::Style::native);
archive_object.SetCString(obj.c_str());
if (must_exist && !archive_file.Exists())
return false;
@@ -648,41 +645,31 @@ ConstString ObjectFile::GetNextSyntheticSymbolName() {
return ConstString(ss.GetString());
}
-Status ObjectFile::LoadInMemory(Target &target, bool set_pc) {
- Status error;
- ProcessSP process = target.CalculateProcess();
- if (!process)
- return Status("No Process");
- if (set_pc && !GetEntryPointAddress().IsValid())
- return Status("No entry address in object file");
-
+std::vector<ObjectFile::LoadableData>
+ObjectFile::GetLoadableData(Target &target) {
+ std::vector<LoadableData> loadables;
SectionList *section_list = GetSectionList();
if (!section_list)
- return Status("No section in object file");
+ return loadables;
+ // Create a list of loadable data from loadable sections
size_t section_count = section_list->GetNumSections(0);
for (size_t i = 0; i < section_count; ++i) {
+ LoadableData loadable;
SectionSP section_sp = section_list->GetSectionAtIndex(i);
- addr_t addr = target.GetSectionLoadList().GetSectionLoadAddress(section_sp);
- if (addr != LLDB_INVALID_ADDRESS) {
- DataExtractor section_data;
- // We can skip sections like bss
- if (section_sp->GetFileSize() == 0)
- continue;
- section_sp->GetSectionData(section_data);
- lldb::offset_t written = process->WriteMemory(
- addr, section_data.GetDataStart(), section_data.GetByteSize(), error);
- if (written != section_data.GetByteSize())
- return error;
- }
- }
- if (set_pc) {
- ThreadList &thread_list = process->GetThreadList();
- ThreadSP curr_thread(thread_list.GetSelectedThread());
- RegisterContextSP reg_context(curr_thread->GetRegisterContext());
- Address file_entry = GetEntryPointAddress();
- reg_context->SetPC(file_entry.GetLoadAddress(&target));
+ loadable.Dest =
+ target.GetSectionLoadList().GetSectionLoadAddress(section_sp);
+ if (loadable.Dest == LLDB_INVALID_ADDRESS)
+ continue;
+ // We can skip sections like bss
+ if (section_sp->GetFileSize() == 0)
+ continue;
+ DataExtractor section_data;
+ section_sp->GetSectionData(section_data);
+ loadable.Contents = llvm::ArrayRef<uint8_t>(section_data.GetDataStart(),
+ section_data.GetByteSize());
+ loadables.push_back(loadable);
}
- return error;
+ return loadables;
}
void ObjectFile::RelocateSection(lldb_private::Section *section)
diff --git a/source/Symbol/Symbol.cpp b/source/Symbol/Symbol.cpp
index ab297ef330f2..69fd5424bd9a 100644
--- a/source/Symbol/Symbol.cpp
+++ b/source/Symbol/Symbol.cpp
@@ -122,9 +122,9 @@ ConstString Symbol::GetDisplayName() const {
ConstString Symbol::GetReExportedSymbolName() const {
if (m_type == eSymbolTypeReExported) {
- // For eSymbolTypeReExported, the "const char *" from a ConstString
- // is used as the offset in the address range base address. We can
- // then make this back into a string that is the re-exported name.
+ // For eSymbolTypeReExported, the "const char *" from a ConstString is used
+ // as the offset in the address range base address. We can then make this
+ // back into a string that is the re-exported name.
intptr_t str_ptr = m_addr_range.GetBaseAddress().GetOffset();
if (str_ptr != 0)
return ConstString((const char *)str_ptr);
@@ -136,9 +136,9 @@ ConstString Symbol::GetReExportedSymbolName() const {
FileSpec Symbol::GetReExportedSymbolSharedLibrary() const {
if (m_type == eSymbolTypeReExported) {
- // For eSymbolTypeReExported, the "const char *" from a ConstString
- // is used as the offset in the address range base address. We can
- // then make this back into a string that is the re-exported name.
+ // For eSymbolTypeReExported, the "const char *" from a ConstString is used
+ // as the offset in the address range base address. We can then make this
+ // back into a string that is the re-exported name.
intptr_t str_ptr = m_addr_range.GetByteSize();
if (str_ptr != 0)
return FileSpec((const char *)str_ptr, false);
@@ -148,15 +148,15 @@ FileSpec Symbol::GetReExportedSymbolSharedLibrary() const {
void Symbol::SetReExportedSymbolName(const ConstString &name) {
SetType(eSymbolTypeReExported);
- // For eSymbolTypeReExported, the "const char *" from a ConstString
- // is used as the offset in the address range base address.
+ // For eSymbolTypeReExported, the "const char *" from a ConstString is used
+ // as the offset in the address range base address.
m_addr_range.GetBaseAddress().SetOffset((uintptr_t)name.GetCString());
}
bool Symbol::SetReExportedSymbolSharedLibrary(const FileSpec &fspec) {
if (m_type == eSymbolTypeReExported) {
- // For eSymbolTypeReExported, the "const char *" from a ConstString
- // is used as the offset in the address range base address.
+ // For eSymbolTypeReExported, the "const char *" from a ConstString is used
+ // as the offset in the address range base address.
m_addr_range.SetByteSize(
(uintptr_t)ConstString(fspec.GetPath().c_str()).GetCString());
return true;
@@ -262,9 +262,8 @@ uint32_t Symbol::GetPrologueByteSize() {
Function *function = base_address.CalculateSymbolContextFunction();
if (function) {
// Functions have line entries which can also potentially have end of
- // prologue information.
- // So if this symbol points to a function, use the prologue information
- // from there.
+ // prologue information. So if this symbol points to a function, use
+ // the prologue information from there.
m_type_data = function->GetPrologueByteSize();
} else {
ModuleSP module_sp(base_address.GetModule());
@@ -280,10 +279,9 @@ uint32_t Symbol::GetPrologueByteSize() {
Address addr(base_address);
addr.Slide(m_type_data);
- // Check the first few instructions and look for one that has a line
- // number that is
- // different than the first entry. This is also done in
- // Function::GetPrologueByteSize().
+ // Check the first few instructions and look for one that has a
+ // line number that is different than the first entry. This is also
+ // done in Function::GetPrologueByteSize().
uint16_t total_offset = m_type_data;
for (int idx = 0; idx < 6; ++idx) {
SymbolContext sc_temp;
@@ -293,8 +291,8 @@ uint32_t Symbol::GetPrologueByteSize() {
if (!(resolved_flags & eSymbolContextLineEntry))
break;
- // If this line number is different than our first one, use it and
- // we're done.
+ // If this line number is different than our first one, use it
+ // and we're done.
if (sc_temp.line_entry.line != sc.line_entry.line) {
m_type_data = total_offset;
break;
@@ -309,12 +307,10 @@ uint32_t Symbol::GetPrologueByteSize() {
}
// Sanity check - this may be a function in the middle of code that
- // has debug information, but
- // not for this symbol. So the line entries surrounding us won't
- // lie inside our function.
- // In that case, the line entry will be bigger than we are, so we do
- // that quick check and
- // if that is true, we just return 0.
+ // has debug information, but not for this symbol. So the line
+ // entries surrounding us won't lie inside our function. In that
+ // case, the line entry will be bigger than we are, so we do that
+ // quick check and if that is true, we just return 0.
if (m_type_data >= m_addr_range.GetByteSize())
m_type_data = 0;
} else {
@@ -420,9 +416,9 @@ Symbol *Symbol::ResolveReExportedSymbolInModuleSpec(
// Try searching for the module file spec first using the full path
module_sp = target.GetImages().FindFirstModule(module_spec);
if (!module_sp) {
- // Next try and find the module by basename in case environment
- // variables or other runtime trickery causes shared libraries
- // to be loaded from alternate paths
+ // Next try and find the module by basename in case environment variables
+ // or other runtime trickery causes shared libraries to be loaded from
+ // alternate paths
module_spec.GetFileSpec().GetDirectory().Clear();
module_sp = target.GetImages().FindFirstModule(module_spec);
}
@@ -430,8 +426,7 @@ Symbol *Symbol::ResolveReExportedSymbolInModuleSpec(
if (module_sp) {
// There should not be cycles in the reexport list, but we don't want to
- // crash if there are so make sure
- // we haven't seen this before:
+ // crash if there are so make sure we haven't seen this before:
if (!seen_modules.AppendIfNeeded(module_sp))
return nullptr;
@@ -449,8 +444,8 @@ Symbol *Symbol::ResolveReExportedSymbolInModuleSpec(
}
}
// If we didn't find the symbol in this module, it may be because this
- // module re-exports some
- // whole other library. We have to search those as well:
+ // module re-exports some whole other library. We have to search those as
+ // well:
seen_modules.Append(module_sp);
FileSpecList reexported_libraries =
diff --git a/source/Symbol/SymbolContext.cpp b/source/Symbol/SymbolContext.cpp
index 4ac35010c74c..8716f50a384d 100644
--- a/source/Symbol/SymbolContext.cpp
+++ b/source/Symbol/SymbolContext.cpp
@@ -359,8 +359,7 @@ void SymbolContext::Dump(Stream *s, Target *target) const {
if (block != nullptr)
*s << " {0x" << block->GetID() << '}';
// Dump the block and pass it a negative depth to we print all the parent
- // blocks
- // if (block != NULL)
+ // blocks if (block != NULL)
// block->Dump(s, function->GetFileAddress(), INT_MIN);
s->EOL();
s->Indent();
@@ -468,27 +467,27 @@ bool SymbolContext::GetParentOfInlinedScope(const Address &curr_frame_pc,
if (block) {
// const addr_t curr_frame_file_addr = curr_frame_pc.GetFileAddress();
- // In order to get the parent of an inlined function we first need to
- // see if we are in an inlined block as "this->block" could be an
- // inlined block, or a parent of "block" could be. So lets check if
- // this block or one of this blocks parents is an inlined function.
+ // In order to get the parent of an inlined function we first need to see
+ // if we are in an inlined block as "this->block" could be an inlined
+ // block, or a parent of "block" could be. So lets check if this block or
+ // one of this blocks parents is an inlined function.
Block *curr_inlined_block = block->GetContainingInlinedBlock();
if (curr_inlined_block) {
- // "this->block" is contained in an inline function block, so to
- // get the scope above the inlined block, we get the parent of the
- // inlined block itself
+ // "this->block" is contained in an inline function block, so to get the
+ // scope above the inlined block, we get the parent of the inlined block
+ // itself
Block *next_frame_block = curr_inlined_block->GetParent();
// Now calculate the symbol context of the containing block
next_frame_block->CalculateSymbolContext(&next_frame_sc);
// If we get here we weren't able to find the return line entry using the
- // nesting of the blocks and
- // the line table. So just use the call site info from our inlined block.
+ // nesting of the blocks and the line table. So just use the call site
+ // info from our inlined block.
AddressRange range;
if (curr_inlined_block->GetRangeContainingAddress(curr_frame_pc, range)) {
- // To see there this new frame block it, we need to look at the
- // call site information from
+ // To see there this new frame block it, we need to look at the call
+ // site information from
const InlineFunctionInfo *curr_inlined_block_inlined_info =
curr_inlined_block->GetInlinedFunctionInfo();
next_frame_pc = range.GetBaseAddress();
@@ -550,22 +549,22 @@ bool SymbolContext::GetParentOfInlinedScope(const Address &curr_frame_pc,
Block *SymbolContext::GetFunctionBlock() {
if (function) {
if (block) {
- // If this symbol context has a block, check to see if this block
- // is itself, or is contained within a block with inlined function
- // information. If so, then the inlined block is the block that
- // defines the function.
+ // If this symbol context has a block, check to see if this block is
+ // itself, or is contained within a block with inlined function
+ // information. If so, then the inlined block is the block that defines
+ // the function.
Block *inlined_block = block->GetContainingInlinedBlock();
if (inlined_block)
return inlined_block;
- // The block in this symbol context is not inside an inlined
- // block, so the block that defines the function is the function's
- // top level block, which is returned below.
+ // The block in this symbol context is not inside an inlined block, so
+ // the block that defines the function is the function's top level block,
+ // which is returned below.
}
- // There is no block information in this symbol context, so we must
- // assume that the block that is desired is the top level block of
- // the function itself.
+ // There is no block information in this symbol context, so we must assume
+ // that the block that is desired is the top level block of the function
+ // itself.
return &function->GetBlock(true);
}
return nullptr;
@@ -594,8 +593,8 @@ void SymbolContext::SortTypeList(TypeMap &type_map, TypeList &type_list) const {
isInlinedblock = true;
//----------------------------------------------------------------------
- // Find all types that match the current block if we have one and put
- // them first in the list. Keep iterating up through all blocks.
+ // Find all types that match the current block if we have one and put them
+ // first in the list. Keep iterating up through all blocks.
//----------------------------------------------------------------------
while (curr_block != nullptr && !isInlinedblock) {
type_map.ForEach(
@@ -606,8 +605,8 @@ void SymbolContext::SortTypeList(TypeMap &type_map, TypeList &type_list) const {
return true; // Keep iterating
});
- // Remove any entries that are now in "type_list" from "type_map"
- // since we can't remove from type_map while iterating
+ // Remove any entries that are now in "type_list" from "type_map" since we
+ // can't remove from type_map while iterating
type_list.ForEach([&type_map](const lldb::TypeSP &type_sp) -> bool {
type_map.Remove(type_sp);
return true; // Keep iterating
@@ -615,8 +614,8 @@ void SymbolContext::SortTypeList(TypeMap &type_map, TypeList &type_list) const {
curr_block = curr_block->GetParent();
}
//----------------------------------------------------------------------
- // Find all types that match the current function, if we have onem, and
- // put them next in the list.
+ // Find all types that match the current function, if we have onem, and put
+ // them next in the list.
//----------------------------------------------------------------------
if (function != nullptr && !type_map.Empty()) {
const size_t old_type_list_size = type_list.GetSize();
@@ -627,8 +626,8 @@ void SymbolContext::SortTypeList(TypeMap &type_map, TypeList &type_list) const {
return true; // Keep iterating
});
- // Remove any entries that are now in "type_list" from "type_map"
- // since we can't remove from type_map while iterating
+ // Remove any entries that are now in "type_list" from "type_map" since we
+ // can't remove from type_map while iterating
const size_t new_type_list_size = type_list.GetSize();
if (new_type_list_size > old_type_list_size) {
for (size_t i = old_type_list_size; i < new_type_list_size; ++i)
@@ -636,8 +635,8 @@ void SymbolContext::SortTypeList(TypeMap &type_map, TypeList &type_list) const {
}
}
//----------------------------------------------------------------------
- // Find all types that match the current compile unit, if we have one,
- // and put them next in the list.
+ // Find all types that match the current compile unit, if we have one, and
+ // put them next in the list.
//----------------------------------------------------------------------
if (comp_unit != nullptr && !type_map.Empty()) {
const size_t old_type_list_size = type_list.GetSize();
@@ -649,8 +648,8 @@ void SymbolContext::SortTypeList(TypeMap &type_map, TypeList &type_list) const {
return true; // Keep iterating
});
- // Remove any entries that are now in "type_list" from "type_map"
- // since we can't remove from type_map while iterating
+ // Remove any entries that are now in "type_list" from "type_map" since we
+ // can't remove from type_map while iterating
const size_t new_type_list_size = type_list.GetSize();
if (new_type_list_size > old_type_list_size) {
for (size_t i = old_type_list_size; i < new_type_list_size; ++i)
@@ -658,8 +657,8 @@ void SymbolContext::SortTypeList(TypeMap &type_map, TypeList &type_list) const {
}
}
//----------------------------------------------------------------------
- // Find all types that match the current module, if we have one, and put
- // them next in the list.
+ // Find all types that match the current module, if we have one, and put them
+ // next in the list.
//----------------------------------------------------------------------
if (module_sp && !type_map.Empty()) {
const size_t old_type_list_size = type_list.GetSize();
@@ -669,8 +668,8 @@ void SymbolContext::SortTypeList(TypeMap &type_map, TypeList &type_list) const {
type_list.Insert(type_sp);
return true; // Keep iterating
});
- // Remove any entries that are now in "type_list" from "type_map"
- // since we can't remove from type_map while iterating
+ // Remove any entries that are now in "type_list" from "type_map" since we
+ // can't remove from type_map while iterating
const size_t new_type_list_size = type_list.GetSize();
if (new_type_list_size > old_type_list_size) {
for (size_t i = old_type_list_size; i < new_type_list_size; ++i)
@@ -831,9 +830,9 @@ SymbolContext::FindBestGlobalDataSymbol(const ConstString &name, Status &error)
case eSymbolTypeObjCMetaClass:
case eSymbolTypeObjCIVar:
if (symbol->GetDemangledNameIsSynthesized()) {
- // If the demangled name was synthesized, then don't use it
- // for expressions. Only let the symbol match if the mangled
- // named matches for these symbols.
+ // If the demangled name was synthesized, then don't use it for
+ // expressions. Only let the symbol match if the mangled named
+ // matches for these symbols.
if (symbol->GetMangled().GetMangledName() != name)
break;
}
@@ -861,8 +860,8 @@ SymbolContext::FindBestGlobalDataSymbol(const ConstString &name, Status &error)
target.GetImages().FindFirstModule(reexport_module_spec);
}
}
- // Don't allow us to try and resolve a re-exported symbol if it is
- // the same as the current symbol
+ // Don't allow us to try and resolve a re-exported symbol if it
+ // is the same as the current symbol
if (name == symbol->GetReExportedSymbolName() &&
module == reexport_module_sp.get())
return nullptr;
@@ -1012,9 +1011,8 @@ bool SymbolContextSpecifier::AddSpecification(const char *spec_string,
} break;
case eFileSpecified:
// CompUnits can't necessarily be resolved here, since an inlined function
- // might show up in
- // a number of CompUnits. Instead we just convert to a FileSpec and store
- // it away.
+ // might show up in a number of CompUnits. Instead we just convert to a
+ // FileSpec and store it away.
m_file_spec_ap.reset(new FileSpec(spec_string, false));
m_type |= eFileSpecified;
break;
diff --git a/source/Symbol/SymbolFile.cpp b/source/Symbol/SymbolFile.cpp
index eb20b80f4916..6b4da9c53009 100644
--- a/source/Symbol/SymbolFile.cpp
+++ b/source/Symbol/SymbolFile.cpp
@@ -30,8 +30,7 @@ SymbolFile *SymbolFile::FindPlugin(ObjectFile *obj_file) {
if (obj_file != nullptr) {
// We need to test the abilities of this section list. So create what it
- // would
- // be with this new obj_file.
+ // would be with this new obj_file.
lldb::ModuleSP module_sp(obj_file->GetModule());
if (module_sp) {
// Default to the main module section list.
@@ -60,16 +59,16 @@ SymbolFile *SymbolFile::FindPlugin(ObjectFile *obj_file) {
if (sym_file_abilities > best_symfile_abilities) {
best_symfile_abilities = sym_file_abilities;
best_symfile_ap.reset(curr_symfile_ap.release());
- // If any symbol file parser has all of the abilities, then
- // we should just stop looking.
+ // If any symbol file parser has all of the abilities, then we should
+ // just stop looking.
if ((kAllAbilities & sym_file_abilities) == kAllAbilities)
break;
}
}
}
if (best_symfile_ap.get()) {
- // Let the winning symbol file parser initialize itself more
- // completely now that it has been chosen
+ // Let the winning symbol file parser initialize itself more completely
+ // now that it has been chosen
best_symfile_ap->InitializeObject();
}
}
@@ -97,19 +96,16 @@ uint32_t SymbolFile::ResolveSymbolContext(const FileSpec &file_spec,
return 0;
}
-uint32_t SymbolFile::FindGlobalVariables(
- const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches, VariableList &variables) {
- if (!append)
- variables.Clear();
+uint32_t
+SymbolFile::FindGlobalVariables(const ConstString &name,
+ const CompilerDeclContext *parent_decl_ctx,
+ uint32_t max_matches, VariableList &variables) {
return 0;
}
uint32_t SymbolFile::FindGlobalVariables(const RegularExpression &regex,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
VariableList &variables) {
- if (!append)
- variables.Clear();
return 0;
}
diff --git a/source/Symbol/SymbolVendor.cpp b/source/Symbol/SymbolVendor.cpp
index f5a08739f24d..245f7bbf8add 100644
--- a/source/Symbol/SymbolVendor.cpp
+++ b/source/Symbol/SymbolVendor.cpp
@@ -26,9 +26,9 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// FindPlugin
//
-// Platforms can register a callback to use when creating symbol
-// vendors to allow for complex debug information file setups, and to
-// also allow for finding separate debug information files.
+// Platforms can register a callback to use when creating symbol vendors to
+// allow for complex debug information file setups, and to also allow for
+// finding separate debug information files.
//----------------------------------------------------------------------
SymbolVendor *SymbolVendor::FindPlugin(const lldb::ModuleSP &module_sp,
lldb_private::Stream *feedback_strm) {
@@ -45,8 +45,8 @@ SymbolVendor *SymbolVendor::FindPlugin(const lldb::ModuleSP &module_sp,
return instance_ap.release();
}
}
- // The default implementation just tries to create debug information using the
- // file representation for the module.
+ // The default implementation just tries to create debug information using
+ // the file representation for the module.
instance_ap.reset(new SymbolVendor(module_sp));
if (instance_ap.get()) {
ObjectFile *objfile = module_sp->GetObjectFile();
@@ -88,11 +88,11 @@ bool SymbolVendor::SetCompileUnitAtIndex(size_t idx, const CompUnitSP &cu_sp) {
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
const size_t num_compile_units = GetNumCompileUnits();
if (idx < num_compile_units) {
- // Fire off an assertion if this compile unit already exists for now.
- // The partial parsing should take care of only setting the compile
- // unit once, so if this assertion fails, we need to make sure that
- // we don't have a race condition, or have a second parse of the same
- // compile unit.
+ // Fire off an assertion if this compile unit already exists for now. The
+ // partial parsing should take care of only setting the compile unit
+ // once, so if this assertion fails, we need to make sure that we don't
+ // have a race condition, or have a second parse of the same compile
+ // unit.
assert(m_compile_units[idx].get() == nullptr);
m_compile_units[idx] = cu_sp;
return true;
@@ -111,10 +111,10 @@ size_t SymbolVendor::GetNumCompileUnits() {
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_compile_units.empty()) {
if (m_sym_file_ap.get()) {
- // Resize our array of compile unit shared pointers -- which will
- // each remain NULL until someone asks for the actual compile unit
- // information. When this happens, the symbol file will be asked
- // to parse this compile unit information.
+ // Resize our array of compile unit shared pointers -- which will each
+ // remain NULL until someone asks for the actual compile unit
+ // information. When this happens, the symbol file will be asked to
+ // parse this compile unit information.
m_compile_units.resize(m_sym_file_ap->GetNumCompileUnits());
}
}
@@ -260,28 +260,28 @@ uint32_t SymbolVendor::ResolveSymbolContext(const FileSpec &file_spec,
return 0;
}
-size_t SymbolVendor::FindGlobalVariables(
- const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
- bool append, size_t max_matches, VariableList &variables) {
+size_t
+SymbolVendor::FindGlobalVariables(const ConstString &name,
+ const CompilerDeclContext *parent_decl_ctx,
+ size_t max_matches, VariableList &variables) {
ModuleSP module_sp(GetModule());
if (module_sp) {
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
- return m_sym_file_ap->FindGlobalVariables(name, parent_decl_ctx, append,
+ return m_sym_file_ap->FindGlobalVariables(name, parent_decl_ctx,
max_matches, variables);
}
return 0;
}
size_t SymbolVendor::FindGlobalVariables(const RegularExpression &regex,
- bool append, size_t max_matches,
+ size_t max_matches,
VariableList &variables) {
ModuleSP module_sp(GetModule());
if (module_sp) {
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
- return m_sym_file_ap->FindGlobalVariables(regex, append, max_matches,
- variables);
+ return m_sym_file_ap->FindGlobalVariables(regex, max_matches, variables);
}
return 0;
}
@@ -392,6 +392,8 @@ void SymbolVendor::Dump(Stream *s) {
}
}
s->EOL();
+ if (m_sym_file_ap)
+ m_sym_file_ap->Dump(*s);
s->IndentMore();
m_type_list.Dump(s, show_context);
diff --git a/source/Symbol/Symtab.cpp b/source/Symbol/Symtab.cpp
index 4ac30649110f..c502b18555f0 100644
--- a/source/Symbol/Symtab.cpp
+++ b/source/Symbol/Symtab.cpp
@@ -100,9 +100,8 @@ void Symtab::Dump(Stream *s, Target *target, SortOrder sort_order) {
} break;
case eSortOrderByName: {
- // Although we maintain a lookup by exact name map, the table
- // isn't sorted by name. So we must make the ordered symbol list
- // up ourselves.
+ // Although we maintain a lookup by exact name map, the table isn't
+ // sorted by name. So we must make the ordered symbol list up ourselves.
s->PutCString(" (sorted by name):\n");
DumpSymbolHeader(s);
typedef std::multimap<const char *, const Symbol *,
@@ -228,8 +227,8 @@ void Symtab::InitNameIndexes() {
m_name_to_index.Reserve(num_symbols);
#else
// TODO: benchmark this to see if we save any memory. Otherwise we
- // will always keep the memory reserved in the vector unless we pull
- // some STL swap magic and then recopy...
+ // will always keep the memory reserved in the vector unless we pull some
+ // STL swap magic and then recopy...
uint32_t actual_count = 0;
for (const_iterator pos = m_symbols.begin(), end = m_symbols.end();
pos != end; ++pos) {
@@ -255,11 +254,10 @@ void Symtab::InitNameIndexes() {
for (entry.value = 0; entry.value < num_symbols; ++entry.value) {
const Symbol *symbol = &m_symbols[entry.value];
- // Don't let trampolines get into the lookup by name map
- // If we ever need the trampoline symbols to be searchable by name
- // we can remove this and then possibly add a new bool to any of the
- // Symtab functions that lookup symbols by name to indicate if they
- // want trampolines.
+ // Don't let trampolines get into the lookup by name map If we ever need
+ // the trampoline symbols to be searchable by name we can remove this and
+ // then possibly add a new bool to any of the Symtab functions that
+ // lookup symbols by name to indicate if they want trampolines.
if (symbol->IsTrampoline())
continue;
@@ -293,10 +291,9 @@ void Symtab::InitNameIndexes() {
mangled.GetDemangledName(lldb::eLanguageTypeC_plus_plus));
entry.cstring = ConstString(cxx_method.GetBasename());
if (entry.cstring) {
- // ConstString objects permanently store the string in the pool so
- // calling
- // GetCString() on the value gets us a const char * that will
- // never go away
+ // ConstString objects permanently store the string in the pool
+ // so calling GetCString() on the value gets us a const char *
+ // that will never go away
const char *const_context =
ConstString(cxx_method.GetContext()).GetCString();
@@ -312,25 +309,25 @@ void Symtab::InitNameIndexes() {
if (entry_ref[0] == '~' ||
!cxx_method.GetQualifiers().empty()) {
// The first character of the demangled basename is '~' which
- // means we have a class destructor. We can use this information
- // to help us know what is a class and what isn't.
+ // means we have a class destructor. We can use this
+ // information to help us know what is a class and what
+ // isn't.
if (class_contexts.find(const_context) == class_contexts.end())
class_contexts.insert(const_context);
m_method_to_index.Append(entry);
} else {
if (class_contexts.find(const_context) !=
class_contexts.end()) {
- // The current decl context is in our "class_contexts" which
- // means
- // this is a method on a class
+ // The current decl context is in our "class_contexts"
+ // which means this is a method on a class
m_method_to_index.Append(entry);
} else {
- // We don't know if this is a function basename or a method,
- // so put it into a temporary collection so once we are done
- // we can look in class_contexts to see if each entry is a
- // class
- // or just a function and will put any remaining items into
- // m_method_to_index or m_basename_to_index as needed
+ // We don't know if this is a function basename or a
+ // method, so put it into a temporary collection so once we
+ // are done we can look in class_contexts to see if each
+ // entry is a class or just a function and will put any
+ // remaining items into m_method_to_index or
+ // m_basename_to_index as needed
mangled_name_to_index.Append(entry);
symbol_contexts[entry.value] = const_context;
}
@@ -354,9 +351,8 @@ void Symtab::InitNameIndexes() {
}
}
- // If the demangled name turns out to be an ObjC name, and
- // is a category name, add the version without categories to the index
- // too.
+ // If the demangled name turns out to be an ObjC name, and is a category
+ // name, add the version without categories to the index too.
ObjCLanguage::MethodName objc_method(entry.cstring.GetStringRef(), true);
if (objc_method.IsValid(true)) {
entry.cstring = objc_method.GetSelector();
@@ -383,8 +379,7 @@ void Symtab::InitNameIndexes() {
m_method_to_index.Append(entry);
} else {
// If we got here, we have something that had a context (was inside
- // a namespace or class)
- // yet we don't know if the entry
+ // a namespace or class) yet we don't know if the entry
m_method_to_index.Append(entry);
m_basename_to_index.Append(entry);
}
@@ -520,20 +515,15 @@ struct SymbolIndexComparator {
std::vector<lldb::addr_t> &addr_cache;
// Getting from the symbol to the Address to the File Address involves some
- // work.
- // Since there are potentially many symbols here, and we're using this for
- // sorting so
- // we're going to be computing the address many times, cache that in
- // addr_cache.
- // The array passed in has to be the same size as the symbols array passed
- // into the
- // member variable symbols, and should be initialized with
- // LLDB_INVALID_ADDRESS.
+ // work. Since there are potentially many symbols here, and we're using this
+ // for sorting so we're going to be computing the address many times, cache
+ // that in addr_cache. The array passed in has to be the same size as the
+ // symbols array passed into the member variable symbols, and should be
+ // initialized with LLDB_INVALID_ADDRESS.
// NOTE: You have to make addr_cache externally and pass it in because
// std::stable_sort
// makes copies of the comparator it is initially passed in, and you end up
- // spending
- // huge amounts of time copying this array...
+ // spending huge amounts of time copying this array...
SymbolIndexComparator(const std::vector<Symbol> &s,
std::vector<lldb::addr_t> &a)
@@ -584,8 +574,7 @@ void Symtab::SortSymbolIndexesByValue(std::vector<uint32_t> &indexes,
// NOTE: The use of std::stable_sort instead of std::sort here is strictly for
// performance,
// not correctness. The indexes vector tends to be "close" to sorted, which
- // the
- // stable sort handles better.
+ // the stable sort handles better.
std::vector<lldb::addr_t> addr_cache(m_symbols.size(), LLDB_INVALID_ADDRESS);
@@ -752,14 +741,14 @@ Symtab::FindAllSymbolsWithNameAndType(const ConstString &name,
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "%s", LLVM_PRETTY_FUNCTION);
- // Initialize all of the lookup by name indexes before converting NAME
- // to a uniqued string NAME_STR below.
+ // Initialize all of the lookup by name indexes before converting NAME to a
+ // uniqued string NAME_STR below.
if (!m_name_indexes_computed)
InitNameIndexes();
if (name) {
- // The string table did have a string that matched, but we need
- // to check the symbols and match the symbol_type if any was given.
+ // The string table did have a string that matched, but we need to check
+ // the symbols and match the symbol_type if any was given.
AppendSymbolIndexesWithNameAndType(name, symbol_type, symbol_indexes);
}
return symbol_indexes.size();
@@ -772,14 +761,14 @@ size_t Symtab::FindAllSymbolsWithNameAndType(
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "%s", LLVM_PRETTY_FUNCTION);
- // Initialize all of the lookup by name indexes before converting NAME
- // to a uniqued string NAME_STR below.
+ // Initialize all of the lookup by name indexes before converting NAME to a
+ // uniqued string NAME_STR below.
if (!m_name_indexes_computed)
InitNameIndexes();
if (name) {
- // The string table did have a string that matched, but we need
- // to check the symbols and match the symbol_type if any was given.
+ // The string table did have a string that matched, but we need to check
+ // the symbols and match the symbol_type if any was given.
AppendSymbolIndexesWithNameAndType(name, symbol_type, symbol_debug_type,
symbol_visibility, symbol_indexes);
}
@@ -810,8 +799,8 @@ Symbol *Symtab::FindFirstSymbolWithNameAndType(const ConstString &name,
if (name) {
std::vector<uint32_t> matching_indexes;
- // The string table did have a string that matched, but we need
- // to check the symbols and match the symbol_type if any was given.
+ // The string table did have a string that matched, but we need to check
+ // the symbols and match the symbol_type if any was given.
if (AppendSymbolIndexesWithNameAndType(name, symbol_type, symbol_debug_type,
symbol_visibility,
matching_indexes)) {
@@ -835,8 +824,8 @@ typedef struct {
addr_t match_offset;
} SymbolSearchInfo;
-// Add all the section file start address & size to the RangeVector,
-// recusively adding any children sections.
+// Add all the section file start address & size to the RangeVector, recusively
+// adding any children sections.
static void AddSectionsToRangeMap(SectionList *sectlist,
RangeVector<addr_t, addr_t> &section_ranges) {
const int num_sections = sectlist->GetNumSections(0);
@@ -885,9 +874,9 @@ void Symtab::InitAddressIndexes() {
// Create a RangeVector with the start & size of all the sections for
// this objfile. We'll need to check this for any FileRangeToIndexMap
- // entries with an uninitialized size, which could potentially be a
- // large number so reconstituting the weak pointer is busywork when it
- // is invariant information.
+ // entries with an uninitialized size, which could potentially be a large
+ // number so reconstituting the weak pointer is busywork when it is
+ // invariant information.
SectionList *sectlist = m_objfile->GetSectionList();
RangeVector<addr_t, addr_t> section_ranges;
if (sectlist) {
@@ -922,9 +911,8 @@ void Symtab::InitAddressIndexes() {
if (next_base_addr > curr_base_addr) {
addr_t size_to_next_symbol = next_base_addr - curr_base_addr;
- // Take the difference between this symbol and the next one as its
- // size,
- // if it is less than the size of the section.
+ // Take the difference between this symbol and the next one as
+ // its size, if it is less than the size of the section.
if (sym_size == 0 || size_to_next_symbol < sym_size) {
sym_size = size_to_next_symbol;
}
@@ -958,8 +946,7 @@ void Symtab::CalculateSymbolSizes() {
for (size_t i = 0; i < num_entries; ++i) {
// The entries in the m_file_addr_to_index have calculated the sizes
- // already
- // so we will use this size if we need to.
+ // already so we will use this size if we need to.
const FileRangeToIndexMap::Entry &entry =
m_file_addr_to_index.GetEntryRef(i);
@@ -1086,8 +1073,8 @@ size_t Symtab::FindFunctionSymbols(const ConstString &name,
}
if (name_type_mask & eFunctionNameTypeBase) {
- // From mangled names we can't tell what is a basename and what
- // is a method name, so we just treat them the same
+ // From mangled names we can't tell what is a basename and what is a method
+ // name, so we just treat them the same
if (!m_name_indexes_computed)
InitNameIndexes();
diff --git a/source/Symbol/Type.cpp b/source/Symbol/Type.cpp
index 53bf3e850055..b62c55f76e2b 100644
--- a/source/Symbol/Type.cpp
+++ b/source/Symbol/Type.cpp
@@ -387,8 +387,8 @@ bool Type::DumpValueInMemory(ExecutionContext *exe_ctx, Stream *s,
bool Type::ReadFromMemory(ExecutionContext *exe_ctx, lldb::addr_t addr,
AddressType address_type, DataExtractor &data) {
if (address_type == eAddressTypeFile) {
- // Can't convert a file address to anything valid without more
- // context (which Module it came from)
+ // Can't convert a file address to anything valid without more context
+ // (which Module it came from)
return false;
}
@@ -533,10 +533,8 @@ bool Type::ResolveClangType(ResolveState compiler_type_resolve_state) {
}
// When we have a EncodingUID, our "m_flags.compiler_type_resolve_state" is
- // set to eResolveStateUnresolved
- // so we need to update it to say that we now have a forward declaration
- // since that is what we created
- // above.
+ // set to eResolveStateUnresolved so we need to update it to say that we
+ // now have a forward declaration since that is what we created above.
if (m_compiler_type.IsValid())
m_flags.compiler_type_resolve_state = eResolveStateForward;
}
@@ -556,8 +554,8 @@ bool Type::ResolveClangType(ResolveState compiler_type_resolve_state) {
}
}
- // If we have an encoding type, then we need to make sure it is
- // resolved appropriately.
+ // If we have an encoding type, then we need to make sure it is resolved
+ // appropriately.
if (m_encoding_uid != LLDB_INVALID_UID) {
if (encoding_type == nullptr)
encoding_type = GetEncodingType();
@@ -847,35 +845,26 @@ TypeImpl &TypeImpl::operator=(const TypeImpl &rhs) {
}
bool TypeImpl::CheckModule(lldb::ModuleSP &module_sp) const {
- // Check if we have a module for this type. If we do and the shared pointer is
- // can be successfully initialized with m_module_wp, return true. Else return
- // false
- // if we didn't have a module, or if we had a module and it has been deleted.
- // Any
- // functions doing anything with a TypeSP in this TypeImpl class should call
- // this
- // function and only do anything with the ivars if this function returns true.
- // If
- // we have a module, the "module_sp" will be filled in with a strong reference
- // to the
- // module so that the module will at least stay around long enough for the
- // type
- // query to succeed.
+ // Check if we have a module for this type. If we do and the shared pointer
+ // is can be successfully initialized with m_module_wp, return true. Else
+ // return false if we didn't have a module, or if we had a module and it has
+ // been deleted. Any functions doing anything with a TypeSP in this TypeImpl
+ // class should call this function and only do anything with the ivars if
+ // this function returns true. If we have a module, the "module_sp" will be
+ // filled in with a strong reference to the module so that the module will at
+ // least stay around long enough for the type query to succeed.
module_sp = m_module_wp.lock();
if (!module_sp) {
lldb::ModuleWP empty_module_wp;
// If either call to "std::weak_ptr::owner_before(...) value returns true,
- // this
- // indicates that m_module_wp once contained (possibly still does) a
- // reference
- // to a valid shared pointer. This helps us know if we had a valid reference
- // to
- // a section which is now invalid because the module it was in was deleted
+ // this indicates that m_module_wp once contained (possibly still does) a
+ // reference to a valid shared pointer. This helps us know if we had a
+ // valid reference to a section which is now invalid because the module it
+ // was in was deleted
if (empty_module_wp.owner_before(m_module_wp) ||
m_module_wp.owner_before(empty_module_wp)) {
// m_module_wp had a valid reference to a module, but all strong
- // references
- // have been released and the module has been deleted
+ // references have been released and the module has been deleted
return false;
}
}
diff --git a/source/Symbol/TypeList.cpp b/source/Symbol/TypeList.cpp
index 4fcaff3daf90..4a0a06f3e8e3 100644
--- a/source/Symbol/TypeList.cpp
+++ b/source/Symbol/TypeList.cpp
@@ -32,7 +32,8 @@ TypeList::TypeList() : m_types() {}
TypeList::~TypeList() {}
void TypeList::Insert(const TypeSP &type_sp) {
- // Just push each type on the back for now. We will worry about uniquing later
+ // Just push each type on the back for now. We will worry about uniquing
+ // later
if (type_sp)
m_types.push_back(type_sp);
}
@@ -76,6 +77,7 @@ uint32_t TypeList::GetSize() const { return m_types.size(); }
TypeSP TypeList::GetTypeAtIndex(uint32_t idx) {
iterator pos, end;
uint32_t i = idx;
+ assert(i < GetSize() && "Accessing past the end of a TypeList");
for (pos = m_types.begin(), end = m_types.end(); pos != end; ++pos) {
if (i == 0)
return *pos;
@@ -123,10 +125,10 @@ void TypeList::RemoveMismatchedTypes(const char *qualified_typename,
void TypeList::RemoveMismatchedTypes(const std::string &type_scope,
const std::string &type_basename,
TypeClass type_class, bool exact_match) {
- // Our "collection" type currently is a std::map which doesn't
- // have any good way to iterate and remove items from the map
- // so we currently just make a new list and add all of the matching
- // types to it, and then swap it into m_types at the end
+ // Our "collection" type currently is a std::map which doesn't have any good
+ // way to iterate and remove items from the map so we currently just make a
+ // new list and add all of the matching types to it, and then swap it into
+ // m_types at the end
collection matching_types;
iterator pos, end = m_types.end();
@@ -161,19 +163,15 @@ void TypeList::RemoveMismatchedTypes(const std::string &type_scope,
if (type_scope_pos == match_type_scope_size - type_scope_size) {
if (type_scope_pos >= 2) {
// Our match scope ends with the type scope we were looking
- // for,
- // but we need to make sure what comes before the matching
- // type scope is a namespace boundary in case we are trying to
- // match:
- // type_basename = "d"
- // type_scope = "b::c::"
+ // for, but we need to make sure what comes before the
+ // matching type scope is a namespace boundary in case we are
+ // trying to match: type_basename = "d" type_scope = "b::c::"
// We want to match:
// match_type_scope "a::b::c::"
// But not:
// match_type_scope "a::bb::c::"
// So below we make sure what comes before "b::c::" in
- // match_type_scope
- // is "::", or the namespace boundary
+ // match_type_scope is "::", or the namespace boundary
if (match_type_scope[type_scope_pos - 1] == ':' &&
match_type_scope[type_scope_pos - 2] == ':') {
keep_match = true;
@@ -184,9 +182,8 @@ void TypeList::RemoveMismatchedTypes(const std::string &type_scope,
}
}
} else {
- // The type we are currently looking at doesn't exists
- // in a namespace or class, so it only matches if there
- // is no type scope...
+ // The type we are currently looking at doesn't exists in a namespace
+ // or class, so it only matches if there is no type scope...
keep_match =
type_scope.empty() && type_basename.compare(match_type_name) == 0;
}
@@ -203,10 +200,10 @@ void TypeList::RemoveMismatchedTypes(TypeClass type_class) {
if (type_class == eTypeClassAny)
return;
- // Our "collection" type currently is a std::map which doesn't
- // have any good way to iterate and remove items from the map
- // so we currently just make a new list and add all of the matching
- // types to it, and then swap it into m_types at the end
+ // Our "collection" type currently is a std::map which doesn't have any good
+ // way to iterate and remove items from the map so we currently just make a
+ // new list and add all of the matching types to it, and then swap it into
+ // m_types at the end
collection matching_types;
iterator pos, end = m_types.end();
diff --git a/source/Symbol/TypeMap.cpp b/source/Symbol/TypeMap.cpp
index 40c6558d5825..2838039ad603 100644
--- a/source/Symbol/TypeMap.cpp
+++ b/source/Symbol/TypeMap.cpp
@@ -45,7 +45,8 @@ TypeMap::TypeMap() : m_types() {}
TypeMap::~TypeMap() {}
void TypeMap::Insert(const TypeSP &type_sp) {
- // Just push each type on the back for now. We will worry about uniquing later
+ // Just push each type on the back for now. We will worry about uniquing
+ // later
if (type_sp)
m_types.insert(std::make_pair(type_sp->GetID(), type_sp));
}
@@ -167,10 +168,10 @@ void TypeMap::RemoveMismatchedTypes(const char *qualified_typename,
void TypeMap::RemoveMismatchedTypes(const std::string &type_scope,
const std::string &type_basename,
TypeClass type_class, bool exact_match) {
- // Our "collection" type currently is a std::map which doesn't
- // have any good way to iterate and remove items from the map
- // so we currently just make a new list and add all of the matching
- // types to it, and then swap it into m_types at the end
+ // Our "collection" type currently is a std::map which doesn't have any good
+ // way to iterate and remove items from the map so we currently just make a
+ // new list and add all of the matching types to it, and then swap it into
+ // m_types at the end
collection matching_types;
iterator pos, end = m_types.end();
@@ -205,19 +206,15 @@ void TypeMap::RemoveMismatchedTypes(const std::string &type_scope,
if (type_scope_pos == match_type_scope_size - type_scope_size) {
if (type_scope_pos >= 2) {
// Our match scope ends with the type scope we were looking
- // for,
- // but we need to make sure what comes before the matching
- // type scope is a namespace boundary in case we are trying to
- // match:
- // type_basename = "d"
- // type_scope = "b::c::"
+ // for, but we need to make sure what comes before the
+ // matching type scope is a namespace boundary in case we are
+ // trying to match: type_basename = "d" type_scope = "b::c::"
// We want to match:
// match_type_scope "a::b::c::"
// But not:
// match_type_scope "a::bb::c::"
// So below we make sure what comes before "b::c::" in
- // match_type_scope
- // is "::", or the namespace boundary
+ // match_type_scope is "::", or the namespace boundary
if (match_type_scope[type_scope_pos - 1] == ':' &&
match_type_scope[type_scope_pos - 2] == ':') {
keep_match = true;
@@ -228,9 +225,8 @@ void TypeMap::RemoveMismatchedTypes(const std::string &type_scope,
}
}
} else {
- // The type we are currently looking at doesn't exists
- // in a namespace or class, so it only matches if there
- // is no type scope...
+ // The type we are currently looking at doesn't exists in a namespace
+ // or class, so it only matches if there is no type scope...
keep_match =
type_scope.empty() && type_basename.compare(match_type_name) == 0;
}
@@ -247,10 +243,10 @@ void TypeMap::RemoveMismatchedTypes(TypeClass type_class) {
if (type_class == eTypeClassAny)
return;
- // Our "collection" type currently is a std::map which doesn't
- // have any good way to iterate and remove items from the map
- // so we currently just make a new list and add all of the matching
- // types to it, and then swap it into m_types at the end
+ // Our "collection" type currently is a std::map which doesn't have any good
+ // way to iterate and remove items from the map so we currently just make a
+ // new list and add all of the matching types to it, and then swap it into
+ // m_types at the end
collection matching_types;
iterator pos, end = m_types.end();
diff --git a/source/Symbol/UnwindPlan.cpp b/source/Symbol/UnwindPlan.cpp
index 4c0014348c42..23ca1324ab06 100644
--- a/source/Symbol/UnwindPlan.cpp
+++ b/source/Symbol/UnwindPlan.cpp
@@ -46,8 +46,7 @@ operator==(const UnwindPlan::Row::RegisterLocation &rhs) const {
}
// This function doesn't copy the dwarf expression bytes; they must remain in
-// allocated
-// memory for the lifespan of this UnwindPlan object.
+// allocated memory for the lifespan of this UnwindPlan object.
void UnwindPlan::Row::RegisterLocation::SetAtDWARFExpression(
const uint8_t *opcodes, uint32_t len) {
m_type = atDWARFExpression;
@@ -56,8 +55,7 @@ void UnwindPlan::Row::RegisterLocation::SetAtDWARFExpression(
}
// This function doesn't copy the dwarf expression bytes; they must remain in
-// allocated
-// memory for the lifespan of this UnwindPlan object.
+// allocated memory for the lifespan of this UnwindPlan object.
void UnwindPlan::Row::RegisterLocation::SetIsDWARFExpression(
const uint8_t *opcodes, uint32_t len) {
m_type = isDWARFExpression;
diff --git a/source/Symbol/UnwindTable.cpp b/source/Symbol/UnwindTable.cpp
index 405d57754ea5..7f98eaca2521 100644
--- a/source/Symbol/UnwindTable.cpp
+++ b/source/Symbol/UnwindTable.cpp
@@ -20,10 +20,9 @@
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
-// There is one UnwindTable object per ObjectFile.
-// It contains a list of Unwind objects -- one per function, populated lazily --
-// for the ObjectFile.
-// Each Unwind object has multiple UnwindPlans for different scenarios.
+// There is one UnwindTable object per ObjectFile. It contains a list of Unwind
+// objects -- one per function, populated lazily -- for the ObjectFile. Each
+// Unwind object has multiple UnwindPlans for different scenarios.
using namespace lldb;
using namespace lldb_private;
@@ -33,8 +32,7 @@ UnwindTable::UnwindTable(ObjectFile &objfile)
m_eh_frame_up(), m_compact_unwind_up(), m_arm_unwind_up() {}
// We can't do some of this initialization when the ObjectFile is running its
-// ctor; delay doing it
-// until needed for something.
+// ctor; delay doing it until needed for something.
void UnwindTable::Initialize() {
if (m_initialized)
@@ -134,10 +132,9 @@ UnwindTable::GetFuncUnwindersContainingAddress(const Address &addr,
}
// Ignore any existing FuncUnwinders for this function, create a new one and
-// don't add it to the
-// UnwindTable. This is intended for use by target modules show-unwind where we
-// want to create
-// new UnwindPlans, not re-use existing ones.
+// don't add it to the UnwindTable. This is intended for use by target modules
+// show-unwind where we want to create new UnwindPlans, not re-use existing
+// ones.
FuncUnwindersSP
UnwindTable::GetUncachedFuncUnwindersContainingAddress(const Address &addr,
SymbolContext &sc) {
diff --git a/source/Symbol/Variable.cpp b/source/Symbol/Variable.cpp
index 1957bcef1f3a..7eafef1e8955 100644
--- a/source/Symbol/Variable.cpp
+++ b/source/Symbol/Variable.cpp
@@ -239,9 +239,8 @@ bool Variable::LocationIsValidForFrame(StackFrame *frame) {
target_sp.get());
if (loclist_base_load_addr == LLDB_INVALID_ADDRESS)
return false;
- // It is a location list. We just need to tell if the location
- // list contains the current address when converted to a load
- // address
+ // It is a location list. We just need to tell if the location list
+ // contains the current address when converted to a load address
return m_location.LocationListContainsAddress(
loclist_base_load_addr,
frame->GetFrameCodeAddress().GetLoadAddress(target_sp.get()));
@@ -251,8 +250,8 @@ bool Variable::LocationIsValidForFrame(StackFrame *frame) {
}
bool Variable::LocationIsValidForAddress(const Address &address) {
- // Be sure to resolve the address to section offset prior to
- // calling this function.
+ // Be sure to resolve the address to section offset prior to calling this
+ // function.
if (address.IsSectionOffset()) {
SymbolContext sc;
CalculateSymbolContext(&sc);
@@ -268,9 +267,8 @@ bool Variable::LocationIsValidForAddress(const Address &address) {
sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
if (loclist_base_file_addr == LLDB_INVALID_ADDRESS)
return false;
- // It is a location list. We just need to tell if the location
- // list contains the current address when converted to a load
- // address
+ // It is a location list. We just need to tell if the location list
+ // contains the current address when converted to a load address
return m_location.LocationListContainsAddress(loclist_base_file_addr,
address.GetFileAddress());
}
@@ -294,8 +292,8 @@ bool Variable::IsInScope(StackFrame *frame) {
case eValueTypeVariableArgument:
case eValueTypeVariableLocal:
if (frame) {
- // We don't have a location list, we just need to see if the block
- // that this variable was defined in is currently
+ // We don't have a location list, we just need to see if the block that
+ // this variable was defined in is currently
Block *deepest_frame_block =
frame->GetSymbolContext(eSymbolContextBlock).block;
if (deepest_frame_block) {
@@ -313,8 +311,7 @@ bool Variable::IsInScope(StackFrame *frame) {
return false;
// If no scope range is specified then it means that the scope is the
- // same as the
- // scope of the enclosing lexical block.
+ // same as the scope of the enclosing lexical block.
if (m_scope_range.IsEmpty())
return true;
@@ -455,8 +452,8 @@ Status Variable::GetValuesForVariableExpressionPath(
}
bool Variable::DumpLocationForAddress(Stream *s, const Address &address) {
- // Be sure to resolve the address to section offset prior to
- // calling this function.
+ // Be sure to resolve the address to section offset prior to calling this
+ // function.
if (address.IsSectionOffset()) {
SymbolContext sc;
CalculateSymbolContext(&sc);
@@ -759,13 +756,13 @@ static void PrivateAutoComplete(
}
size_t Variable::AutoComplete(const ExecutionContext &exe_ctx,
- llvm::StringRef partial_path, StringList &matches,
- bool &word_complete) {
- word_complete = false;
+ CompletionRequest &request) {
CompilerType compiler_type;
- PrivateAutoComplete(exe_ctx.GetFramePtr(), partial_path, "", compiler_type,
- matches, word_complete);
+ bool word_complete = false;
+ PrivateAutoComplete(exe_ctx.GetFramePtr(), request.GetCursorArgumentPrefix(),
+ "", compiler_type, request.GetMatches(), word_complete);
+ request.SetWordComplete(word_complete);
- return matches.GetSize();
+ return request.GetMatches().GetSize();
}
diff --git a/source/Target/ABI.cpp b/source/Target/ABI.cpp
index 72f58be5a3d4..8d4513ad6811 100644
--- a/source/Target/ABI.cpp
+++ b/source/Target/ABI.cpp
@@ -102,15 +102,18 @@ ValueObjectSP ABI::GetReturnValueObject(Thread &thread, CompilerType &ast_type,
// work.
if (persistent) {
+ Target &target = *thread.CalculateTarget();
PersistentExpressionState *persistent_expression_state =
- thread.CalculateTarget()->GetPersistentExpressionStateForLanguage(
+ target.GetPersistentExpressionStateForLanguage(
ast_type.GetMinimumLanguage());
if (!persistent_expression_state)
return ValueObjectSP();
- ConstString persistent_variable_name(
- persistent_expression_state->GetNextPersistentVariableName());
+ auto prefix = persistent_expression_state->GetPersistentVariablePrefix();
+ ConstString persistent_variable_name =
+ persistent_expression_state->GetNextPersistentVariableName(target,
+ prefix);
lldb::ValueObjectSP const_valobj_sp;
@@ -193,18 +196,18 @@ bool ABI::PrepareTrivialCall(Thread &thread, lldb::addr_t sp,
bool ABI::GetFallbackRegisterLocation(
const RegisterInfo *reg_info,
UnwindPlan::Row::RegisterLocation &unwind_regloc) {
- // Did the UnwindPlan fail to give us the caller's stack pointer?
- // The stack pointer is defined to be the same as THIS frame's CFA, so return
- // the CFA value as
- // the caller's stack pointer. This is true on x86-32/x86-64 at least.
+ // Did the UnwindPlan fail to give us the caller's stack pointer? The stack
+ // pointer is defined to be the same as THIS frame's CFA, so return the CFA
+ // value as the caller's stack pointer. This is true on x86-32/x86-64 at
+ // least.
if (reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_SP) {
unwind_regloc.SetIsCFAPlusOffset(0);
return true;
}
// If a volatile register is being requested, we don't want to forward the
- // next frame's register contents
- // up the stack -- the register is not retrievable at this frame.
+ // next frame's register contents up the stack -- the register is not
+ // retrievable at this frame.
if (RegisterIsVolatile(reg_info)) {
unwind_regloc.SetUndefined();
return true;
diff --git a/source/Target/CMakeLists.txt b/source/Target/CMakeLists.txt
index 1d858ae584d9..df137c314afa 100644
--- a/source/Target/CMakeLists.txt
+++ b/source/Target/CMakeLists.txt
@@ -1,5 +1,3 @@
-include_directories(../Plugins/Process/Utility)
-
add_lldb_library(lldbTarget
ABI.cpp
CPPLanguageRuntime.cpp
diff --git a/source/Target/ExecutionContext.cpp b/source/Target/ExecutionContext.cpp
index 3643c1590421..73c64916cf1f 100644
--- a/source/Target/ExecutionContext.cpp
+++ b/source/Target/ExecutionContext.cpp
@@ -369,15 +369,14 @@ ExecutionContext &ExecutionContext::operator=(const ExecutionContext &rhs) {
bool ExecutionContext::operator==(const ExecutionContext &rhs) const {
// Check that the frame shared pointers match, or both are valid and their
- // stack
- // IDs match since sometimes we get new objects that represent the same
+ // stack IDs match since sometimes we get new objects that represent the same
// frame within a thread.
if ((m_frame_sp == rhs.m_frame_sp) ||
(m_frame_sp && rhs.m_frame_sp &&
m_frame_sp->GetStackID() == rhs.m_frame_sp->GetStackID())) {
- // Check that the thread shared pointers match, or both are valid and
- // their thread IDs match since sometimes we get new objects that
- // represent the same thread within a process.
+ // Check that the thread shared pointers match, or both are valid and their
+ // thread IDs match since sometimes we get new objects that represent the
+ // same thread within a process.
if ((m_thread_sp == rhs.m_thread_sp) ||
(m_thread_sp && rhs.m_thread_sp &&
m_thread_sp->GetID() == rhs.m_thread_sp->GetID())) {
@@ -596,9 +595,9 @@ lldb::ThreadSP ExecutionContextRef::GetThreadSP() const {
lldb::ThreadSP thread_sp(m_thread_wp.lock());
if (m_tid != LLDB_INVALID_THREAD_ID) {
- // We check if the thread has been destroyed in cases where clients
- // might still have shared pointer to a thread, but the thread is
- // not valid anymore (not part of the process)
+ // We check if the thread has been destroyed in cases where clients might
+ // still have shared pointer to a thread, but the thread is not valid
+ // anymore (not part of the process)
if (!thread_sp || !thread_sp->IsValid()) {
lldb::ProcessSP process_sp(GetProcessSP());
if (process_sp && process_sp->IsValid()) {
@@ -608,9 +607,8 @@ lldb::ThreadSP ExecutionContextRef::GetThreadSP() const {
}
}
- // Check that we aren't about to return an invalid thread sp. We might return
- // a nullptr thread_sp,
- // but don't return an invalid one.
+ // Check that we aren't about to return an invalid thread sp. We might
+ // return a nullptr thread_sp, but don't return an invalid one.
if (thread_sp && !thread_sp->IsValid())
thread_sp.reset();
diff --git a/source/Target/Memory.cpp b/source/Target/Memory.cpp
index ced359418682..ad1b4093155d 100644
--- a/source/Target/Memory.cpp
+++ b/source/Target/Memory.cpp
@@ -133,12 +133,12 @@ size_t MemoryCache::Read(addr_t addr, void *dst, size_t dst_len,
Status &error) {
size_t bytes_left = dst_len;
- // Check the L1 cache for a range that contain the entire memory read.
- // If we find a range in the L1 cache that does, we use it. Else we fall
- // back to reading memory in m_L2_cache_line_byte_size byte sized chunks.
- // The L1 cache contains chunks of memory that are not required to be
- // m_L2_cache_line_byte_size bytes in size, so we don't try anything
- // tricky when reading from them (no partial reads from the L1 cache).
+ // Check the L1 cache for a range that contain the entire memory read. If we
+ // find a range in the L1 cache that does, we use it. Else we fall back to
+ // reading memory in m_L2_cache_line_byte_size byte sized chunks. The L1
+ // cache contains chunks of memory that are not required to be
+ // m_L2_cache_line_byte_size bytes in size, so we don't try anything tricky
+ // when reading from them (no partial reads from the L1 cache).
std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (!m_L1_cache.empty()) {
@@ -155,11 +155,11 @@ size_t MemoryCache::Read(addr_t addr, void *dst, size_t dst_len,
}
}
- // If this memory read request is larger than the cache line size, then
- // we (1) try to read as much of it at once as possible, and (2) don't
- // add the data to the memory cache. We don't want to split a big read
- // up into more separate reads than necessary, and with a large memory read
- // request, it is unlikely that the caller function will ask for the next
+ // If this memory read request is larger than the cache line size, then we
+ // (1) try to read as much of it at once as possible, and (2) don't add the
+ // data to the memory cache. We don't want to split a big read up into more
+ // separate reads than necessary, and with a large memory read request, it is
+ // unlikely that the caller function will ask for the next
// 4 bytes after the large memory read - so there's little benefit to saving
// it in the cache.
if (dst && dst_len > m_L2_cache_line_byte_size) {
@@ -218,9 +218,9 @@ size_t MemoryCache::Read(addr_t addr, void *dst, size_t dst_len,
bytes_left -= curr_read_size;
curr_addr += curr_read_size;
- // We have a cache page that succeeded to read some bytes
- // but not an entire page. If this happens, we must cap
- // off how much data we are able to read...
+ // We have a cache page that succeeded to read some bytes but not
+ // an entire page. If this happens, we must cap off how much data
+ // we are able to read...
if (pos->second->GetByteSize() != cache_line_byte_size)
return dst_len - bytes_left;
}
@@ -277,8 +277,8 @@ lldb::addr_t AllocatedBlock::ReserveBlock(uint32_t size) {
if (range_size >= size)
{
// We found a free block that is big enough for our data. Figure out how
- // many chunks we will need and calculate the resulting block size we will
- // reserve.
+ // many chunks we will need and calculate the resulting block size we
+ // will reserve.
addr_t addr = free_block.GetRangeBase();
size_t num_chunks = CalculateChunksNeededForSize(size);
lldb::addr_t block_size = num_chunks * m_chunk_size;
@@ -296,8 +296,8 @@ lldb::addr_t AllocatedBlock::ReserveBlock(uint32_t size) {
// Make the new allocated range and add it to the allocated ranges.
Range<lldb::addr_t, uint32_t> reserved_block(free_block);
reserved_block.SetByteSize(block_size);
- // Insert the reserved range and don't combine it with other blocks
- // in the reserved blocks list.
+ // Insert the reserved range and don't combine it with other blocks in
+ // the reserved blocks list.
m_reserved_blocks.Insert(reserved_block, false);
// Adjust the free range in place since we won't change the sorted
// ordering of the m_free_blocks list.
diff --git a/source/Target/ModuleCache.cpp b/source/Target/ModuleCache.cpp
index 2b654772639a..19adfbabe277 100644
--- a/source/Target/ModuleCache.cpp
+++ b/source/Target/ModuleCache.cpp
@@ -312,9 +312,8 @@ Status ModuleCache::GetAndPut(const FileSpec &root_dir_spec,
llvm::FileRemover tmp_symfile_remover(tmp_download_sym_file_spec.GetPath());
if (error.Fail())
// Failed to download a symfile but fetching the module was successful. The
- // module might
- // contain the necessary symbols and the debugging is also possible without
- // a symfile.
+ // module might contain the necessary symbols and the debugging is also
+ // possible without a symfile.
return Status();
error = Put(root_dir_spec, escaped_hostname.c_str(), module_spec,
diff --git a/source/Target/ObjCLanguageRuntime.cpp b/source/Target/ObjCLanguageRuntime.cpp
index d3cc7c019dce..b1fcee6db63b 100644
--- a/source/Target/ObjCLanguageRuntime.cpp
+++ b/source/Target/ObjCLanguageRuntime.cpp
@@ -23,6 +23,7 @@
#include "lldb/Utility/Timer.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DJB.h"
using namespace lldb;
using namespace lldb_private;
@@ -45,8 +46,7 @@ bool ObjCLanguageRuntime::AddClass(ObjCISA isa,
if (isa != 0) {
m_isa_to_descriptor[isa] = descriptor_sp;
// class_name is assumed to be valid
- m_hash_to_isa_map.insert(
- std::make_pair(MappedHash::HashStringUsingDJB(class_name), isa));
+ m_hash_to_isa_map.insert(std::make_pair(llvm::djbHash(class_name), isa));
return true;
}
return false;
@@ -170,8 +170,7 @@ ObjCLanguageRuntime::GetDescriptorIterator(const ConstString &name) {
UpdateISAToDescriptorMap();
if (m_hash_to_isa_map.empty()) {
// No name hashes were provided, we need to just linearly power through
- // the
- // names and find a match
+ // the names and find a match
for (ISAToDescriptorIterator pos = m_isa_to_descriptor.begin();
pos != end; ++pos) {
if (pos->second->GetClassName() == name)
@@ -180,8 +179,7 @@ ObjCLanguageRuntime::GetDescriptorIterator(const ConstString &name) {
} else {
// Name hashes were provided, so use them to efficiently lookup name to
// isa/descriptor
- const uint32_t name_hash =
- MappedHash::HashStringUsingDJB(name.GetCString());
+ const uint32_t name_hash = llvm::djbHash(name.GetStringRef());
std::pair<HashToISAIterator, HashToISAIterator> range =
m_hash_to_isa_map.equal_range(name_hash);
for (HashToISAIterator range_pos = range.first; range_pos != range.second;
@@ -240,9 +238,9 @@ ObjCLanguageRuntime::GetClassDescriptorFromClassName(
ObjCLanguageRuntime::ClassDescriptorSP
ObjCLanguageRuntime::GetClassDescriptor(ValueObject &valobj) {
ClassDescriptorSP objc_class_sp;
- // if we get an invalid VO (which might still happen when playing around
- // with pointers returned by the expression parser, don't consider this
- // a valid ObjC object)
+ // if we get an invalid VO (which might still happen when playing around with
+ // pointers returned by the expression parser, don't consider this a valid
+ // ObjC object)
if (valobj.GetCompilerType().IsValid()) {
addr_t isa_pointer = valobj.GetPointerValue();
if (isa_pointer != LLDB_INVALID_ADDRESS) {
diff --git a/source/Target/PathMappingList.cpp b/source/Target/PathMappingList.cpp
index 782c6e49623c..778728eebb09 100644
--- a/source/Target/PathMappingList.cpp
+++ b/source/Target/PathMappingList.cpp
@@ -14,6 +14,7 @@
// Other libraries and framework includes
// Project includes
+#include "lldb/lldb-private-enumerations.h"
#include "lldb/Host/PosixApi.h"
#include "lldb/Target/PathMappingList.h"
#include "lldb/Utility/FileSpec.h"
@@ -23,6 +24,22 @@
using namespace lldb;
using namespace lldb_private;
+namespace {
+ // We must normalize our path pairs that we store because if we don't then
+ // things won't always work. We found a case where if we did:
+ // (lldb) settings set target.source-map . /tmp
+ // We would store a path pairs of "." and "/tmp" as raw strings. If the debug
+ // info contains "./foo/bar.c", the path will get normalized to "foo/bar.c".
+ // When PathMappingList::RemapPath() is called, it expects the path to start
+ // with the raw path pair, which doesn't work anymore because the paths have
+ // been normalized when the debug info was loaded. So we need to store
+ // nomalized path pairs to ensure things match up.
+ ConstString NormalizePath(const ConstString &path) {
+ // If we use "path" to construct a FileSpec, it will normalize the path for
+ // us. We then grab the string and turn it back into a ConstString.
+ return ConstString(FileSpec(path.GetStringRef(), false).GetPath());
+ }
+}
//----------------------------------------------------------------------
// PathMappingList constructor
//----------------------------------------------------------------------
@@ -52,7 +69,7 @@ PathMappingList::~PathMappingList() = default;
void PathMappingList::Append(const ConstString &path,
const ConstString &replacement, bool notify) {
++m_mod_id;
- m_pairs.push_back(pair(path, replacement));
+ m_pairs.emplace_back(pair(NormalizePath(path), NormalizePath(replacement)));
if (notify && m_callback)
m_callback(*this, m_callback_baton);
}
@@ -77,7 +94,8 @@ void PathMappingList::Insert(const ConstString &path,
insert_iter = m_pairs.end();
else
insert_iter = m_pairs.begin() + index;
- m_pairs.insert(insert_iter, pair(path, replacement));
+ m_pairs.emplace(insert_iter, pair(NormalizePath(path),
+ NormalizePath(replacement)));
if (notify && m_callback)
m_callback(*this, m_callback_baton);
}
@@ -88,7 +106,7 @@ bool PathMappingList::Replace(const ConstString &path,
if (index >= m_pairs.size())
return false;
++m_mod_id;
- m_pairs[index] = pair(path, replacement);
+ m_pairs[index] = pair(NormalizePath(path), NormalizePath(replacement));
if (notify && m_callback)
m_callback(*this, m_callback_baton);
return true;
@@ -134,22 +152,10 @@ void PathMappingList::Clear(bool notify) {
bool PathMappingList::RemapPath(const ConstString &path,
ConstString &new_path) const {
- const char *path_cstr = path.GetCString();
- // CLEANUP: Convert this function to use StringRefs internally instead
- // of raw c-strings.
- if (!path_cstr)
- return false;
-
- const_iterator pos, end = m_pairs.end();
- for (pos = m_pairs.begin(); pos != end; ++pos) {
- const size_t prefixLen = pos->first.GetLength();
-
- if (::strncmp(pos->first.GetCString(), path_cstr, prefixLen) == 0) {
- std::string new_path_str(pos->second.GetCString());
- new_path_str.append(path.GetCString() + prefixLen);
- new_path.SetCString(new_path_str.c_str());
- return true;
- }
+ std::string remapped;
+ if (RemapPath(path.GetStringRef(), remapped)) {
+ new_path.SetString(remapped);
+ return true;
}
return false;
}
@@ -158,34 +164,41 @@ bool PathMappingList::RemapPath(llvm::StringRef path,
std::string &new_path) const {
if (m_pairs.empty() || path.empty())
return false;
-
- const_iterator pos, end = m_pairs.end();
- for (pos = m_pairs.begin(); pos != end; ++pos) {
- if (!path.consume_front(pos->first.GetStringRef()))
- continue;
-
- new_path = pos->second.GetStringRef();
- new_path.append(path);
+ LazyBool path_is_relative = eLazyBoolCalculate;
+ for (const auto &it : m_pairs) {
+ auto prefix = it.first.GetStringRef();
+ if (!path.consume_front(prefix)) {
+ // Relative paths won't have a leading "./" in them unless "." is the
+ // only thing in the relative path so we need to work around "."
+ // carefully.
+ if (prefix != ".")
+ continue;
+ // We need to figure out if the "path" argument is relative. If it is,
+ // then we should remap, else skip this entry.
+ if (path_is_relative == eLazyBoolCalculate) {
+ path_is_relative = FileSpec(path, false).IsRelative() ? eLazyBoolYes :
+ eLazyBoolNo;
+ }
+ if (!path_is_relative)
+ continue;
+ }
+ FileSpec remapped(it.second.GetStringRef(), false);
+ remapped.AppendPathComponent(path);
+ new_path = remapped.GetPath();
return true;
}
return false;
}
-bool PathMappingList::ReverseRemapPath(const ConstString &path,
- ConstString &new_path) const {
- const char *path_cstr = path.GetCString();
- if (!path_cstr)
- return false;
-
+bool PathMappingList::ReverseRemapPath(const FileSpec &file, FileSpec &fixed) const {
+ std::string path = file.GetPath();
+ llvm::StringRef path_ref(path);
for (const auto &it : m_pairs) {
- // FIXME: This should be using FileSpec API's to do the path appending.
- const size_t prefixLen = it.second.GetLength();
- if (::strncmp(it.second.GetCString(), path_cstr, prefixLen) == 0) {
- std::string new_path_str(it.first.GetCString());
- new_path_str.append(path.GetCString() + prefixLen);
- new_path.SetCString(new_path_str.c_str());
- return true;
- }
+ if (!path_ref.consume_front(it.second.GetStringRef()))
+ continue;
+ fixed.SetFile(it.first.GetStringRef(), false, FileSpec::Style::native);
+ fixed.AppendPathComponent(path_ref);
+ return true;
}
return false;
}
@@ -203,7 +216,8 @@ bool PathMappingList::FindFile(const FileSpec &orig_spec,
if (orig_path_len >= prefix_len) {
if (::strncmp(pos->first.GetCString(), orig_path, prefix_len) == 0) {
- new_spec.SetFile(pos->second.GetCString(), false);
+ new_spec.SetFile(pos->second.GetCString(), false,
+ FileSpec::Style::native);
new_spec.AppendPathComponent(orig_path + prefix_len);
if (new_spec.Exists())
return true;
@@ -277,7 +291,8 @@ bool PathMappingList::GetPathsAtIndex(uint32_t idx, ConstString &path,
return false;
}
-uint32_t PathMappingList::FindIndexForPath(const ConstString &path) const {
+uint32_t PathMappingList::FindIndexForPath(const ConstString &orig_path) const {
+ const ConstString path = NormalizePath(orig_path);
const_iterator pos;
const_iterator begin = m_pairs.begin();
const_iterator end = m_pairs.end();
diff --git a/source/Target/Platform.cpp b/source/Target/Platform.cpp
index 5d60bb791555..5ae556ecc02a 100644
--- a/source/Target/Platform.cpp
+++ b/source/Target/Platform.cpp
@@ -10,6 +10,7 @@
// C Includes
// C++ Includes
#include <algorithm>
+#include <csignal>
#include <fstream>
#include <vector>
@@ -45,8 +46,8 @@
#include "llvm/Support/FileSystem.h"
-// Define these constants from POSIX mman.h rather than include the file
-// so that they will be correct even when compiled on Linux.
+// Define these constants from POSIX mman.h rather than include the file so
+// that they will be correct even when compiled on Linux.
#define MAP_PRIVATE 2
#define MAP_ANON 0x1000
@@ -55,8 +56,8 @@ using namespace lldb_private;
static uint32_t g_initialize_count = 0;
-// Use a singleton function for g_local_platform_sp to avoid init
-// constructors since LLDB is often part of a shared library
+// Use a singleton function for g_local_platform_sp to avoid init constructors
+// since LLDB is often part of a shared library
static PlatformSP &GetHostPlatformSP() {
static PlatformSP g_platform_sp;
return g_platform_sp;
@@ -368,13 +369,11 @@ ArchSpec Platform::GetAugmentedArchSpec(Platform *platform, llvm::StringRef trip
Platform::Platform(bool is_host)
: m_is_host(is_host), m_os_version_set_while_connected(false),
m_system_arch_set_while_connected(false), m_sdk_sysroot(), m_sdk_build(),
- m_working_dir(), m_remote_url(), m_name(), m_major_os_version(UINT32_MAX),
- m_minor_os_version(UINT32_MAX), m_update_os_version(UINT32_MAX),
- m_system_arch(), m_mutex(), m_uid_map(), m_gid_map(),
- m_max_uid_name_len(0), m_max_gid_name_len(0), m_supports_rsync(false),
- m_rsync_opts(), m_rsync_prefix(), m_supports_ssh(false), m_ssh_opts(),
- m_ignores_remote_hostname(false), m_trap_handlers(),
- m_calculated_trap_handlers(false),
+ m_working_dir(), m_remote_url(), m_name(), m_system_arch(), m_mutex(),
+ m_uid_map(), m_gid_map(), m_max_uid_name_len(0), m_max_gid_name_len(0),
+ m_supports_rsync(false), m_rsync_opts(), m_rsync_prefix(),
+ m_supports_ssh(false), m_ssh_opts(), m_ignores_remote_hostname(false),
+ m_trap_handlers(), m_calculated_trap_handlers(false),
m_module_cache(llvm::make_unique<ModuleCache>()) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
if (log)
@@ -394,9 +393,6 @@ Platform::~Platform() {
}
void Platform::GetStatus(Stream &strm) {
- uint32_t major = UINT32_MAX;
- uint32_t minor = UINT32_MAX;
- uint32_t update = UINT32_MAX;
std::string s;
strm.Printf(" Platform: %s\n", GetPluginName().GetCString());
@@ -409,12 +405,9 @@ void Platform::GetStatus(Stream &strm) {
}
}
- if (GetOSVersion(major, minor, update)) {
- strm.Printf("OS Version: %u", major);
- if (minor != UINT32_MAX)
- strm.Printf(".%u", minor);
- if (update != UINT32_MAX)
- strm.Printf(".%u", update);
+ llvm::VersionTuple os_version = GetOSVersion();
+ if (!os_version.empty()) {
+ strm.Format("OS Version: {0}", os_version.getAsString());
if (GetOSBuildString(s))
strm.Printf(" (%s)", s.c_str());
@@ -446,17 +439,14 @@ void Platform::GetStatus(Stream &strm) {
strm.Printf("Platform-specific connection: %s\n", specific_info.c_str());
}
-bool Platform::GetOSVersion(uint32_t &major, uint32_t &minor, uint32_t &update,
- Process *process) {
+llvm::VersionTuple Platform::GetOSVersion(Process *process) {
std::lock_guard<std::mutex> guard(m_mutex);
- bool success = m_major_os_version != UINT32_MAX;
if (IsHost()) {
- if (!success) {
+ if (m_os_version.empty()) {
// We have a local host platform
- success = HostInfo::GetOSVersion(m_major_os_version, m_minor_os_version,
- m_update_os_version);
- m_os_version_set_while_connected = success;
+ m_os_version = HostInfo::GetOSVersion();
+ m_os_version_set_while_connected = !m_os_version.empty();
}
} else {
// We have a remote platform. We can only fetch the remote
@@ -466,11 +456,10 @@ bool Platform::GetOSVersion(uint32_t &major, uint32_t &minor, uint32_t &update,
const bool is_connected = IsConnected();
bool fetch = false;
- if (success) {
- // We have valid OS version info, check to make sure it wasn't
- // manually set prior to connecting. If it was manually set prior
- // to connecting, then lets fetch the actual OS version info
- // if we are now connected.
+ if (!m_os_version.empty()) {
+ // We have valid OS version info, check to make sure it wasn't manually
+ // set prior to connecting. If it was manually set prior to connecting,
+ // then lets fetch the actual OS version info if we are now connected.
if (is_connected && !m_os_version_set_while_connected)
fetch = true;
} else {
@@ -478,22 +467,18 @@ bool Platform::GetOSVersion(uint32_t &major, uint32_t &minor, uint32_t &update,
fetch = is_connected;
}
- if (fetch) {
- success = GetRemoteOSVersion();
- m_os_version_set_while_connected = success;
- }
+ if (fetch)
+ m_os_version_set_while_connected = GetRemoteOSVersion();
}
- if (success) {
- major = m_major_os_version;
- minor = m_minor_os_version;
- update = m_update_os_version;
- } else if (process) {
- // Check with the process in case it can answer the question if
- // a process was provided
- return process->GetHostOSVersion(major, minor, update);
+ if (!m_os_version.empty())
+ return m_os_version;
+ if (process) {
+ // Check with the process in case it can answer the question if a process
+ // was provided
+ return process->GetHostOSVersion();
}
- return success;
+ return llvm::VersionTuple();
}
bool Platform::GetOSBuildString(std::string &s) {
@@ -577,8 +562,8 @@ RecurseCopy_Callback(void *baton, llvm::sys::fs::file_type ft,
// now recurse
std::string src_dir_path(src.GetPath());
- // Make a filespec that only fills in the directory of a FileSpec so
- // when we enumerate we can quickly fill in the filename for dst copies
+ // Make a filespec that only fills in the directory of a FileSpec so when
+ // we enumerate we can quickly fill in the filename for dst copies
FileSpec recurse_dst;
recurse_dst.GetDirectory().SetCString(dst_dir.GetPath().c_str());
RecurseCopyBaton rc_baton2 = {recurse_dst, rc_baton->platform_ptr,
@@ -656,9 +641,9 @@ Status Platform::Install(const FileSpec &src, const FileSpec &dst) {
if (first_dst_dir_char == '/' || first_dst_dir_char == '\\') {
fixed_dst.GetDirectory() = dst.GetDirectory();
}
- // If the fixed destination file doesn't have a directory yet,
- // then we must have a relative path. We will resolve this relative
- // path against the platform's working directory
+ // If the fixed destination file doesn't have a directory yet, then we
+ // must have a relative path. We will resolve this relative path against
+ // the platform's working directory
if (!fixed_dst.GetDirectory()) {
FileSpec relative_spec;
std::string path;
@@ -859,26 +844,22 @@ const char *Platform::GetGroupName(uint32_t gid) {
return nullptr;
}
-bool Platform::SetOSVersion(uint32_t major, uint32_t minor, uint32_t update) {
+bool Platform::SetOSVersion(llvm::VersionTuple version) {
if (IsHost()) {
- // We don't need anyone setting the OS version for the host platform,
- // we should be able to figure it out by calling
- // HostInfo::GetOSVersion(...).
+ // We don't need anyone setting the OS version for the host platform, we
+ // should be able to figure it out by calling HostInfo::GetOSVersion(...).
return false;
} else {
- // We have a remote platform, allow setting the target OS version if
- // we aren't connected, since if we are connected, we should be able to
+ // We have a remote platform, allow setting the target OS version if we
+ // aren't connected, since if we are connected, we should be able to
// request the remote OS version from the connected platform.
if (IsConnected())
return false;
else {
- // We aren't connected and we might want to set the OS version
- // ahead of time before we connect so we can peruse files and
- // use a local SDK or PDK cache of support files to disassemble
- // or do other things.
- m_major_os_version = major;
- m_minor_os_version = minor;
- m_update_os_version = update;
+ // We aren't connected and we might want to set the OS version ahead of
+ // time before we connect so we can peruse files and use a local SDK or
+ // PDK cache of support files to disassemble or do other things.
+ m_os_version = version;
return true;
}
}
@@ -896,9 +877,9 @@ Platform::ResolveExecutable(const ModuleSpec &module_spec,
module_search_paths_ptr, nullptr,
nullptr);
} else {
- // No valid architecture was specified, ask the platform for
- // the architectures that we should be using (in the correct order)
- // and see if we can find a match that way
+ // No valid architecture was specified, ask the platform for the
+ // architectures that we should be using (in the correct order) and see
+ // if we can find a match that way
ModuleSpec arch_module_spec(module_spec);
for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
idx, arch_module_spec.GetArchitecture());
@@ -942,18 +923,17 @@ const ArchSpec &Platform::GetSystemArchitecture() {
m_system_arch_set_while_connected = m_system_arch.IsValid();
}
} else {
- // We have a remote platform. We can only fetch the remote
- // system architecture if we are connected, and we don't want to do it
- // more than once.
+ // We have a remote platform. We can only fetch the remote system
+ // architecture if we are connected, and we don't want to do it more than
+ // once.
const bool is_connected = IsConnected();
bool fetch = false;
if (m_system_arch.IsValid()) {
- // We have valid OS version info, check to make sure it wasn't
- // manually set prior to connecting. If it was manually set prior
- // to connecting, then lets fetch the actual OS version info
- // if we are now connected.
+ // We have valid OS version info, check to make sure it wasn't manually
+ // set prior to connecting. If it was manually set prior to connecting,
+ // then lets fetch the actual OS version info if we are now connected.
if (is_connected && !m_system_arch_set_while_connected)
fetch = true;
} else {
@@ -1025,8 +1005,8 @@ Status Platform::DisconnectRemote() {
bool Platform::GetProcessInfo(lldb::pid_t pid,
ProcessInstanceInfo &process_info) {
- // Take care of the host case so that each subclass can just
- // call this function to get the host functionality.
+ // Take care of the host case so that each subclass can just call this
+ // function to get the host functionality.
if (IsHost())
return Host::GetProcessInfo(pid, process_info);
return false;
@@ -1034,8 +1014,8 @@ bool Platform::GetProcessInfo(lldb::pid_t pid,
uint32_t Platform::FindProcesses(const ProcessInstanceInfoMatch &match_info,
ProcessInstanceInfoList &process_infos) {
- // Take care of the host case so that each subclass can just
- // call this function to get the host functionality.
+ // Take care of the host case so that each subclass can just call this
+ // function to get the host functionality.
uint32_t match_count = 0;
if (IsHost())
match_count = Host::FindProcesses(match_info, process_infos);
@@ -1048,8 +1028,8 @@ Status Platform::LaunchProcess(ProcessLaunchInfo &launch_info) {
if (log)
log->Printf("Platform::%s()", __FUNCTION__);
- // Take care of the host case so that each subclass can just
- // call this function to get the host functionality.
+ // Take care of the host case so that each subclass can just call this
+ // function to get the host functionality.
if (IsHost()) {
if (::getenv("LLDB_LAUNCH_FLAG_LAUNCH_IN_TTY"))
launch_info.GetFlags().Set(eLaunchFlagLaunchInTTY);
@@ -1106,8 +1086,7 @@ Status Platform::KillProcess(const lldb::pid_t pid) {
log->Printf("Platform::%s, pid %" PRIu64, __FUNCTION__, pid);
// Try to find a process plugin to handle this Kill request. If we can't,
- // fall back to
- // the default OS implementation.
+ // fall back to the default OS implementation.
size_t num_debuggers = Debugger::GetNumDebuggers();
for (size_t didx = 0; didx < num_debuggers; ++didx) {
DebuggerSP debugger = Debugger::GetDebuggerAtIndex(didx);
@@ -1142,23 +1121,22 @@ Platform::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
// Make sure we stop at the entry point
launch_info.GetFlags().Set(eLaunchFlagDebug);
// We always launch the process we are going to debug in a separate process
- // group, since then we can handle ^C interrupts ourselves w/o having to worry
- // about the target getting them as well.
+ // group, since then we can handle ^C interrupts ourselves w/o having to
+ // worry about the target getting them as well.
launch_info.SetLaunchInSeparateProcessGroup(true);
// Allow any StructuredData process-bound plugins to adjust the launch info
// if needed
size_t i = 0;
bool iteration_complete = false;
- // Note iteration can't simply go until a nullptr callback is returned, as
- // it is valid for a plugin to not supply a filter.
+ // Note iteration can't simply go until a nullptr callback is returned, as it
+ // is valid for a plugin to not supply a filter.
auto get_filter_func = PluginManager::GetStructuredDataFilterCallbackAtIndex;
for (auto filter_callback = get_filter_func(i, iteration_complete);
!iteration_complete;
filter_callback = get_filter_func(++i, iteration_complete)) {
if (filter_callback) {
- // Give this ProcessLaunchInfo filter a chance to adjust the launch
- // info.
+ // Give this ProcessLaunchInfo filter a chance to adjust the launch info.
error = (*filter_callback)(launch_info, target);
if (!error.Success()) {
if (log)
@@ -1191,10 +1169,10 @@ Platform::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
// process if this happens.
process_sp->SetShouldDetach(false);
- // If we didn't have any file actions, the pseudo terminal might
- // have been used where the slave side was given as the file to
- // open for stdin/out/err after we have already opened the master
- // so we can read/write stdin/out/err.
+ // If we didn't have any file actions, the pseudo terminal might have
+ // been used where the slave side was given as the file to open for
+ // stdin/out/err after we have already opened the master so we can
+ // read/write stdin/out/err.
int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
if (pty_fd != PseudoTerminal::invalid_fd) {
process_sp->SetSTDIOFileDescriptor(pty_fd);
@@ -1313,8 +1291,8 @@ Status Platform::PutFile(const FileSpec &source, const FileSpec &destination,
offset += bytes_written;
if (bytes_written != bytes_read) {
- // We didn't write the correct number of bytes, so adjust
- // the file position in the source file we are reading from...
+ // We didn't write the correct number of bytes, so adjust the file
+ // position in the source file we are reading from...
source_file.SeekFromStart(offset);
}
}
@@ -1373,12 +1351,10 @@ lldb_private::Status Platform::RunShellCommand(
// process to exit
std::string
*command_output, // Pass nullptr if you don't want the command output
- uint32_t
- timeout_sec) // Timeout in seconds to wait for shell program to finish
-{
+ const Timeout<std::micro> &timeout) {
if (IsHost())
return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr,
- command_output, timeout_sec);
+ command_output, timeout);
else
return Status("unimplemented");
}
@@ -1539,10 +1515,7 @@ lldb_private::Status OptionGroupPlatformCaching::SetOptionValue(
return error;
}
-size_t Platform::GetEnvironment(StringList &environment) {
- environment.Clear();
- return false;
-}
+Environment Platform::GetEnvironment() { return Environment(); }
const std::vector<ConstString> &Platform::GetTrapHandlerSymbolNames() {
if (!m_calculated_trap_handlers) {
@@ -1602,9 +1575,9 @@ Status Platform::GetRemoteSharedModule(const ModuleSpec &module_spec,
if (module_spec.GetArchitecture().IsValid() == false) {
Status error;
- // No valid architecture was specified, ask the platform for
- // the architectures that we should be using (in the correct order)
- // and see if we can find a match that way
+ // No valid architecture was specified, ask the platform for the
+ // architectures that we should be using (in the correct order) and see if
+ // we can find a match that way
ModuleSpec arch_module_spec(module_spec);
for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
idx, arch_module_spec.GetArchitecture());
@@ -1765,7 +1738,7 @@ uint32_t Platform::LoadImage(lldb_private::Process *process,
if (error.Fail())
return LLDB_INVALID_IMAGE_TOKEN;
}
- return DoLoadImage(process, remote_file, error);
+ return DoLoadImage(process, remote_file, nullptr, error);
}
if (local_file) {
@@ -1778,12 +1751,12 @@ uint32_t Platform::LoadImage(lldb_private::Process *process,
if (error.Fail())
return LLDB_INVALID_IMAGE_TOKEN;
}
- return DoLoadImage(process, target_file, error);
- }
+ return DoLoadImage(process, target_file, nullptr, error);
+ }
if (remote_file) {
// Only remote file was specified so we don't have to do any copying
- return DoLoadImage(process, remote_file, error);
+ return DoLoadImage(process, remote_file, nullptr, error);
}
error.SetErrorString("Neither local nor remote file was specified");
@@ -1792,11 +1765,30 @@ uint32_t Platform::LoadImage(lldb_private::Process *process,
uint32_t Platform::DoLoadImage(lldb_private::Process *process,
const lldb_private::FileSpec &remote_file,
- lldb_private::Status &error) {
+ const std::vector<std::string> *paths,
+ lldb_private::Status &error,
+ lldb_private::FileSpec *loaded_image) {
error.SetErrorString("LoadImage is not supported on the current platform");
return LLDB_INVALID_IMAGE_TOKEN;
}
+uint32_t Platform::LoadImageUsingPaths(lldb_private::Process *process,
+ const lldb_private::FileSpec &remote_filename,
+ const std::vector<std::string> &paths,
+ lldb_private::Status &error,
+ lldb_private::FileSpec *loaded_path)
+{
+ FileSpec file_to_use;
+ if (remote_filename.IsAbsolute())
+ file_to_use = FileSpec(remote_filename.GetFilename().GetStringRef(),
+ false,
+ remote_filename.GetPathStyle());
+ else
+ file_to_use = remote_filename;
+
+ return DoLoadImage(process, file_to_use, &paths, error, loaded_path);
+}
+
Status Platform::UnloadImage(lldb_private::Process *process,
uint32_t image_token) {
return Status("UnloadImage is not supported on the current platform");
@@ -1855,22 +1847,22 @@ size_t Platform::GetSoftwareBreakpointTrapOpcode(Target &target,
// TODO: support big-endian arm and thumb trap codes.
case llvm::Triple::arm: {
- // The ARM reference recommends the use of 0xe7fddefe and 0xdefe
- // but the linux kernel does otherwise.
+ // The ARM reference recommends the use of 0xe7fddefe and 0xdefe but the
+ // linux kernel does otherwise.
static const uint8_t g_arm_breakpoint_opcode[] = {0xf0, 0x01, 0xf0, 0xe7};
static const uint8_t g_thumb_breakpoint_opcode[] = {0x01, 0xde};
lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0));
- AddressClass addr_class = eAddressClassUnknown;
+ AddressClass addr_class = AddressClass::eUnknown;
if (bp_loc_sp) {
addr_class = bp_loc_sp->GetAddress().GetAddressClass();
- if (addr_class == eAddressClassUnknown &&
+ if (addr_class == AddressClass::eUnknown &&
(bp_loc_sp->GetAddress().GetFileAddress() & 1))
- addr_class = eAddressClassCodeAlternateISA;
+ addr_class = AddressClass::eCodeAlternateISA;
}
- if (addr_class == eAddressClassCodeAlternateISA) {
+ if (addr_class == AddressClass::eCodeAlternateISA) {
trap_opcode = g_thumb_breakpoint_opcode;
trap_opcode_size = sizeof(g_thumb_breakpoint_opcode);
} else {
diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp
index 8fb149fab063..c3d8abc9f78d 100644
--- a/source/Target/Process.cpp
+++ b/source/Target/Process.cpp
@@ -30,6 +30,7 @@
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/IRDynamicChecks.h"
#include "lldb/Expression/UserExpression.h"
+#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
@@ -39,6 +40,7 @@
#include "lldb/Host/Terminal.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
@@ -88,19 +90,18 @@ public:
ProcessOptionValueProperties(const ConstString &name)
: OptionValueProperties(name) {}
- // This constructor is used when creating ProcessOptionValueProperties when it
- // is part of a new lldb_private::Process instance. It will copy all current
- // global property values as needed
+ // This constructor is used when creating ProcessOptionValueProperties when
+ // it is part of a new lldb_private::Process instance. It will copy all
+ // current global property values as needed
ProcessOptionValueProperties(ProcessProperties *global_properties)
: OptionValueProperties(*global_properties->GetValueProperties()) {}
const Property *GetPropertyAtIndex(const ExecutionContext *exe_ctx,
bool will_modify,
uint32_t idx) const override {
- // When getting the value for a key from the process options, we will always
- // try and grab the setting from the current process if there is one. Else
- // we just
- // use the one from this instance.
+ // When getting the value for a key from the process options, we will
+ // always try and grab the setting from the current process if there is
+ // one. Else we just use the one from this instance.
if (exe_ctx) {
Process *process = exe_ctx->GetProcessPtr();
if (process) {
@@ -307,16 +308,7 @@ void ProcessInstanceInfo::Dump(Stream &s, Platform *platform) const {
}
}
- const uint32_t envc = m_environment.GetArgumentCount();
- if (envc > 0) {
- for (uint32_t i = 0; i < envc; i++) {
- const char *env = m_environment.GetArgumentAtIndex(i);
- if (i < 10)
- s.Printf(" env[%u] = %s\n", i, env);
- else
- s.Printf("env[%u] = %s\n", i, env);
- }
- }
+ s.Format("{0}", m_environment);
if (m_arch.IsValid()) {
s.Printf(" arch = ");
@@ -498,7 +490,7 @@ Status ProcessLaunchCommandOptions::SetOptionValue(
{
bool success;
const bool disable_aslr_arg =
- Args::StringToBoolean(option_arg, true, &success);
+ OptionArgParser::ToBoolean(option_arg, true, &success);
if (success)
disable_aslr = disable_aslr_arg ? eLazyBoolYes : eLazyBoolNo;
else
@@ -511,7 +503,8 @@ Status ProcessLaunchCommandOptions::SetOptionValue(
case 'X': // shell expand args.
{
bool success;
- const bool expand_args = Args::StringToBoolean(option_arg, true, &success);
+ const bool expand_args =
+ OptionArgParser::ToBoolean(option_arg, true, &success);
if (success)
launch_info.SetShellExpandArguments(expand_args);
else
@@ -529,7 +522,7 @@ Status ProcessLaunchCommandOptions::SetOptionValue(
break;
case 'v':
- launch_info.GetEnvironmentEntries().AppendArgument(option_arg);
+ launch_info.GetEnvironment().insert(option_arg);
break;
default:
@@ -732,7 +725,7 @@ Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp,
: ProcessProperties(this), UserID(LLDB_INVALID_PROCESS_ID),
Broadcaster((target_sp->GetDebugger().GetBroadcasterManager()),
Process::GetStaticBroadcasterClass().AsCString()),
- m_target_sp(target_sp), m_public_state(eStateUnloaded),
+ m_target_wp(target_sp), m_public_state(eStateUnloaded),
m_private_state(eStateUnloaded),
m_private_state_broadcaster(nullptr,
"lldb.process.internal_state_broadcaster"),
@@ -815,8 +808,8 @@ Process::~Process() {
StopPrivateStateThread();
// ThreadList::Clear() will try to acquire this process's mutex, so
- // explicitly clear the thread list here to ensure that the mutex
- // is not destroyed before the thread list.
+ // explicitly clear the thread list here to ensure that the mutex is not
+ // destroyed before the thread list.
m_thread_list.Clear();
}
@@ -854,13 +847,12 @@ void Process::Finalize() {
// Clear our broadcaster before we proceed with destroying
Broadcaster::Clear();
- // Do any cleanup needed prior to being destructed... Subclasses
- // that override this method should call this superclass method as well.
+ // Do any cleanup needed prior to being destructed... Subclasses that
+ // override this method should call this superclass method as well.
// We need to destroy the loader before the derived Process class gets
- // destroyed
- // since it is very likely that undoing the loader will require access to the
- // real process.
+ // destroyed since it is very likely that undoing the loader will require
+ // access to the real process.
m_dynamic_checkers_ap.reset();
m_abi_sp.reset();
m_os_ap.reset();
@@ -880,8 +872,8 @@ void Process::Finalize() {
m_language_runtimes.clear();
m_instrumentation_runtimes.clear();
m_next_event_action_ap.reset();
- // Clear the last natural stop ID since it has a strong
- // reference to this process
+ // Clear the last natural stop ID since it has a strong reference to this
+ // process
m_mod_id.SetStopEventForLastNaturalStopID(EventSP());
//#ifdef LLDB_CONFIGURATION_DEBUG
// StreamFile s(stdout, false);
@@ -937,14 +929,11 @@ void Process::SynchronouslyNotifyStateChanged(StateType state) {
// FIXME: We need to do some work on events before the general Listener sees
// them.
// For instance if we are continuing from a breakpoint, we need to ensure that
-// we do
-// the little "insert real insn, step & stop" trick. But we can't do that when
-// the
-// event is delivered by the broadcaster - since that is done on the thread that
-// is
-// waiting for new events, so if we needed more than one event for our handling,
-// we would
-// stall. So instead we do it when we fetch the event off of the queue.
+// we do the little "insert real insn, step & stop" trick. But we can't do
+// that when the event is delivered by the broadcaster - since that is done on
+// the thread that is waiting for new events, so if we needed more than one
+// event for our handling, we would stall. So instead we do it when we fetch
+// the event off of the queue.
//
StateType Process::GetNextEvent(EventSP &event_sp) {
@@ -958,21 +947,25 @@ StateType Process::GetNextEvent(EventSP &event_sp) {
return state;
}
-void Process::SyncIOHandler(uint32_t iohandler_id, uint64_t timeout_msec) {
+void Process::SyncIOHandler(uint32_t iohandler_id,
+ const Timeout<std::micro> &timeout) {
// don't sync (potentially context switch) in case where there is no process
// IO
if (!m_process_input_reader)
return;
- uint32_t new_iohandler_id = 0;
- m_iohandler_sync.WaitForValueNotEqualTo(
- iohandler_id, new_iohandler_id, std::chrono::milliseconds(timeout_msec));
+ auto Result = m_iohandler_sync.WaitForValueNotEqualTo(iohandler_id, timeout);
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("Process::%s waited for m_iohandler_sync to change from %u, "
- "new value is %u",
- __FUNCTION__, iohandler_id, new_iohandler_id);
+ if (Result) {
+ LLDB_LOG(
+ log,
+ "waited from m_iohandler_sync to change from {0}. New value is {1}.",
+ iohandler_id, *Result);
+ } else {
+ LLDB_LOG(log, "timed out waiting for m_iohandler_sync to change from {0}.",
+ iohandler_id);
+ }
}
StateType Process::WaitForProcessToStop(const Timeout<std::micro> &timeout,
@@ -980,15 +973,13 @@ StateType Process::WaitForProcessToStop(const Timeout<std::micro> &timeout,
ListenerSP hijack_listener_sp,
Stream *stream, bool use_run_lock) {
// We can't just wait for a "stopped" event, because the stopped event may
- // have restarted the target.
- // We have to actually check each event, and in the case of a stopped event
- // check the restarted flag
- // on the event.
+ // have restarted the target. We have to actually check each event, and in
+ // the case of a stopped event check the restarted flag on the event.
if (event_sp_ptr)
event_sp_ptr->reset();
StateType state = GetState();
- // If we are exited or detached, we won't ever get back to any
- // other valid state...
+ // If we are exited or detached, we won't ever get back to any other valid
+ // state...
if (state == eStateDetached || state == eStateExited)
return state;
@@ -1154,10 +1145,8 @@ bool Process::HandleProcessStateChangedEvent(const EventSP &event_sp,
case eStopReasonSignal: {
// Don't select a signal thread if we weren't going to stop at
- // that
- // signal. We have to have had another reason for stopping here,
- // and
- // the user doesn't want to see this thread.
+ // that signal. We have to have had another reason for stopping
+ // here, and the user doesn't want to see this thread.
uint64_t signo = thread->GetStopInfo()->GetValue();
if (process_sp->GetUnixSignals()->GetShouldStop(signo)) {
if (!other_thread)
@@ -1197,10 +1186,9 @@ bool Process::HandleProcessStateChangedEvent(const EventSP &event_sp,
}
}
// 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.
+ // 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 (stream) {
Debugger &debugger = process_sp->GetTarget().GetDebugger();
if (debugger.GetTargetList().GetSelectedTarget().get() ==
@@ -1388,8 +1376,8 @@ bool Process::SetExitStatus(int status, const char *cstr) {
else
m_exit_string.clear();
- // Clear the last natural stop ID since it has a strong
- // reference to this process
+ // Clear the last natural stop ID since it has a strong reference to this
+ // process
m_mod_id.SetStopEventForLastNaturalStopID(EventSP());
SetPrivateState(eStateExited);
@@ -1416,9 +1404,9 @@ bool Process::IsAlive() {
}
}
-// This static callback can be used to watch for local child processes on
-// the current host. The child process exits, the process will be
-// found in the global target list (we want to be completely sure that the
+// This static callback can be used to watch for local child processes on the
+// current host. The child process exits, the process will be found in the
+// global target list (we want to be completely sure that the
// lldb_private::Process doesn't go away before we can deliver the signal.
bool Process::SetProcessExitStatus(
lldb::pid_t pid, bool exited,
@@ -1455,20 +1443,19 @@ void Process::UpdateThreadListIfNeeded() {
const StateType state = GetPrivateState();
if (StateIsStoppedState(state, true)) {
std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
- // m_thread_list does have its own mutex, but we need to
- // hold onto the mutex between the call to UpdateThreadList(...)
- // and the os->UpdateThreadList(...) so it doesn't change on us
+ // m_thread_list does have its own mutex, but we need to hold onto the
+ // mutex between the call to UpdateThreadList(...) and the
+ // os->UpdateThreadList(...) so it doesn't change on us
ThreadList &old_thread_list = m_thread_list;
ThreadList real_thread_list(this);
ThreadList new_thread_list(this);
- // Always update the thread list with the protocol specific
- // thread list, but only update if "true" is returned
+ // Always update the thread list with the protocol specific thread list,
+ // but only update if "true" is returned
if (UpdateThreadList(m_thread_list_real, real_thread_list)) {
// Don't call into the OperatingSystem to update the thread list if we
- // are shutting down, since
- // that may call back into the SBAPI's, requiring the API lock which is
- // already held by whoever is
- // shutting us down, causing a deadlock.
+ // are shutting down, since that may call back into the SBAPI's,
+ // requiring the API lock which is already held by whoever is shutting
+ // us down, causing a deadlock.
OperatingSystem *os = GetOperatingSystem();
if (os && !m_destroy_in_process) {
// Clear any old backing threads where memory threads might have been
@@ -1478,12 +1465,9 @@ void Process::UpdateThreadListIfNeeded() {
old_thread_list.GetThreadAtIndex(i, false)->ClearBackingThread();
// Turn off dynamic types to ensure we don't run any expressions.
- // Objective C
- // can run an expression to determine if a SBValue is a dynamic type
- // or not
- // and we need to avoid this. OperatingSystem plug-ins can't run
- // expressions
- // that require running code...
+ // Objective-C can run an expression to determine if a SBValue is a
+ // dynamic type or not and we need to avoid this. OperatingSystem
+ // plug-ins can't run expressions that require running code...
Target &target = GetTarget();
const lldb::DynamicValueType saved_prefer_dynamic =
@@ -1592,9 +1576,9 @@ void Process::SetPublicState(StateType new_state, bool restarted) {
const StateType old_state = m_public_state.GetValue();
m_public_state.SetValue(new_state);
- // On the transition from Run to Stopped, we unlock the writer end of the
- // run lock. The lock gets locked in Resume, which is the public API
- // to tell the program to run.
+ // On the transition from Run to Stopped, we unlock the writer end of the run
+ // lock. The lock gets locked in Resume, which is the public API to tell the
+ // program to run.
if (!StateChangedIsExternallyHijacked()) {
if (new_state == eStateDetached) {
if (log)
@@ -1707,17 +1691,16 @@ void Process::SetPrivateState(StateType new_state) {
new Event(eBroadcastBitStateChanged,
new ProcessEventData(shared_from_this(), new_state)));
if (StateIsStoppedState(new_state, false)) {
- // Note, this currently assumes that all threads in the list
- // stop when the process stops. In the future we will want to
- // support a debugging model where some threads continue to run
- // while others are stopped. When that happens we will either need
- // a way for the thread list to identify which threads are stopping
- // or create a special thread list containing only threads which
- // actually stopped.
+ // Note, this currently assumes that all threads in the list stop when
+ // the process stops. In the future we will want to support a debugging
+ // model where some threads continue to run while others are stopped.
+ // When that happens we will either need a way for the thread list to
+ // identify which threads are stopping or create a special thread list
+ // containing only threads which actually stopped.
//
- // The process plugin is responsible for managing the actual
- // behavior of the threads and should have stopped any threads
- // that are going to stop before we get here.
+ // The process plugin is responsible for managing the actual behavior of
+ // the threads and should have stopped any threads that are going to stop
+ // before we get here.
m_thread_list.DidStop();
m_mod_id.BumpStopID();
@@ -1890,8 +1873,8 @@ Process::CreateBreakpointSite(const BreakpointLocationSP &owner,
break;
}
- // Reset the IsIndirect flag here, in case the location changes from
- // pointing to a indirect symbol to a regular symbol.
+ // Reset the IsIndirect flag here, in case the location changes from pointing
+ // to a indirect symbol to a regular symbol.
owner->SetIsIndirect(false);
if (owner->ShouldResolveIndirectFunctions()) {
@@ -1921,8 +1904,7 @@ Process::CreateBreakpointSite(const BreakpointLocationSP &owner,
BreakpointSiteSP bp_site_sp;
// Look up this breakpoint site. If it exists, then add this new owner,
- // otherwise
- // create a new breakpoint site and add it.
+ // otherwise create a new breakpoint site and add it.
bp_site_sp = m_breakpoint_site_list.FindByAddress(load_addr);
@@ -2170,7 +2152,8 @@ Status Process::DisableSoftwareBreakpoint(BreakpointSite *bp_site) {
return error;
}
-// Uncomment to verify memory caching works after making changes to caching code
+// Uncomment to verify memory caching works after making changes to caching
+// code
//#define VERIFY_MEMORY_READS
size_t Process::ReadMemory(addr_t addr, void *buf, size_t size, Status &error) {
@@ -2224,8 +2207,8 @@ size_t Process::ReadCStringFromMemory(addr_t addr, std::string &out_str,
if (length == 0)
break;
out_str.append(buf, length);
- // If we got "length - 1" bytes, we didn't get the whole C string, we
- // need to read some more characters
+ // If we got "length - 1" bytes, we didn't get the whole C string, we need
+ // to read some more characters
if (length == sizeof(buf) - 1)
curr_addr += length;
else
@@ -2238,7 +2221,8 @@ size_t Process::ReadStringFromMemory(addr_t addr, char *dst, size_t max_bytes,
Status &error, size_t type_width) {
size_t total_bytes_read = 0;
if (dst && max_bytes && type_width && max_bytes >= type_width) {
- // Ensure a null terminator independent of the number of bytes that is read.
+ // Ensure a null terminator independent of the number of bytes that is
+ // read.
memset(dst, 0, max_bytes);
size_t bytes_left = max_bytes - type_width;
@@ -2285,8 +2269,7 @@ size_t Process::ReadStringFromMemory(addr_t addr, char *dst, size_t max_bytes,
}
// Deprecated in favor of ReadStringFromMemory which has wchar support and
-// correct code to find
-// null terminators.
+// correct code to find null terminators.
size_t Process::ReadCStringFromMemory(addr_t addr, char *dst,
size_t dst_max_len,
Status &result_error) {
@@ -2460,16 +2443,16 @@ size_t Process::WriteMemory(addr_t addr, const void *buf, size_t size,
// Check for bytes before this breakpoint
const addr_t curr_addr = addr + bytes_written;
if (intersect_addr > curr_addr) {
- // There are some bytes before this breakpoint that we need to
- // just write to memory
+ // There are some bytes before this breakpoint that we need to just
+ // write to memory
size_t curr_size = intersect_addr - curr_addr;
size_t curr_bytes_written = WriteMemoryPrivate(
curr_addr, ubuf + bytes_written, curr_size, error);
bytes_written += curr_bytes_written;
if (curr_bytes_written != curr_size) {
- // We weren't able to write all of the requested bytes, we
- // are done looping and will return the number of bytes that
- // we have written so far.
+ // We weren't able to write all of the requested bytes, we are
+ // done looping and will return the number of bytes that we have
+ // written so far.
if (error.Success())
error.SetErrorToGenericError();
}
@@ -2542,11 +2525,24 @@ size_t Process::ReadScalarIntegerFromMemory(addr_t addr, uint32_t byte_size,
return 0;
}
+Status Process::WriteObjectFile(std::vector<ObjectFile::LoadableData> entries) {
+ Status error;
+ for (const auto &Entry : entries) {
+ WriteMemory(Entry.Dest, Entry.Contents.data(), Entry.Contents.size(),
+ error);
+ if (!error.Success())
+ break;
+ }
+ return error;
+}
+
#define USE_ALLOCATE_MEMORY_CACHE 1
addr_t Process::AllocateMemory(size_t size, uint32_t permissions,
Status &error) {
- if (GetPrivateState() != eStateStopped)
+ if (GetPrivateState() != eStateStopped) {
+ error.SetErrorToGenericError();
return LLDB_INVALID_ADDRESS;
+ }
#if defined(USE_ALLOCATE_MEMORY_CACHE)
return m_allocated_memory_cache.AllocateMemory(size, permissions, error);
@@ -2692,8 +2688,7 @@ StateType
Process::WaitForProcessStopPrivate(EventSP &event_sp,
const Timeout<std::micro> &timeout) {
StateType state;
- // Now wait for the process to launch and return control to us, and then
- // call DidLaunch:
+
while (true) {
event_sp.reset();
state = GetStateChangedEventsPrivate(event_sp, timeout);
@@ -2771,11 +2766,14 @@ Status Process::Launch(ProcessLaunchInfo &launch_info) {
}
} else {
EventSP event_sp;
+
+ // Now wait for the process to launch and return control to us, and then call
+ // DidLaunch:
StateType state = WaitForProcessStopPrivate(event_sp, seconds(10));
if (state == eStateInvalid || !event_sp) {
- // We were able to launch the process, but we failed to
- // catch the initial stop.
+ // We were able to launch the process, but we failed to catch the
+ // initial stop.
error.SetErrorString("failed to catch stop after launch");
SetExitStatus(0, "failed to catch stop after launch");
Destroy(false);
@@ -2795,18 +2793,15 @@ Status Process::Launch(ProcessLaunchInfo &launch_info) {
if (!m_os_ap)
LoadOperatingSystemPlugin(false);
- // We successfully launched the process and stopped,
- // now it the right time to set up signal filters before resuming.
+ // We successfully launched the process and stopped, now it the
+ // right time to set up signal filters before resuming.
UpdateAutomaticSignalFiltering();
// Note, the stop event was consumed above, but not handled. This
- // was done
- // to give DidLaunch a chance to run. The target is either stopped
- // or crashed.
- // Directly set the state. This is done to prevent a stop message
- // with a bunch
- // of spurious output on thread status, as well as not pop a
- // ProcessIOHandler.
+ // was done to give DidLaunch a chance to run. The target is either
+ // stopped or crashed. Directly set the state. This is done to
+ // prevent a stop message with a bunch of spurious output on thread
+ // status, as well as not pop a ProcessIOHandler.
SetPublicState(state, false);
if (PrivateStateThreadIsValid())
@@ -2815,15 +2810,13 @@ Status Process::Launch(ProcessLaunchInfo &launch_info) {
StartPrivateStateThread();
// Target was stopped at entry as was intended. Need to notify the
- // listeners
- // about it.
+ // listeners about it.
if (state == eStateStopped &&
launch_info.GetFlags().Test(eLaunchFlagStopAtEntry))
HandlePrivateEvent(event_sp);
} else if (state == eStateExited) {
// We exited while trying to launch somehow. Don't call DidLaunch
- // as that's
- // not likely to work, and return an invalid pid.
+ // as that's not likely to work, and return an invalid pid.
HandlePrivateEvent(event_sp);
}
}
@@ -2862,14 +2855,13 @@ Status Process::LoadCore() {
LoadOperatingSystemPlugin(false);
// We successfully loaded a core file, now pretend we stopped so we can
- // show all of the threads in the core file and explore the crashed
- // state.
+ // show all of the threads in the core file and explore the crashed state.
SetPrivateState(eStateStopped);
- // Wait indefinitely for a stopped event since we just posted one above...
+ // Wait for a stopped event since we just posted one above...
lldb::EventSP event_sp;
- listener_sp->GetEvent(event_sp, llvm::None);
- StateType state = ProcessEventData::GetStateFromEvent(event_sp.get());
+ StateType state =
+ WaitForProcessToStop(seconds(10), &event_sp, true, listener_sp);
if (!StateIsStoppedState(state, false)) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
@@ -2939,8 +2931,8 @@ Process::AttachCompletionHandler::PerformAction(lldb::EventSP &event_sp) {
// During attach, prior to sending the eStateStopped event,
// lldb_private::Process subclasses must set the new process ID.
assert(m_process->GetID() != LLDB_INVALID_PROCESS_ID);
- // We don't want these events to be reported, so go set the ShouldReportStop
- // here:
+ // We don't want these events to be reported, so go set the
+ // ShouldReportStop here:
m_process->GetThreadList().SetShouldReportStop(eVoteNo);
if (m_exec_count > 0) {
@@ -3134,8 +3126,8 @@ void Process::CompleteAttach() {
}
// We just attached. If we have a platform, ask it for the process
- // architecture, and if it isn't
- // the same as the one we've already set, switch architectures.
+ // architecture, and if it isn't the same as the one we've already set,
+ // switch architectures.
PlatformSP platform_sp(GetTarget().GetPlatform());
assert(platform_sp);
if (platform_sp) {
@@ -3272,21 +3264,20 @@ Status Process::PrivateResume() {
m_mod_id.GetStopID(), StateAsCString(m_public_state.GetValue()),
StateAsCString(m_private_state.GetValue()));
- // If signals handing status changed we might want to update
- // our signal filters before resuming.
+ // If signals handing status changed we might want to update our signal
+ // filters before resuming.
UpdateAutomaticSignalFiltering();
Status error(WillResume());
// Tell the process it is about to resume before the thread list
if (error.Success()) {
- // Now let the thread list know we are about to resume so it
- // can let all of our threads know that they are about to be
- // resumed. Threads will each be called with
- // Thread::WillResume(StateType) where StateType contains the state
- // that they are supposed to have when the process is resumed
- // (suspended/running/stepping). Threads should also check
- // their resume signal in lldb::Thread::GetResumeSignal()
- // to see if they are supposed to start back up with a signal.
+ // Now let the thread list know we are about to resume so it can let all of
+ // our threads know that they are about to be resumed. Threads will each be
+ // called with Thread::WillResume(StateType) where StateType contains the
+ // state that they are supposed to have when the process is resumed
+ // (suspended/running/stepping). Threads should also check their resume
+ // signal in lldb::Thread::GetResumeSignal() to see if they are supposed to
+ // start back up with a signal.
if (m_thread_list.WillResume()) {
// Last thing, do the PreResumeActions.
if (!RunPreResumeActions()) {
@@ -3303,11 +3294,10 @@ Status Process::PrivateResume() {
}
}
} else {
- // Somebody wanted to run without running (e.g. we were faking a step from
- // one frame of a set of inlined
- // frames that share the same PC to another.) So generate a continue & a
- // stopped event,
- // and let the world handle them.
+ // Somebody wanted to run without running (e.g. we were faking a step
+ // from one frame of a set of inlined frames that share the same PC to
+ // another.) So generate a continue & a stopped event, and let the world
+ // handle them.
if (log)
log->Printf(
"Process::PrivateResume() asked to simulate a start & stop.");
@@ -3325,9 +3315,8 @@ Status Process::Halt(bool clear_thread_plans, bool use_run_lock) {
if (!StateIsRunningState(m_public_state.GetValue()))
return Status("Process is not running.");
- // Don't clear the m_clear_thread_plans_on_stop, only set it to true if
- // in case it was already set and some thread plan logic calls halt on its
- // own.
+ // Don't clear the m_clear_thread_plans_on_stop, only set it to true if in
+ // case it was already set and some thread plan logic calls halt on its own.
m_clear_thread_plans_on_stop |= clear_thread_plans;
ListenerSP halt_listener_sp(
@@ -3339,8 +3328,8 @@ Status Process::Halt(bool clear_thread_plans, bool use_run_lock) {
SendAsyncInterrupt();
if (m_public_state.GetValue() == eStateAttaching) {
- // Don't hijack and eat the eStateExited as the code that was doing
- // the attach will be waiting for this event...
+ // Don't hijack and eat the eStateExited as the code that was doing the
+ // attach will be waiting for this event...
RestoreProcessEvents();
SetExitStatus(SIGKILL, "Cancelled async attach.");
Destroy(false);
@@ -3366,8 +3355,8 @@ Status Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp) {
Status error;
// Check both the public & private states here. If we're hung evaluating an
- // expression, for instance, then
- // the public state will be stopped, but we still need to interrupt.
+ // expression, for instance, then the public state will be stopped, but we
+ // still need to interrupt.
if (m_public_state.GetValue() == eStateRunning ||
m_private_state.GetValue() == eStateRunning) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
@@ -3387,10 +3376,9 @@ Status Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp) {
RestoreProcessEvents();
// If the process exited while we were waiting for it to stop, put the
- // exited event into
- // the shared pointer passed in and return. Our caller doesn't need to do
- // anything else, since
- // they don't have a process anymore...
+ // exited event into the shared pointer passed in and return. Our caller
+ // doesn't need to do anything else, since they don't have a process
+ // anymore...
if (state == eStateExited || m_private_state.GetValue() == eStateExited) {
if (log)
@@ -3405,9 +3393,8 @@ Status Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp) {
log->Printf("Process::%s() failed to stop, state is: %s", __FUNCTION__,
StateAsCString(state));
// If we really couldn't stop the process then we should just error out
- // here, but if the
- // lower levels just bobbled sending the event and we really are stopped,
- // then continue on.
+ // here, but if the lower levels just bobbled sending the event and we
+ // really are stopped, then continue on.
StateType private_state = m_private_state.GetValue();
if (private_state != eStateStopped) {
return Status(
@@ -3455,20 +3442,18 @@ Status Process::Detach(bool keep_stopped) {
}
m_destroy_in_process = false;
- // If we exited when we were waiting for a process to stop, then
- // forward the event here so we don't lose the event
+ // If we exited when we were waiting for a process to stop, then forward the
+ // event here so we don't lose the event
if (exit_event_sp) {
- // Directly broadcast our exited event because we shut down our
- // private state thread above
+ // Directly broadcast our exited event because we shut down our private
+ // state thread above
BroadcastEvent(exit_event_sp);
}
// If we have been interrupted (to kill us) in the middle of running, we may
- // not end up propagating
- // the last events through the event system, in which case we might strand the
- // write lock. Unlock
- // it here so when we do to tear down the process we don't get an error
- // destroying the lock.
+ // not end up propagating the last events through the event system, in which
+ // case we might strand the write lock. Unlock it here so when we do to tear
+ // down the process we don't get an error destroying the lock.
m_public_run_lock.SetStopped();
return error;
@@ -3477,9 +3462,8 @@ Status Process::Detach(bool keep_stopped) {
Status Process::Destroy(bool force_kill) {
// Tell ourselves we are in the process of destroying the process, so that we
- // don't do any unnecessary work
- // that might hinder the destruction. Remember to set this back to false when
- // we are done. That way if the attempt
+ // don't do any unnecessary work that might hinder the destruction. Remember
+ // to set this back to false when we are done. That way if the attempt
// failed and the process stays around for some reason it won't be in a
// confused state.
@@ -3502,12 +3486,11 @@ Status Process::Destroy(bool force_kill) {
}
if (m_public_state.GetValue() != eStateRunning) {
- // Ditch all thread plans, and remove all our breakpoints: in case we have
- // to restart the target to
- // kill it, we don't want it hitting a breakpoint...
- // Only do this if we've stopped, however, since if we didn't manage to
- // halt it above, then
- // we're not going to have much luck doing this now.
+ // Ditch all thread plans, and remove all our breakpoints: in case we
+ // have to restart the target to kill it, we don't want it hitting a
+ // breakpoint... Only do this if we've stopped, however, since if we
+ // didn't manage to halt it above, then we're not going to have much luck
+ // doing this now.
m_thread_list.DiscardThreadPlans();
DisableAllBreakpointSites();
}
@@ -3527,20 +3510,18 @@ Status Process::Destroy(bool force_kill) {
m_process_input_reader.reset();
}
- // If we exited when we were waiting for a process to stop, then
- // forward the event here so we don't lose the event
+ // If we exited when we were waiting for a process to stop, then forward
+ // the event here so we don't lose the event
if (exit_event_sp) {
- // Directly broadcast our exited event because we shut down our
- // private state thread above
+ // Directly broadcast our exited event because we shut down our private
+ // state thread above
BroadcastEvent(exit_event_sp);
}
- // If we have been interrupted (to kill us) in the middle of running, we may
- // not end up propagating
- // the last events through the event system, in which case we might strand
- // the write lock. Unlock
- // it here so when we do to tear down the process we don't get an error
- // destroying the lock.
+ // If we have been interrupted (to kill us) in the middle of running, we
+ // may not end up propagating the last events through the event system, in
+ // which case we might strand the write lock. Unlock it here so when we do
+ // to tear down the process we don't get an error destroying the lock.
m_public_run_lock.SetStopped();
}
@@ -3607,11 +3588,11 @@ bool Process::ShouldBroadcastEvent(Event *event_ptr) {
break;
case eStateRunning:
case eStateStepping:
- // If we've started the target running, we handle the cases where we
- // are already running and where there is a transition from stopped to
- // running differently.
- // running -> running: Automatically suppress extra running events
- // stopped -> running: Report except when there is one or more no votes
+ // If we've started the target running, we handle the cases where we are
+ // already running and where there is a transition from stopped to running
+ // differently. running -> running: Automatically suppress extra running
+ // events stopped -> running: Report except when there is one or more no
+ // votes
// and no yes votes.
SynchronouslyNotifyStateChanged(state);
if (m_force_next_event_delivery)
@@ -3625,11 +3606,10 @@ bool Process::ShouldBroadcastEvent(Event *event_ptr) {
break;
default:
// TODO: make this work correctly. For now always report
- // run if we aren't running so we don't miss any running
- // events. If I run the lldb/test/thread/a.out file and
- // break at main.cpp:58, run and hit the breakpoints on
- // multiple threads, then somehow during the stepping over
- // of all breakpoints no run gets reported.
+ // run if we aren't running so we don't miss any running events. If I
+ // run the lldb/test/thread/a.out file and break at main.cpp:58, run
+ // and hit the breakpoints on multiple threads, then somehow during the
+ // stepping over of all breakpoints no run gets reported.
// This is a transition from stop to run.
switch (m_thread_list.ShouldReportRun(event_ptr)) {
@@ -3648,11 +3628,10 @@ bool Process::ShouldBroadcastEvent(Event *event_ptr) {
case eStateStopped:
case eStateCrashed:
case eStateSuspended:
- // We've stopped. First see if we're going to restart the target.
- // If we are going to stop, then we always broadcast the event.
- // If we aren't going to stop, let the thread plans decide if we're going to
- // report this event.
- // If no thread has an opinion, we don't report it.
+ // We've stopped. First see if we're going to restart the target. If we
+ // are going to stop, then we always broadcast the event. If we aren't
+ // going to stop, let the thread plans decide if we're going to report this
+ // event. If no thread has an opinion, we don't report it.
m_stdio_communication.SynchronizeWithReadThread();
RefreshStateAfterStop();
@@ -3662,8 +3641,7 @@ bool Process::ShouldBroadcastEvent(Event *event_ptr) {
"interrupt, state: %s",
static_cast<void *>(event_ptr), StateAsCString(state));
// Even though we know we are going to stop, we should let the threads
- // have a look at the stop,
- // so they can properly set their state.
+ // have a look at the stop, so they can properly set their state.
m_thread_list.ShouldStop(event_ptr);
return_value = true;
} else {
@@ -3671,10 +3649,8 @@ bool Process::ShouldBroadcastEvent(Event *event_ptr) {
bool should_resume = false;
// It makes no sense to ask "ShouldStop" if we've already been
- // restarted...
- // Asking the thread list is also not likely to go well, since we are
- // running again.
- // So in that case just report the event.
+ // restarted... Asking the thread list is also not likely to go well,
+ // since we are running again. So in that case just report the event.
if (!was_restarted)
should_resume = !m_thread_list.ShouldStop(event_ptr);
@@ -3717,16 +3693,13 @@ bool Process::ShouldBroadcastEvent(Event *event_ptr) {
m_force_next_event_delivery = false;
// We do some coalescing of events (for instance two consecutive running
- // events get coalesced.)
- // But we only coalesce against events we actually broadcast. So we use
- // m_last_broadcast_state
- // to track that. NB - you can't use "m_public_state.GetValue()" for that
- // purpose, as was originally done,
- // because the PublicState reflects the last event pulled off the queue, and
- // there may be several
- // events stacked up on the queue unserviced. So the PublicState may not
- // reflect the last broadcasted event
- // yet. m_last_broadcast_state gets updated here.
+ // events get coalesced.) But we only coalesce against events we actually
+ // broadcast. So we use m_last_broadcast_state to track that. NB - you
+ // can't use "m_public_state.GetValue()" for that purpose, as was originally
+ // done, because the PublicState reflects the last event pulled off the
+ // queue, and there may be several events stacked up on the queue unserviced.
+ // So the PublicState may not reflect the last broadcasted event yet.
+ // m_last_broadcast_state gets updated here.
if (return_value)
m_last_broadcast_state = state;
@@ -3752,8 +3725,8 @@ bool Process::StartPrivateStateThread(bool is_secondary_thread) {
if (!is_secondary_thread && already_running)
return true;
- // Create a thread that watches our internal state and controls which
- // events make it to clients (into the DCProcess event queue).
+ // Create a thread that watches our internal state and controls which events
+ // make it to clients (into the DCProcess event queue).
char thread_name[1024];
uint32_t max_len = llvm::get_max_thread_name_length();
if (max_len > 0 && max_len <= 30) {
@@ -3818,10 +3791,10 @@ void Process::ControlPrivateStateThread(uint32_t signal) {
// Signal the private state thread
if (m_private_state_thread.IsJoinable()) {
// Broadcast the event.
- // It is important to do this outside of the if below, because
- // it's possible that the thread state is invalid but that the
- // thread is waiting on a control event instead of simply being
- // on its way out (this should not happen, but it apparently can).
+ // It is important to do this outside of the if below, because it's
+ // possible that the thread state is invalid but that the thread is waiting
+ // on a control event instead of simply being on its way out (this should
+ // not happen, but it apparently can).
if (log)
log->Printf("Sending control event of type: %d.", signal);
std::shared_ptr<EventDataReceipt> event_receipt_sp(new EventDataReceipt());
@@ -3832,14 +3805,13 @@ void Process::ControlPrivateStateThread(uint32_t signal) {
bool receipt_received = false;
if (PrivateStateThreadIsValid()) {
while (!receipt_received) {
- bool timed_out = false;
- // Check for a receipt for 2 seconds and then check if the private state
- // thread is still around.
- receipt_received = event_receipt_sp->WaitForEventReceived(
- std::chrono::seconds(2), &timed_out);
+ // Check for a receipt for 2 seconds and then check if the private
+ // state thread is still around.
+ receipt_received =
+ event_receipt_sp->WaitForEventReceived(std::chrono::seconds(2));
if (!receipt_received) {
- // Check if the private state thread is still around. If it isn't then
- // we are done waiting
+ // Check if the private state thread is still around. If it isn't
+ // then we are done waiting
if (!PrivateStateThreadIsValid())
break; // Private state thread exited or is exiting, we are done
}
@@ -3889,9 +3861,9 @@ void Process::HandlePrivateEvent(EventSP &event_sp) {
break;
case NextEventAction::eEventActionExit:
- // Handle Exiting Here. If we already got an exited event,
- // we should just propagate it. Otherwise, swallow this event,
- // and set our state to exit so the next event will kill us.
+ // Handle Exiting Here. If we already got an exited event, we should
+ // just propagate it. Otherwise, swallow this event, and set our state
+ // to exit so the next event will kill us.
if (new_state != eStateExited) {
// FIXME: should cons up an exited event, and discard this one.
SetExitStatus(0, m_next_event_action_ap->GetExitString());
@@ -3917,9 +3889,9 @@ void Process::HandlePrivateEvent(EventSP &event_sp) {
}
Process::ProcessEventData::SetUpdateStateOnRemoval(event_sp.get());
if (StateIsRunningState(new_state)) {
- // Only push the input handler if we aren't fowarding events,
- // as this means the curses GUI is in use...
- // Or don't push it if we are launching since it will come up stopped.
+ // Only push the input handler if we aren't fowarding events, as this
+ // means the curses GUI is in use... Or don't push it if we are launching
+ // since it will come up stopped.
if (!GetTarget().GetDebugger().IsForwardingEvents() &&
new_state != eStateLaunching && new_state != eStateAttaching) {
PushProcessIOHandler();
@@ -3931,27 +3903,26 @@ void Process::HandlePrivateEvent(EventSP &event_sp) {
}
} else if (StateIsStoppedState(new_state, false)) {
if (!Process::ProcessEventData::GetRestartedFromEvent(event_sp.get())) {
- // If the lldb_private::Debugger is handling the events, we don't
- // want to pop the process IOHandler here, we want to do it when
- // we receive the stopped event so we can carefully control when
- // the process IOHandler is popped because when we stop we want to
- // display some text stating how and why we stopped, then maybe some
- // process/thread/frame info, and then we want the "(lldb) " prompt
- // to show up. If we pop the process IOHandler here, then we will
- // cause the command interpreter to become the top IOHandler after
- // the process pops off and it will update its prompt right away...
- // See the Debugger.cpp file where it calls the function as
+ // If the lldb_private::Debugger is handling the events, we don't want
+ // to pop the process IOHandler here, we want to do it when we receive
+ // the stopped event so we can carefully control when the process
+ // IOHandler is popped because when we stop we want to display some
+ // text stating how and why we stopped, then maybe some
+ // process/thread/frame info, and then we want the "(lldb) " prompt to
+ // show up. If we pop the process IOHandler here, then we will cause
+ // the command interpreter to become the top IOHandler after the
+ // process pops off and it will update its prompt right away... See the
+ // Debugger.cpp file where it calls the function as
// "process_sp->PopProcessIOHandler()" to see where I am talking about.
// Otherwise we end up getting overlapping "(lldb) " prompts and
// garbled output.
//
// If we aren't handling the events in the debugger (which is indicated
- // by "m_target.GetDebugger().IsHandlingEvents()" returning false) or we
- // are hijacked, then we always pop the process IO handler manually.
+ // by "m_target.GetDebugger().IsHandlingEvents()" returning false) or
+ // we are hijacked, then we always pop the process IO handler manually.
// Hijacking happens when the internal process state thread is running
- // thread plans, or when commands want to run in synchronous mode
- // and they call "process->WaitForProcessToStop()". An example of
- // something
+ // thread plans, or when commands want to run in synchronous mode and
+ // they call "process->WaitForProcessToStop()". An example of something
// that will hijack the events is a simple expression:
//
// (lldb) expr (int)puts("hello")
@@ -4054,23 +4025,19 @@ thread_result_t Process::RunPrivateStateThread(bool is_secondary_thread) {
") failed to halt the process: %s",
__FUNCTION__, static_cast<void *>(this), GetID(),
error.AsCString());
- // Halt should generate a stopped event. Make a note of the fact that we
- // were
- // doing the interrupt, so we can set the interrupted flag after we
- // receive the
- // event. We deliberately set this to true even if HaltPrivate failed,
- // so that we
- // can interrupt on the next natural stop.
+ // Halt should generate a stopped event. Make a note of the fact that
+ // we were doing the interrupt, so we can set the interrupted flag
+ // after we receive the event. We deliberately set this to true even if
+ // HaltPrivate failed, so that we can interrupt on the next natural
+ // stop.
interrupt_requested = true;
} else {
// This can happen when someone (e.g. Process::Halt) sees that we are
- // running and
- // sends an interrupt request, but the process actually stops before we
- // receive
- // it. In that case, we can just ignore the request. We use
- // m_last_broadcast_state, because the Stopped event may not have been
- // popped of
- // the event queue yet, which is when the public state gets updated.
+ // running and sends an interrupt request, but the process actually
+ // stops before we receive it. In that case, we can just ignore the
+ // request. We use m_last_broadcast_state, because the Stopped event
+ // may not have been popped of the event queue yet, which is when the
+ // public state gets updated.
if (log)
log->Printf(
"Process::%s ignoring interrupt as we have already stopped.",
@@ -4092,8 +4059,7 @@ thread_result_t Process::RunPrivateStateThread(bool is_secondary_thread) {
if (interrupt_requested) {
if (StateIsStoppedState(internal_state, true)) {
// We requested the interrupt, so mark this as such in the stop event
- // so
- // clients can tell an interrupted process from a natural stop
+ // so clients can tell an interrupted process from a natural stop
ProcessEventData::SetInterruptedInEvent(event_sp.get(), true);
interrupt_requested = false;
} else if (log) {
@@ -4124,10 +4090,8 @@ thread_result_t Process::RunPrivateStateThread(bool is_secondary_thread) {
__FUNCTION__, static_cast<void *>(this), GetID());
// If we are a secondary thread, then the primary thread we are working for
- // will have already
- // acquired the public_run_lock, and isn't done with what it was doing yet, so
- // don't
- // try to change it on the way out.
+ // will have already acquired the public_run_lock, and isn't done with what
+ // it was doing yet, so don't try to change it on the way out.
if (!is_secondary_thread)
m_public_run_lock.SetStopped();
return NULL;
@@ -4167,14 +4131,12 @@ void Process::ProcessEventData::DoOnRemoval(Event *event_ptr) {
return;
// This function gets called twice for each event, once when the event gets
- // pulled
- // off of the private process event queue, and then any number of times, first
- // when it gets pulled off of
- // the public event queue, then other times when we're pretending that this is
- // where we stopped at the
- // end of expression evaluation. m_update_state is used to distinguish these
- // three cases; it is 0 when we're just pulling it off for private handling,
- // and > 1 for expression evaluation, and we don't want to do the breakpoint
+ // pulled off of the private process event queue, and then any number of
+ // times, first when it gets pulled off of the public event queue, then other
+ // times when we're pretending that this is where we stopped at the end of
+ // expression evaluation. m_update_state is used to distinguish these three
+ // cases; it is 0 when we're just pulling it off for private handling, and >
+ // 1 for expression evaluation, and we don't want to do the breakpoint
// command handling then.
if (m_update_state != 1)
return;
@@ -4183,16 +4145,15 @@ void Process::ProcessEventData::DoOnRemoval(Event *event_ptr) {
m_state, Process::ProcessEventData::GetRestartedFromEvent(event_ptr));
if (m_state == eStateStopped && !m_restarted) {
- // Let process subclasses know we are about to do a public stop and
- // do anything they might need to in order to speed up register and
- // memory accesses.
+ // Let process subclasses know we are about to do a public stop and do
+ // anything they might need to in order to speed up register and memory
+ // accesses.
process_sp->WillPublicStop();
}
// If this is a halt event, even if the halt stopped with some reason other
- // than a plain interrupt (e.g. we had
- // already stopped for a breakpoint when the halt request came through) don't
- // do the StopInfo actions, as they may
+ // than a plain interrupt (e.g. we had already stopped for a breakpoint when
+ // the halt request came through) don't do the StopInfo actions, as they may
// end up restarting the process.
if (m_interrupted)
return;
@@ -4204,37 +4165,32 @@ void Process::ProcessEventData::DoOnRemoval(Event *event_ptr) {
uint32_t idx;
// The actions might change one of the thread's stop_info's opinions about
- // whether we should
- // stop the process, so we need to query that as we go.
+ // whether we should stop the process, so we need to query that as we go.
// One other complication here, is that we try to catch any case where the
- // target has run (except for expressions)
- // and immediately exit, but if we get that wrong (which is possible) then
- // the thread list might have changed, and
- // that would cause our iteration here to crash. We could make a copy of
- // the thread list, but we'd really like
- // to also know if it has changed at all, so we make up a vector of the
- // thread ID's and check what we get back
- // against this list & bag out if anything differs.
+ // target has run (except for expressions) and immediately exit, but if we
+ // get that wrong (which is possible) then the thread list might have
+ // changed, and that would cause our iteration here to crash. We could
+ // make a copy of the thread list, but we'd really like to also know if it
+ // has changed at all, so we make up a vector of the thread ID's and check
+ // what we get back against this list & bag out if anything differs.
std::vector<uint32_t> thread_index_array(num_threads);
for (idx = 0; idx < num_threads; ++idx)
thread_index_array[idx] =
curr_thread_list.GetThreadAtIndex(idx)->GetIndexID();
// Use this to track whether we should continue from here. We will only
- // continue the target running if
- // no thread says we should stop. Of course if some thread's PerformAction
- // actually sets the target running,
- // then it doesn't matter what the other threads say...
+ // continue the target running if no thread says we should stop. Of course
+ // if some thread's PerformAction actually sets the target running, then it
+ // doesn't matter what the other threads say...
bool still_should_stop = false;
// Sometimes - for instance if we have a bug in the stub we are talking to,
- // we stop but no thread has a
- // valid stop reason. In that case we should just stop, because we have no
- // way of telling what the right
- // thing to do is, and it's better to let the user decide than continue
- // behind their backs.
+ // we stop but no thread has a valid stop reason. In that case we should
+ // just stop, because we have no way of telling what the right thing to do
+ // is, and it's better to let the user decide than continue behind their
+ // backs.
bool does_anybody_have_an_opinion = false;
@@ -4271,13 +4227,11 @@ void Process::ProcessEventData::DoOnRemoval(Event *event_ptr) {
stop_info_sp->GetOverriddenShouldStopValue();
} else {
stop_info_sp->PerformAction(event_ptr);
- // The stop action might restart the target. If it does, then we want
- // to mark that in the
- // event so that whoever is receiving it will know to wait for the
- // running event and reflect
- // that state appropriately.
- // We also need to stop processing actions, since they aren't
- // expecting the target to be running.
+ // The stop action might restart the target. If it does, then we
+ // want to mark that in the event so that whoever is receiving it
+ // will know to wait for the running event and reflect that state
+ // appropriately. We also need to stop processing actions, since they
+ // aren't expecting the target to be running.
// FIXME: we might have run.
if (stop_info_sp->HasTargetRunSinceMe()) {
@@ -4297,12 +4251,12 @@ void Process::ProcessEventData::DoOnRemoval(Event *event_ptr) {
if (!still_should_stop && does_anybody_have_an_opinion) {
// We've been asked to continue, so do that here.
SetRestarted(true);
- // Use the public resume method here, since this is just
- // extending a public resume.
+ // Use the public resume method here, since this is just extending a
+ // public resume.
process_sp->PrivateResume();
} else {
- // If we didn't restart, run the Stop Hooks here:
- // They might also restart the target, so watch for that.
+ // If we didn't restart, run the Stop Hooks here: They might also
+ // restart the target, so watch for that.
process_sp->GetTarget().RunStopHooks();
if (process_sp->GetPrivateState() == eStateRunning)
SetRestarted(true);
@@ -4423,7 +4377,7 @@ bool Process::ProcessEventData::SetUpdateStateOnRemoval(Event *event_ptr) {
return false;
}
-lldb::TargetSP Process::CalculateTarget() { return m_target_sp.lock(); }
+lldb::TargetSP Process::CalculateTarget() { return m_target_wp.lock(); }
void Process::CalculateExecutionContext(ExecutionContext &exe_ctx) {
exe_ctx.SetTargetPtr(&GetTarget());
@@ -4574,9 +4528,8 @@ public:
~IOHandlerProcessSTDIO() override = default;
- // Each IOHandler gets to run until it is done. It should read data
- // from the "in" and place output into "out" and "err and return
- // when done.
+ // Each IOHandler gets to run until it is done. It should read data from the
+ // "in" and place output into "out" and "err and return when done.
void Run() override {
if (!m_read_file.IsValid() || !m_write_file.IsValid() ||
!m_pipe.CanRead() || !m_pipe.CanWrite()) {
@@ -4640,9 +4593,8 @@ public:
void Cancel() override {
SetIsDone(true);
// Only write to our pipe to cancel if we are in
- // IOHandlerProcessSTDIO::Run().
- // We can end up with a python command that is being run from the command
- // interpreter:
+ // IOHandlerProcessSTDIO::Run(). We can end up with a python command that
+ // is being run from the command interpreter:
//
// (lldb) step_process_thousands_of_times
//
@@ -4659,12 +4611,11 @@ public:
}
bool Interrupt() override {
- // Do only things that are safe to do in an interrupt context (like in
- // a SIGINT handler), like write 1 byte to a file descriptor. This will
+ // Do only things that are safe to do in an interrupt context (like in a
+ // SIGINT handler), like write 1 byte to a file descriptor. This will
// interrupt the IOHandlerProcessSTDIO::Run() and we can look at the byte
// that was written to the pipe and then call
- // m_process->SendAsyncInterrupt()
- // from a much safer location in code.
+ // m_process->SendAsyncInterrupt() from a much safer location in code.
if (m_active) {
char ch = 'i'; // Send 'i' for interrupt
size_t bytes_written = 0;
@@ -4672,16 +4623,13 @@ public:
return result.Success();
} else {
// This IOHandler might be pushed on the stack, but not being run
- // currently
- // so do the right thing if we aren't actively watching for STDIN by
- // sending
- // the interrupt to the process. Otherwise the write to the pipe above
- // would
- // do nothing. This can happen when the command interpreter is running and
- // gets a "expression ...". It will be on the IOHandler thread and sending
- // the input is complete to the delegate which will cause the expression
- // to
- // run, which will push the process IO handler, but not run it.
+ // currently so do the right thing if we aren't actively watching for
+ // STDIN by sending the interrupt to the process. Otherwise the write to
+ // the pipe above would do nothing. This can happen when the command
+ // interpreter is running and gets a "expression ...". It will be on the
+ // IOHandler thread and sending the input is complete to the delegate
+ // which will cause the expression to run, which will push the process IO
+ // handler, but not run it.
if (StateIsRunningState(m_process->GetState())) {
m_process->SendAsyncInterrupt();
@@ -4756,12 +4704,10 @@ void Process::SettingsInitialize() { Thread::SettingsInitialize(); }
void Process::SettingsTerminate() { Thread::SettingsTerminate(); }
namespace {
-// RestorePlanState is used to record the "is private", "is master" and "okay to
-// discard" fields of
-// the plan we are running, and reset it on Clean or on destruction.
-// It will only reset the state once, so you can call Clean and then monkey with
-// the state and it
-// won't get reset on you again.
+// RestorePlanState is used to record the "is private", "is master" and "okay
+// to discard" fields of the plan we are running, and reset it on Clean or on
+// destruction. It will only reset the state once, so you can call Clean and
+// then monkey with the state and it won't get reset on you again.
class RestorePlanState {
public:
@@ -4817,8 +4763,8 @@ GetOneThreadExpressionTimeout(const EvaluateExpressionOptions &options) {
static Timeout<std::micro>
GetExpressionTimeout(const EvaluateExpressionOptions &options,
bool before_first_timeout) {
- // If we are going to run all threads the whole time, or if we are only
- // going to run one thread, we can just return the overall timeout.
+ // If we are going to run all threads the whole time, or if we are only going
+ // to run one thread, we can just return the overall timeout.
if (!options.GetStopOthers() || !options.GetTryAllThreads())
return options.GetTimeout();
@@ -4855,7 +4801,8 @@ HandleStoppedEvent(Thread &thread, const ThreadPlanSP &thread_plan_sp,
if (!options.DoesIgnoreBreakpoints()) {
// Restore the plan state and then force Private to false. We are going
// to stop because of this plan so we need it to become a public plan or
- // it won't report correctly when we continue to its termination later on.
+ // it won't report correctly when we continue to its termination later
+ // on.
restorer.Clean();
thread_plan_sp->SetPrivate(false);
event_to_broadcast_sp = event_sp;
@@ -4910,23 +4857,20 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
}
// We need to change some of the thread plan attributes for the thread plan
- // runner. This will restore them
- // when we are done:
+ // runner. This will restore them when we are done:
RestorePlanState thread_plan_restorer(thread_plan_sp);
- // We rely on the thread plan we are running returning "PlanCompleted" if when
- // it successfully completes.
- // For that to be true the plan can't be private - since private plans
- // suppress themselves in the
- // GetCompletedPlan call.
+ // We rely on the thread plan we are running returning "PlanCompleted" if
+ // when it successfully completes. For that to be true the plan can't be
+ // private - since private plans suppress themselves in the GetCompletedPlan
+ // call.
thread_plan_sp->SetPrivate(false);
// The plans run with RunThreadPlan also need to be terminal master plans or
- // when they are done we will end
- // up asking the plan above us whether we should stop, which may give the
- // wrong answer.
+ // when they are done we will end up asking the plan above us whether we
+ // should stop, which may give the wrong answer.
thread_plan_sp->SetIsMasterPlan(true);
thread_plan_sp->SetOkayToDiscard(false);
@@ -4953,8 +4897,8 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
}
}
- // Make sure the timeout values make sense. The one thread timeout needs to be
- // smaller than the overall timeout.
+ // Make sure the timeout values make sense. The one thread timeout needs to
+ // be smaller than the overall timeout.
if (options.GetOneThreadTimeout() && options.GetTimeout() &&
*options.GetTimeout() < *options.GetOneThreadTimeout()) {
diagnostic_manager.PutString(eDiagnosticSeverityError,
@@ -4966,8 +4910,8 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
StackID ctx_frame_id = selected_frame_sp->GetStackID();
// N.B. Running the target may unset the currently selected thread and frame.
- // We don't want to do that either,
- // so we should arrange to reset them as well.
+ // We don't want to do that either, so we should arrange to reset them as
+ // well.
lldb::ThreadSP selected_thread_sp = GetThreadList().GetSelectedThread();
@@ -4988,11 +4932,10 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
LIBLLDB_LOG_PROCESS));
if (m_private_state_thread.EqualsThread(Host::GetCurrentThread())) {
// Yikes, we are running on the private state thread! So we can't wait for
- // public events on this thread, since
- // we are the thread that is generating public events.
- // The simplest thing to do is to spin up a temporary thread to handle
- // private state thread events while
- // we are fielding public events here.
+ // public events on this thread, since we are the thread that is generating
+ // public events. The simplest thing to do is to spin up a temporary thread
+ // to handle private state thread events while we are fielding public
+ // events here.
if (log)
log->Printf("Running thread plan on private state thread, spinning up "
"another state thread to handle the events.");
@@ -5000,15 +4943,12 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
backup_private_state_thread = m_private_state_thread;
// One other bit of business: we want to run just this thread plan and
- // anything it pushes, and then stop,
- // returning control here.
- // But in the normal course of things, the plan above us on the stack would
- // be given a shot at the stop
- // event before deciding to stop, and we don't want that. So we insert a
- // "stopper" base plan on the stack
- // before the plan we want to run. Since base plans always stop and return
- // control to the user, that will
- // do just what we want.
+ // anything it pushes, and then stop, returning control here. But in the
+ // normal course of things, the plan above us on the stack would be given a
+ // shot at the stop event before deciding to stop, and we don't want that.
+ // So we insert a "stopper" base plan on the stack before the plan we want
+ // to run. Since base plans always stop and return control to the user,
+ // that will do just what we want.
stopper_base_plan_sp.reset(new ThreadPlanBase(*thread));
thread->QueueThreadPlan(stopper_base_plan_sp, false);
// Have to make sure our public state is stopped, since otherwise the
@@ -5024,15 +4964,13 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
thread_plan_sp, false); // This used to pass "true" does that make sense?
if (options.GetDebug()) {
- // In this case, we aren't actually going to run, we just want to stop right
- // away.
- // Flush this thread so we will refetch the stacks and show the correct
- // backtrace.
+ // In this case, we aren't actually going to run, we just want to stop
+ // right away. Flush this thread so we will refetch the stacks and show the
+ // correct backtrace.
// FIXME: To make this prettier we should invent some stop reason for this,
// but that
// is only cosmetic, and this functionality is only of use to lldb
- // developers who can
- // live with not pretty...
+ // developers who can live with not pretty...
thread->Flush();
return eExpressionStoppedForDebug;
}
@@ -5044,12 +4982,11 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
{
// This process event hijacker Hijacks the Public events and its destructor
- // makes sure that the process events get
- // restored on exit to the function.
+ // makes sure that the process events get restored on exit to the function.
//
// If the event needs to propagate beyond the hijacker (e.g., the process
- // exits during execution), then the event
- // is put into event_to_broadcast_sp for rebroadcasting.
+ // exits during execution), then the event is put into
+ // event_to_broadcast_sp for rebroadcasting.
ProcessEventHijacker run_thread_plan_hijacker(*this, listener_sp);
@@ -5084,10 +5021,10 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
options.GetStopOthers(), options.GetTryAllThreads(),
before_first_timeout);
- // This isn't going to work if there are unfetched events on the queue.
- // Are there cases where we might want to run the remaining events here, and
- // then try to
- // call the function? That's probably being too tricky for our own good.
+ // This isn't going to work if there are unfetched events on the queue. Are
+ // there cases where we might want to run the remaining events here, and
+ // then try to call the function? That's probably being too tricky for our
+ // own good.
Event *other_events = listener_sp->PeekAtNextEvent();
if (other_events != nullptr) {
@@ -5098,32 +5035,29 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
}
// We also need to make sure that the next event is delivered. We might be
- // calling a function as part of
- // a thread plan, in which case the last delivered event could be the
- // running event, and we don't want
- // event coalescing to cause us to lose OUR running event...
+ // calling a function as part of a thread plan, in which case the last
+ // delivered event could be the running event, and we don't want event
+ // coalescing to cause us to lose OUR running event...
ForceNextEventDelivery();
// This while loop must exit out the bottom, there's cleanup that we need to do
-// when we are done.
-// So don't call return anywhere within it.
+// when we are done. So don't call return anywhere within it.
#ifdef LLDB_RUN_THREAD_HALT_WITH_EVENT
- // It's pretty much impossible to write test cases for things like:
- // One thread timeout expires, I go to halt, but the process already stopped
- // on the function call stop breakpoint. Turning on this define will make
- // us not
- // fetch the first event till after the halt. So if you run a quick
- // function, it will have
- // completed, and the completion event will be waiting, when you interrupt
- // for halt.
- // The expression evaluation should still succeed.
+ // It's pretty much impossible to write test cases for things like: One
+ // thread timeout expires, I go to halt, but the process already stopped on
+ // the function call stop breakpoint. Turning on this define will make us
+ // not fetch the first event till after the halt. So if you run a quick
+ // function, it will have completed, and the completion event will be
+ // waiting, when you interrupt for halt. The expression evaluation should
+ // still succeed.
bool miss_first_event = true;
#endif
while (true) {
- // We usually want to resume the process if we get to the top of the loop.
- // The only exception is if we get two running events with no intervening
- // stop, which can happen, we will just wait for then next stop event.
+ // We usually want to resume the process if we get to the top of the
+ // loop. The only exception is if we get two running events with no
+ // intervening stop, which can happen, we will just wait for then next
+ // stop event.
if (log)
log->Printf("Top of while loop: do_resume: %i handle_running_event: %i "
"before_first_timeout: %i.",
@@ -5182,9 +5116,8 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
if (restarted) {
// This is probably an overabundance of caution, I don't think I
- // should ever get a stopped & restarted
- // event here. But if I do, the best thing is to Halt and then get
- // out of here.
+ // should ever get a stopped & restarted event here. But if I do,
+ // the best thing is to Halt and then get out of here.
const bool clear_thread_plans = false;
const bool use_run_lock = false;
Halt(clear_thread_plans, use_run_lock);
@@ -5200,14 +5133,11 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
if (log)
log->PutCString("Process::RunThreadPlan(): resuming succeeded.");
- // We need to call the function synchronously, so spin waiting for it to
- // return.
- // If we get interrupted while executing, we're going to lose our
- // context, and
- // won't be able to gather the result at this point.
- // We set the timeout AFTER the resume, since the resume takes some time
- // and we
- // don't want to charge that to the timeout.
+ // We need to call the function synchronously, so spin waiting for it
+ // to return. If we get interrupted while executing, we're going to
+ // lose our context, and won't be able to gather the result at this
+ // point. We set the timeout AFTER the resume, since the resume takes
+ // some time and we don't want to charge that to the timeout.
} else {
if (log)
log->PutCString("Process::RunThreadPlan(): waiting for next event.");
@@ -5299,9 +5229,8 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
case lldb::eStateRunning:
// This shouldn't really happen, but sometimes we do get two
- // running events without an
- // intervening stop, and in that case we should just go back to
- // waiting for the stop.
+ // running events without an intervening stop, and in that case
+ // we should just go back to waiting for the stop.
do_resume = false;
keep_going = true;
handle_running_event = false;
@@ -5336,10 +5265,10 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
break;
}
} else {
- // If we didn't get an event that means we've timed out...
- // We will interrupt the process here. Depending on what we were asked
- // to do we will
- // either exit, or try with all threads running for the same timeout.
+ // If we didn't get an event that means we've timed out... We will
+ // interrupt the process here. Depending on what we were asked to do
+ // we will either exit, or try with all threads running for the same
+ // timeout.
if (log) {
if (options.GetTryAllThreads()) {
@@ -5357,14 +5286,13 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
}
// It is possible that between the time we issued the Halt, and we get
- // around to calling Halt the target
- // could have stopped. That's fine, Halt will figure that out and send
- // the appropriate Stopped event.
+ // around to calling Halt the target could have stopped. That's fine,
+ // Halt will figure that out and send the appropriate Stopped event.
// BUT it is also possible that we stopped & restarted (e.g. hit a
// signal with "stop" set to false.) In
// that case, we'll get the stopped & restarted event, and we should go
- // back to waiting for the Halt's
- // stopped event. That's what this while loop does.
+ // back to waiting for the Halt's stopped event. That's what this
+ // while loop does.
bool back_to_top = true;
uint32_t try_halt_again = 0;
@@ -5413,8 +5341,8 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
}
// Between the time we initiated the Halt and the time we
- // delivered it, the process could have
- // already finished its job. Check that here:
+ // delivered it, the process could have already finished its
+ // job. Check that here:
const bool handle_interrupts = false;
if (auto result = HandleStoppedEvent(
*thread, thread_plan_sp, thread_plan_restorer, event_sp,
@@ -5477,8 +5405,8 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
}
} // END WAIT LOOP
- // If we had to start up a temporary private state thread to run this thread
- // plan, shut it down now.
+ // If we had to start up a temporary private state thread to run this
+ // thread plan, shut it down now.
if (backup_private_state_thread.IsJoinable()) {
StopPrivateStateThread();
Status error;
@@ -5498,11 +5426,9 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
log->PutString(s.GetString());
}
// Restore the thread state if we are going to discard the plan execution.
- // There are three cases where this
- // could happen:
- // 1) The execution successfully completed
- // 2) We hit a breakpoint, and ignore_breakpoints was true
- // 3) We got some other error, and discard_on_error was true
+ // There are three cases where this could happen: 1) The execution
+ // successfully completed 2) We hit a breakpoint, and ignore_breakpoints
+ // was true 3) We got some other error, and discard_on_error was true
bool should_unwind = (return_value == eExpressionInterrupted &&
options.DoesUnwindOnError()) ||
(return_value == eExpressionHitBreakpoint &&
@@ -5642,18 +5568,15 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
}
// Thread we ran the function in may have gone away because we ran the
- // target
- // Check that it's still there, and if it is put it back in the context.
- // Also restore the
- // frame in the context if it is still present.
+ // target Check that it's still there, and if it is put it back in the
+ // context. Also restore the frame in the context if it is still present.
thread = GetThreadList().FindThreadByIndexID(thread_idx_id, true).get();
if (thread) {
exe_ctx.SetFrameSP(thread->GetFrameWithStackID(ctx_frame_id));
}
// Also restore the current process'es selected frame & thread, since this
- // function calling may
- // be done behind the user's back.
+ // function calling may be done behind the user's back.
if (selected_tid != LLDB_INVALID_THREAD_ID) {
if (GetThreadList().SetSelectedThreadByIndexID(selected_tid) &&
@@ -5744,10 +5667,9 @@ size_t Process::GetThreadStatus(Stream &strm,
size_t num_thread_infos_dumped = 0;
// You can't hold the thread list lock while calling Thread::GetStatus. That
- // very well might run code (e.g. if we need it
- // to get return values or arguments.) For that to work the process has to be
- // able to acquire it. So instead copy the thread
- // ID's, and look them up one by one:
+ // very well might run code (e.g. if we need it to get return values or
+ // arguments.) For that to work the process has to be able to acquire it.
+ // So instead copy the thread ID's, and look them up one by one:
uint32_t num_threads;
std::vector<lldb::tid_t> thread_id_array;
@@ -5860,12 +5782,12 @@ void Process::DidExec() {
DoDidExec();
CompleteAttach();
// Flush the process (threads and all stack frames) after running
- // CompleteAttach()
- // in case the dynamic loader loaded things in new locations.
+ // CompleteAttach() in case the dynamic loader loaded things in new
+ // locations.
Flush();
- // After we figure out what was loaded/unloaded in CompleteAttach,
- // we need to let the target know so it can do any cleanup it needs to.
+ // After we figure out what was loaded/unloaded in CompleteAttach, we need to
+ // let the target know so it can do any cleanup it needs to.
target.DidExec();
}
@@ -5916,17 +5838,17 @@ void Process::ModulesDidLoad(ModuleList &module_list) {
runtime->ModulesDidLoad(module_list);
}
- // Let any language runtimes we have already created know
- // about the modules that loaded.
+ // Let any language runtimes we have already created know about the modules
+ // that loaded.
- // Iterate over a copy of this language runtime list in case
- // the language runtime ModulesDidLoad somehow causes the language
- // riuntime to be unloaded.
+ // Iterate over a copy of this language runtime list in case the language
+ // runtime ModulesDidLoad somehow causes the language riuntime to be
+ // unloaded.
LanguageRuntimeCollection language_runtimes(m_language_runtimes);
for (const auto &pair : language_runtimes) {
- // We must check language_runtime_sp to make sure it is not
- // nullptr as we might cache the fact that we didn't have a
- // language runtime for a language.
+ // We must check language_runtime_sp to make sure it is not nullptr as we
+ // might cache the fact that we didn't have a language runtime for a
+ // language.
LanguageRuntimeSP language_runtime_sp = pair.second;
if (language_runtime_sp)
language_runtime_sp->ModulesDidLoad(module_list);
@@ -6126,9 +6048,9 @@ Process::GetMemoryRegions(std::vector<lldb::MemoryRegionInfoSP> &region_list) {
Status
Process::ConfigureStructuredData(const ConstString &type_name,
const StructuredData::ObjectSP &config_sp) {
- // If you get this, the Process-derived class needs to implement a method
- // to enable an already-reported asynchronous structured data feature.
- // See ProcessGDBRemote for an example implementation over gdb-remote.
+ // If you get this, the Process-derived class needs to implement a method to
+ // enable an already-reported asynchronous structured data feature. See
+ // ProcessGDBRemote for an example implementation over gdb-remote.
return Status("unimplemented");
}
@@ -6170,23 +6092,27 @@ void Process::MapSupportedStructuredDataPlugins(
return true;
});
- // For each StructuredDataPlugin, if the plugin handles any of the
- // types in the supported_type_names, map that type name to that plugin.
- uint32_t plugin_index = 0;
- for (auto create_instance =
+ // For each StructuredDataPlugin, if the plugin handles any of the types in
+ // the supported_type_names, map that type name to that plugin. Stop when
+ // we've consumed all the type names.
+ // FIXME: should we return an error if there are type names nobody
+ // supports?
+ for (uint32_t plugin_index = 0; !const_type_names.empty(); plugin_index++) {
+ auto create_instance =
PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(
plugin_index);
- create_instance && !const_type_names.empty(); ++plugin_index) {
+ if (!create_instance)
+ break;
+
// Create the plugin.
StructuredDataPluginSP plugin_sp = (*create_instance)(*this);
if (!plugin_sp) {
- // This plugin doesn't think it can work with the process.
- // Move on to the next.
+ // This plugin doesn't think it can work with the process. Move on to the
+ // next.
continue;
}
- // For any of the remaining type names, map any that this plugin
- // supports.
+ // For any of the remaining type names, map any that this plugin supports.
std::vector<ConstString> names_to_remove;
for (auto &type_name : const_type_names) {
if (plugin_sp->SupportsStructuredDataType(type_name)) {
@@ -6213,8 +6139,8 @@ bool Process::RouteAsyncStructuredData(
if (!object_sp)
return false;
- // The contract is this must be a dictionary, so we can look up the
- // routing key via the top-level 'type' string value within the dictionary.
+ // The contract is this must be a dictionary, so we can look up the routing
+ // key via the top-level 'type' string value within the dictionary.
StructuredData::Dictionary *dictionary = object_sp->GetAsDictionary();
if (!dictionary)
return false;
@@ -6241,3 +6167,13 @@ Status Process::UpdateAutomaticSignalFiltering() {
// No automatic signal filtering to speak of.
return Status();
}
+
+UtilityFunction *Process::GetLoadImageUtilityFunction(
+ Platform *platform,
+ llvm::function_ref<std::unique_ptr<UtilityFunction>()> factory) {
+ if (platform != GetTarget().GetPlatform().get())
+ return nullptr;
+ std::call_once(m_dlopen_utility_func_flag_once,
+ [&] { m_dlopen_utility_func_up = factory(); });
+ return m_dlopen_utility_func_up.get();
+}
diff --git a/source/Target/ProcessInfo.cpp b/source/Target/ProcessInfo.cpp
index 0d986bc76914..ac0350686706 100644
--- a/source/Target/ProcessInfo.cpp
+++ b/source/Target/ProcessInfo.cpp
@@ -35,7 +35,7 @@ ProcessInfo::ProcessInfo(const char *name, const ArchSpec &arch,
void ProcessInfo::Clear() {
m_executable.Clear();
m_arguments.Clear();
- m_environment.Clear();
+ m_environment.clear();
m_uid = UINT32_MAX;
m_gid = UINT32_MAX;
m_arch.Clear();
@@ -59,8 +59,7 @@ void ProcessInfo::Dump(Stream &s, Platform *platform) const {
s << "Arguments:\n";
m_arguments.Dump(s);
- s << "Environment:\n";
- m_environment.Dump(s, "env");
+ s.Format("Environment:\n{0}", m_environment);
}
void ProcessInfo::SetExecutableFile(const FileSpec &exe_file,
@@ -94,11 +93,11 @@ void ProcessInfo::SetArguments(char const **argv,
if (first_arg_is_executable) {
const char *first_arg = m_arguments.GetArgumentAtIndex(0);
if (first_arg) {
- // Yes the first argument is an executable, set it as the executable
- // in the launch options. Don't resolve the file path as the path
- // could be a remote platform path
+ // Yes the first argument is an executable, set it as the executable in
+ // the launch options. Don't resolve the file path as the path could be a
+ // remote platform path
const bool resolve = false;
- m_executable.SetFile(first_arg, resolve);
+ m_executable.SetFile(first_arg, resolve, FileSpec::Style::native);
}
}
}
@@ -111,11 +110,11 @@ void ProcessInfo::SetArguments(const Args &args, bool first_arg_is_executable) {
if (first_arg_is_executable) {
const char *first_arg = m_arguments.GetArgumentAtIndex(0);
if (first_arg) {
- // Yes the first argument is an executable, set it as the executable
- // in the launch options. Don't resolve the file path as the path
- // could be a remote platform path
+ // Yes the first argument is an executable, set it as the executable in
+ // the launch options. Don't resolve the file path as the path could be a
+ // remote platform path
const bool resolve = false;
- m_executable.SetFile(first_arg, resolve);
+ m_executable.SetFile(first_arg, resolve, FileSpec::Style::native);
}
}
}
diff --git a/source/Target/ProcessLaunchInfo.cpp b/source/Target/ProcessLaunchInfo.cpp
index 284df9fd8b58..9569750bc5fd 100644
--- a/source/Target/ProcessLaunchInfo.cpp
+++ b/source/Target/ProcessLaunchInfo.cpp
@@ -189,6 +189,13 @@ void ProcessLaunchInfo::SetMonitorProcessCallback(
m_monitor_signals = monitor_signals;
}
+bool ProcessLaunchInfo::NoOpMonitorCallback(lldb::pid_t pid, bool exited, int signal, int status) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS);
+ LLDB_LOG(log, "pid = {0}, exited = {1}, signal = {2}, status = {3}", pid,
+ exited, signal, status);
+ return true;
+}
+
bool ProcessLaunchInfo::MonitorProcess() const {
if (m_monitor_callback && ProcessIDIsValid()) {
Host::StartMonitoringChildProcess(m_monitor_callback, GetProcessID(),
@@ -210,8 +217,7 @@ void ProcessLaunchInfo::FinalizeFileActions(Target *target,
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
// If nothing for stdin or stdout or stderr was specified, then check the
- // process for any default
- // settings that were set with "settings set"
+ // process for any default settings that were set with "settings set"
if (GetFileActionForFD(STDIN_FILENO) == nullptr ||
GetFileActionForFD(STDOUT_FILENO) == nullptr ||
GetFileActionForFD(STDERR_FILENO) == nullptr) {
@@ -221,8 +227,8 @@ void ProcessLaunchInfo::FinalizeFileActions(Target *target,
__FUNCTION__);
if (m_flags.Test(eLaunchFlagLaunchInTTY)) {
- // Do nothing, if we are launching in a remote terminal
- // no file actions should be done at all.
+ // Do nothing, if we are launching in a remote terminal no file actions
+ // should be done at all.
return;
}
@@ -235,16 +241,15 @@ void ProcessLaunchInfo::FinalizeFileActions(Target *target,
AppendSuppressFileAction(STDOUT_FILENO, false, true);
AppendSuppressFileAction(STDERR_FILENO, false, true);
} else {
- // Check for any values that might have gotten set with any of:
- // (lldb) settings set target.input-path
- // (lldb) settings set target.output-path
+ // Check for any values that might have gotten set with any of: (lldb)
+ // settings set target.input-path (lldb) settings set target.output-path
// (lldb) settings set target.error-path
FileSpec in_file_spec;
FileSpec out_file_spec;
FileSpec err_file_spec;
if (target) {
- // Only override with the target settings if we don't already have
- // an action for in, out or error
+ // Only override with the target settings if we don't already have an
+ // action for in, out or error
if (GetFileActionForFD(STDIN_FILENO) == nullptr)
in_file_spec = target->GetStandardInputPath();
if (GetFileActionForFD(STDOUT_FILENO) == nullptr)
@@ -295,9 +300,9 @@ void ProcessLaunchInfo::FinalizeFileActions(Target *target,
int open_flags = O_RDWR | O_NOCTTY;
#if !defined(_WIN32)
- // We really shouldn't be specifying platform specific flags
- // that are intended for a system call in generic code. But
- // this will have to do for now.
+ // We really shouldn't be specifying platform specific flags that are
+ // intended for a system call in generic code. But this will have to
+ // do for now.
open_flags |= O_CLOEXEC;
#endif
if (m_pty->OpenFirstAvailableMaster(open_flags, nullptr, 0)) {
@@ -351,14 +356,13 @@ bool ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell(
StreamString shell_command;
if (will_debug) {
- // Add a modified PATH environment variable in case argv[0]
- // is a relative path.
+ // Add a modified PATH environment variable in case argv[0] is a
+ // relative path.
const char *argv0 = argv[0];
FileSpec arg_spec(argv0, false);
if (arg_spec.IsRelative()) {
- // We have a relative path to our executable which may not work if
- // we just try to run "a.out" (without it being converted to
- // "./a.out")
+ // We have a relative path to our executable which may not work if we
+ // just try to run "a.out" (without it being converted to "./a.out")
FileSpec working_dir = GetWorkingDirectory();
// Be sure to put quotes around PATH's value in case any paths have
// spaces...
@@ -410,8 +414,8 @@ bool ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell(
}
if (first_arg_is_full_shell_command) {
- // There should only be one argument that is the shell command itself to
- // be used as is
+ // There should only be one argument that is the shell command itself
+ // to be used as is
if (argv[0] && !argv[1])
shell_command.Printf("%s", argv[0]);
else
diff --git a/source/Target/RegisterContext.cpp b/source/Target/RegisterContext.cpp
index 28beb7bcb5e8..eaec03d9b595 100644
--- a/source/Target/RegisterContext.cpp
+++ b/source/Target/RegisterContext.cpp
@@ -76,8 +76,7 @@ RegisterContext::UpdateDynamicRegisterSize(const lldb_private::ArchSpec &arch,
ExecutionContext exe_ctx(CalculateThread());
// In MIPS, the floating point registers size is depends on FR bit of SR
- // register.
- // if SR.FR == 1 then all floating point registers are 64 bits.
+ // register. if SR.FR == 1 then all floating point registers are 64 bits.
// else they are all 32 bits.
int expr_result;
@@ -136,7 +135,7 @@ uint64_t RegisterContext::GetPC(uint64_t fail_value) {
if (target_sp) {
Target *target = target_sp.get();
if (target)
- pc = target->GetOpcodeLoadAddress(pc, eAddressClassCode);
+ pc = target->GetOpcodeLoadAddress(pc, AddressClass::eCode);
}
}
@@ -262,8 +261,7 @@ bool RegisterContext::CopyFromRegisterContext(lldb::RegisterContextSP context) {
RegisterValue reg_value;
// If we can reconstruct the register from the frame we are copying from,
- // then do so, otherwise
- // use the value from frame 0.
+ // then do so, otherwise use the value from frame 0.
if (context->ReadRegister(reg_info, reg_value)) {
WriteRegister(reg_info, reg_value);
} else if (frame_zero_context->ReadRegister(reg_info, reg_value)) {
@@ -355,12 +353,11 @@ Status RegisterContext::ReadRegisterValueFromMemory(
return error;
}
- // We now have a memory buffer that contains the part or all of the register
- // value. Set the register value using this memory data.
+ // We now have a memory buffer that contains the part or all of the
+ // register value. Set the register value using this memory data.
// TODO: we might need to add a parameter to this function in case the byte
// order of the memory data doesn't match the process. For now we are
- // assuming
- // they are the same.
+ // assuming they are the same.
reg_value.SetFromMemoryData(reg_info, src, src_len,
process_sp->GetByteOrder(), error);
} else
@@ -381,8 +378,7 @@ Status RegisterContext::WriteRegisterValueToMemory(
// TODO: we might need to add a parameter to this function in case the byte
// order of the memory data doesn't match the process. For now we are
- // assuming
- // they are the same.
+ // assuming they are the same.
const uint32_t bytes_copied = reg_value.GetAsMemoryData(
reg_info, dst, dst_len, process_sp->GetByteOrder(), error);
@@ -431,9 +427,9 @@ ThreadSP RegisterContext::CalculateThread() {
}
StackFrameSP RegisterContext::CalculateStackFrame() {
- // Register contexts might belong to many frames if we have inlined
- // functions inside a frame since all inlined functions share the
- // same registers, so we can't definitively say which frame we come from...
+ // Register contexts might belong to many frames if we have inlined functions
+ // inside a frame since all inlined functions share the same registers, so we
+ // can't definitively say which frame we come from...
return StackFrameSP();
}
diff --git a/source/Target/SectionLoadHistory.cpp b/source/Target/SectionLoadHistory.cpp
index 740f48bc829c..5844da5d41e9 100644
--- a/source/Target/SectionLoadHistory.cpp
+++ b/source/Target/SectionLoadHistory.cpp
@@ -43,13 +43,12 @@ SectionLoadHistory::GetSectionLoadListForStopID(uint32_t stop_id,
if (!m_stop_id_to_section_load_list.empty()) {
if (read_only) {
// The section load list is for reading data only so we don't need to
- // create
- // a new SectionLoadList for the current stop ID, just return the section
- // load list for the stop ID that is equal to or less than the current
- // stop ID
+ // create a new SectionLoadList for the current stop ID, just return the
+ // section load list for the stop ID that is equal to or less than the
+ // current stop ID
if (stop_id == eStopIDNow) {
- // If we are asking for the latest and greatest value, it is always
- // at the end of our list because that will be the highest stop ID.
+ // If we are asking for the latest and greatest value, it is always at
+ // the end of our list because that will be the highest stop ID.
StopIDToSectionLoadList::reverse_iterator rpos =
m_stop_id_to_section_load_list.rbegin();
return rpos->second.get();
@@ -70,10 +69,8 @@ SectionLoadHistory::GetSectionLoadListForStopID(uint32_t stop_id,
assert(stop_id != eStopIDNow);
// We are updating the section load list (not read only), so if the stop
- // ID
- // passed in isn't the same as the last stop ID in our collection, then
- // create
- // a new node using the current stop ID
+ // ID passed in isn't the same as the last stop ID in our collection,
+ // then create a new node using the current stop ID
StopIDToSectionLoadList::iterator pos =
m_stop_id_to_section_load_list.lower_bound(stop_id);
if (pos != m_stop_id_to_section_load_list.end() &&
diff --git a/source/Target/SectionLoadList.cpp b/source/Target/SectionLoadList.cpp
index 31ccf17369db..6839aaccaa52 100644
--- a/source/Target/SectionLoadList.cpp
+++ b/source/Target/SectionLoadList.cpp
@@ -97,12 +97,12 @@ bool SectionLoadList::SetSectionLoadAddress(const lldb::SectionSP &section,
// we have multiple load addresses that correspond to a section, we will
// always attribute the section to the be last section that claims it
// exists at that address. Sometimes it is ok for more that one section
- // to be loaded at a specific load address, and other times it isn't.
- // The "warn_multiple" parameter tells us if we should warn in this case
- // or not. The DynamicLoader plug-in subclasses should know which
- // sections should warn and which shouldn't (darwin shared cache modules
- // all shared the same "__LINKEDIT" sections, so the dynamic loader can
- // pass false for "warn_multiple").
+ // to be loaded at a specific load address, and other times it isn't. The
+ // "warn_multiple" parameter tells us if we should warn in this case or
+ // not. The DynamicLoader plug-in subclasses should know which sections
+ // should warn and which shouldn't (darwin shared cache modules all
+ // shared the same "__LINKEDIT" sections, so the dynamic loader can pass
+ // false for "warn_multiple").
if (warn_multiple && section != ats_pos->second) {
ModuleSP module_sp(section->GetModule());
if (module_sp) {
@@ -228,8 +228,8 @@ bool SectionLoadList::ResolveLoadAddress(addr_t load_addr, Address &so_addr,
}
}
} else {
- // There are no entries that have an address that is >= load_addr,
- // so we need to check the last entry on our collection.
+ // There are no entries that have an address that is >= load_addr, so we
+ // need to check the last entry on our collection.
addr_to_sect_collection::const_reverse_iterator rpos =
m_addr_to_sect.rbegin();
if (load_addr >= rpos->first) {
diff --git a/source/Target/StackFrame.cpp b/source/Target/StackFrame.cpp
index dd44eac8e50c..2b9260f95f3f 100644
--- a/source/Target/StackFrame.cpp
+++ b/source/Target/StackFrame.cpp
@@ -60,8 +60,8 @@ StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
m_is_history_frame(is_history_frame), m_variable_list_sp(),
m_variable_list_value_objects(), m_disassembly(), m_mutex() {
// If we don't have a CFA value, use the frame index for our StackID so that
- // recursive
- // functions properly aren't confused with one another on a history stack.
+ // recursive functions properly aren't confused with one another on a history
+ // stack.
if (m_is_history_frame && !m_cfa_is_valid) {
m_id.SetCFA(m_frame_index);
}
@@ -136,17 +136,17 @@ StackFrame::~StackFrame() = default;
StackID &StackFrame::GetStackID() {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
- // Make sure we have resolved the StackID object's symbol context scope if
- // we already haven't looked it up.
+ // Make sure we have resolved the StackID object's symbol context scope if we
+ // already haven't looked it up.
if (m_flags.IsClear(RESOLVED_FRAME_ID_SYMBOL_SCOPE)) {
if (m_id.GetSymbolContextScope()) {
- // We already have a symbol context scope, we just don't have our
- // flag bit set.
+ // We already have a symbol context scope, we just don't have our flag
+ // bit set.
m_flags.Set(RESOLVED_FRAME_ID_SYMBOL_SCOPE);
} else {
- // Calculate the frame block and use this for the stack ID symbol
- // context scope if we have one.
+ // Calculate the frame block and use this for the stack ID symbol context
+ // scope if we have one.
SymbolContextScope *scope = GetFrameBlock();
if (scope == nullptr) {
// We don't have a block, so use the symbol
@@ -194,7 +194,7 @@ const Address &StackFrame::GetFrameCodeAddress() {
const bool allow_section_end = true;
if (m_frame_code_addr.SetOpcodeLoadAddress(
m_frame_code_addr.GetOffset(), target_sp.get(),
- eAddressClassCode, allow_section_end)) {
+ AddressClass::eCode, allow_section_end)) {
ModuleSP module_sp(m_frame_code_addr.GetModule());
if (module_sp) {
m_sc.module_sp = module_sp;
@@ -247,13 +247,13 @@ Block *StackFrame::GetFrameBlock() {
if (m_sc.block) {
Block *inline_block = m_sc.block->GetContainingInlinedBlock();
if (inline_block) {
- // Use the block with the inlined function info
- // as the frame block we want this frame to have only the variables
- // for the inlined function and its non-inlined block child blocks.
+ // Use the block with the inlined function info as the frame block we
+ // want this frame to have only the variables for the inlined function
+ // and its non-inlined block child blocks.
return inline_block;
} else {
- // This block is not contained within any inlined function blocks
- // with so we want to use the top most function block.
+ // This block is not contained within any inlined function blocks with so
+ // we want to use the top most function block.
return &m_sc.function->GetBlock(false);
}
}
@@ -263,8 +263,8 @@ Block *StackFrame::GetFrameBlock() {
//----------------------------------------------------------------------
// Get the symbol context if we already haven't done so by resolving the
// PC address as much as possible. This way when we pass around a
-// StackFrame object, everyone will have as much information as
-// possible and no one will ever have to look things up manually.
+// StackFrame object, everyone will have as much information as possible and no
+// one will ever have to look things up manually.
//----------------------------------------------------------------------
const SymbolContext &StackFrame::GetSymbolContext(uint32_t resolve_scope) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
@@ -279,15 +279,15 @@ const SymbolContext &StackFrame::GetSymbolContext(uint32_t resolve_scope) {
resolved |= eSymbolContextTarget;
}
- // Resolve our PC to section offset if we haven't already done so
- // and if we don't have a module. The resolved address section will
- // contain the module to which it belongs
+ // Resolve our PC to section offset if we haven't already done so and if we
+ // don't have a module. The resolved address section will contain the
+ // module to which it belongs
if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR))
GetFrameCodeAddress();
- // If this is not frame zero, then we need to subtract 1 from the PC
- // value when doing address lookups since the PC will be on the
- // instruction following the function call instruction...
+ // If this is not frame zero, then we need to subtract 1 from the PC value
+ // when doing address lookups since the PC will be on the instruction
+ // following the function call instruction...
Address lookup_addr(GetFrameCodeAddress());
if (m_frame_index > 0 && lookup_addr.IsValid()) {
@@ -296,10 +296,9 @@ const SymbolContext &StackFrame::GetSymbolContext(uint32_t resolve_scope) {
lookup_addr.SetOffset(offset - 1);
} else {
- // lookup_addr is the start of a section. We need
- // do the math on the actual load address and re-compute
- // the section. We're working with a 'noreturn' function
- // at the end of a section.
+ // lookup_addr is the start of a section. We need do the math on the
+ // actual load address and re-compute the section. We're working with
+ // a 'noreturn' function at the end of a section.
ThreadSP thread_sp(GetThread());
if (thread_sp) {
TargetSP target_sp(thread_sp->CalculateTarget());
@@ -315,9 +314,9 @@ const SymbolContext &StackFrame::GetSymbolContext(uint32_t resolve_scope) {
}
if (m_sc.module_sp) {
- // We have something in our stack frame symbol context, lets check
- // if we haven't already tried to lookup one of those things. If we
- // haven't then we will do the query.
+ // We have something in our stack frame symbol context, lets check if we
+ // haven't already tried to lookup one of those things. If we haven't
+ // then we will do the query.
uint32_t actual_resolve_scope = 0;
@@ -367,17 +366,16 @@ const SymbolContext &StackFrame::GetSymbolContext(uint32_t resolve_scope) {
}
if (actual_resolve_scope) {
- // We might be resolving less information than what is already
- // in our current symbol context so resolve into a temporary
- // symbol context "sc" so we don't clear out data we have
- // already found in "m_sc"
+ // We might be resolving less information than what is already in our
+ // current symbol context so resolve into a temporary symbol context
+ // "sc" so we don't clear out data we have already found in "m_sc"
SymbolContext sc;
// Set flags that indicate what we have tried to resolve
resolved |= m_sc.module_sp->ResolveSymbolContextForAddress(
lookup_addr, actual_resolve_scope, sc);
- // Only replace what we didn't already have as we may have
- // information for an inlined function scope that won't match
- // what a standard lookup by address would match
+ // Only replace what we didn't already have as we may have information
+ // for an inlined function scope that won't match what a standard
+ // lookup by address would match
if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == nullptr)
m_sc.comp_unit = sc.comp_unit;
if ((resolved & eSymbolContextFunction) && m_sc.function == nullptr)
@@ -404,9 +402,9 @@ const SymbolContext &StackFrame::GetSymbolContext(uint32_t resolve_scope) {
// Update our internal flags so we remember what we have tried to locate so
// we don't have to keep trying when more calls to this function are made.
- // We might have dug up more information that was requested (for example
- // if we were asked to only get the block, we will have gotten the
- // compile unit, and function) so set any additional bits that we resolved
+ // We might have dug up more information that was requested (for example if
+ // we were asked to only get the block, we will have gotten the compile
+ // unit, and function) so set any additional bits that we resolved
m_flags.Set(resolve_scope | resolved);
}
@@ -546,8 +544,8 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath(
}
if (!var_sp && (options & eExpressionPathOptionsAllowDirectIVarAccess)) {
- // Check for direct ivars access which helps us with implicit
- // access to ivars with the "this->" or "self->"
+ // Check for direct ivars access which helps us with implicit access to
+ // ivars with the "this->" or "self->"
GetSymbolContext(eSymbolContextFunction | eSymbolContextBlock);
lldb::LanguageType method_language = eLanguageTypeUnknown;
bool is_instance_method = false;
@@ -622,9 +620,8 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath(
valobj_sp->GetCompilerType().GetTypeInfo(nullptr);
if ((pointer_type_flags & eTypeIsObjC) &&
(pointer_type_flags & eTypeIsPointer)) {
- // This was an objective C object pointer and
- // it was requested we skip any fragile ivars
- // so return nothing here
+ // This was an objective C object pointer and it was requested we
+ // skip any fragile ivars so return nothing here
return ValueObjectSP();
}
}
@@ -659,15 +656,14 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath(
ConstString child_name(var_expr.substr(0, var_expr.find_first_of(".-[")));
if (check_ptr_vs_member) {
- // We either have a pointer type and need to verify
- // valobj_sp is a pointer, or we have a member of a
- // class/union/struct being accessed with the . syntax
- // and need to verify we don't have a pointer.
+ // We either have a pointer type and need to verify valobj_sp is a
+ // pointer, or we have a member of a class/union/struct being accessed
+ // with the . syntax and need to verify we don't have a pointer.
const bool actual_is_ptr = valobj_sp->IsPointerType();
if (actual_is_ptr != expr_is_ptr) {
- // Incorrect use of "." with a pointer, or "->" with
- // a class/union/struct instance or reference.
+ // Incorrect use of "." with a pointer, or "->" with a
+ // class/union/struct instance or reference.
valobj_sp->GetExpressionPath(var_expr_path_strm, false);
if (actual_is_ptr)
error.SetErrorStringWithFormat(
@@ -697,10 +693,8 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath(
// No child member with name "child_name"
if (synthetically_added_instance_object) {
// We added a "this->" or "self->" to the beginning of the
- // expression
- // and this is the first pointer ivar access, so just return
- // the normal
- // error
+ // expression and this is the first pointer ivar access, so just
+ // return the normal error
error.SetErrorStringWithFormat(
"no variable or instance variable named '%s' found in "
"this frame",
@@ -735,8 +729,8 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath(
} break;
case '[': {
- // Array member access, or treating pointer as an array
- // Need at least two brackets and a number
+ // Array member access, or treating pointer as an array Need at least two
+ // brackets and a number
if (var_expr.size() <= 2) {
error.SetErrorStringWithFormat(
"invalid square bracket encountered after \"%s\" in \"%s\"",
@@ -790,11 +784,10 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath(
deref = false;
} else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() &&
deref) {
- // what we have is *arr[low]. the most similar C++ syntax is
- // to get arr[0]
- // (an operation that is equivalent to deref-ing arr)
- // and extract bit low out of it. reading array item low
- // would be done by saying arr[low], without a deref * sign
+ // what we have is *arr[low]. the most similar C++ syntax is to get
+ // arr[0] (an operation that is equivalent to deref-ing arr) and
+ // extract bit low out of it. reading array item low would be done by
+ // saying arr[low], without a deref * sign
Status error;
ValueObjectSP temp(valobj_sp->GetChildAtIndex(0, true));
if (error.Fail()) {
@@ -828,8 +821,8 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath(
return ValueObjectSP();
} else if (is_objc_pointer) {
- // dereferencing ObjC variables is not valid.. so let's try
- // and recur to synthetic children
+ // dereferencing ObjC variables is not valid.. so let's try and
+ // recur to synthetic children
ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
if (!synthetic /* no synthetic */
|| synthetic == valobj_sp) /* synthetic is the same as
@@ -874,9 +867,8 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath(
}
} else if (valobj_sp->GetCompilerType().IsArrayType(
nullptr, nullptr, &is_incomplete_array)) {
- // Pass false to dynamic_value here so we can tell the
- // difference between
- // no dynamic value and no member of this type...
+ // Pass false to dynamic_value here so we can tell the difference
+ // between no dynamic value and no member of this type...
child_valobj_sp = valobj_sp->GetChildAtIndex(child_index, true);
if (!child_valobj_sp && (is_incomplete_array || !no_synth_child))
child_valobj_sp =
@@ -976,8 +968,8 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath(
if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
// what we have is *ptr[low-high]. the most similar C++ syntax is to
// deref ptr and extract bits low thru high out of it. reading array
- // items low thru high would be done by saying ptr[low-high], without
- // a deref * sign
+ // items low thru high would be done by saying ptr[low-high], without a
+ // deref * sign
Status error;
ValueObjectSP temp(valobj_sp->Dereference(error));
if (error.Fail()) {
@@ -991,10 +983,10 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath(
valobj_sp = temp;
deref = false;
} else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() && deref) {
- // what we have is *arr[low-high]. the most similar C++ syntax is to get
- // arr[0] (an operation that is equivalent to deref-ing arr) and extract
- // bits low thru high out of it. reading array items low thru high would
- // be done by saying arr[low-high], without a deref * sign
+ // what we have is *arr[low-high]. the most similar C++ syntax is to
+ // get arr[0] (an operation that is equivalent to deref-ing arr) and
+ // extract bits low thru high out of it. reading array items low thru
+ // high would be done by saying arr[low-high], without a deref * sign
Status error;
ValueObjectSP temp(valobj_sp->GetChildAtIndex(0, true));
if (error.Fail()) {
@@ -1091,8 +1083,8 @@ bool StackFrame::GetFrameBaseValue(Scalar &frame_base, Status *error_ptr) {
if (m_sc.function->GetFrameBaseExpression().Evaluate(
&exe_ctx, nullptr, loclist_base_addr, nullptr, nullptr,
expr_value, &m_frame_base_error) == false) {
- // We should really have an error if evaluate returns, but in case
- // we don't, lets set the error to something at least.
+ // We should really have an error if evaluate returns, but in case we
+ // don't, lets set the error to something at least.
if (m_frame_base_error.Success())
m_frame_base_error.SetErrorString(
"Evaluation of the frame base expression failed.");
@@ -1420,8 +1412,8 @@ ValueObjectSP GetValueForDereferincingOffset(StackFrame &frame,
ValueObjectSP &base,
int64_t offset) {
// base is a pointer to something
- // offset is the thing to add to the pointer
- // We return the most sensible ValueObject for the result of *(base+offset)
+ // offset is the thing to add to the pointer We return the most sensible
+ // ValueObject for the result of *(base+offset)
if (!base->IsPointerOrReferenceType()) {
return ValueObjectSP();
@@ -1486,8 +1478,8 @@ lldb::ValueObjectSP DoGuessValueAt(StackFrame &frame, ConstString reg,
//
// f, a pointer to a struct, is known to be at -0x8(%rbp).
//
- // DoGuessValueAt(frame, rdi, 4, dis, vars, 0x22) finds the instruction at +18
- // that assigns to rdi, and calls itself recursively for that dereference
+ // DoGuessValueAt(frame, rdi, 4, dis, vars, 0x22) finds the instruction at
+ // +18 that assigns to rdi, and calls itself recursively for that dereference
// DoGuessValueAt(frame, rdi, 8, dis, vars, 0x18) finds the instruction at
// +14 that assigns to rdi, and calls itself recursively for that
// derefernece
@@ -1533,9 +1525,9 @@ lldb::ValueObjectSP DoGuessValueAt(StackFrame &frame, ConstString reg,
for (uint32_t ii = current_inst - 1; ii != (uint32_t)-1; --ii) {
// This is not an exact algorithm, and it sacrifices accuracy for
- // generality. Recognizing "mov" and "ld" instructions –– and which are
- // their source and destination operands -- is something the disassembler
- // should do for us.
+ // generality. Recognizing "mov" and "ld" instructions –– and which
+ // are their source and destination operands -- is something the
+ // disassembler should do for us.
InstructionSP instruction_sp =
disassembler.GetInstructionList().GetInstructionAtIndex(ii);
diff --git a/source/Target/StackFrameList.cpp b/source/Target/StackFrameList.cpp
index be7fa8001212..2380a91df41d 100644
--- a/source/Target/StackFrameList.cpp
+++ b/source/Target/StackFrameList.cpp
@@ -51,8 +51,8 @@ StackFrameList::StackFrameList(Thread &thread,
}
StackFrameList::~StackFrameList() {
- // Call clear since this takes a lock and clears the stack frame list
- // in case another thread is currently using this stack frame list
+ // Call clear since this takes a lock and clears the stack frame list in case
+ // another thread is currently using this stack frame list
Clear();
}
@@ -95,13 +95,12 @@ void StackFrameList::ResetCurrentInlinedDepth() {
log->Printf(
"ResetCurrentInlinedDepth: Invalidating current inlined depth.\n");
} else {
- // We only need to do something special about inlined blocks when we
- // are at the beginning of an inlined function:
+ // We only need to do something special about inlined blocks when we are
+ // at the beginning of an inlined function:
// FIXME: We probably also have to do something special if the PC is at
// the END
// of an inlined function, which coincides with the end of either its
- // containing
- // function or another inlined function.
+ // containing function or another inlined function.
lldb::addr_t curr_pc = m_thread.GetRegisterContext()->GetPC();
Block *block_ptr = m_frames[0]->GetFrameBlock();
@@ -114,19 +113,15 @@ void StackFrameList::ResetCurrentInlinedDepth() {
containing_range)) {
if (pc_as_address == containing_range.GetBaseAddress()) {
// If we got here because of a breakpoint hit, then set the inlined
- // depth depending on where
- // the breakpoint was set.
- // If we got here because of a crash, then set the inlined depth to
- // the deepest most block.
- // Otherwise, we stopped here naturally as the result of a step, so
- // set ourselves in the
- // containing frame of the whole set of nested inlines, so the user
- // can then "virtually"
- // step into the frames one by one, or next over the whole mess.
- // Note: We don't have to handle being somewhere in the middle of
- // the stack here, since
- // ResetCurrentInlinedDepth doesn't get called if there is a valid
- // inlined depth set.
+ // depth depending on where the breakpoint was set. If we got here
+ // because of a crash, then set the inlined depth to the deepest
+ // most block. Otherwise, we stopped here naturally as the result
+ // of a step, so set ourselves in the containing frame of the whole
+ // set of nested inlines, so the user can then "virtually" step
+ // into the frames one by one, or next over the whole mess. Note:
+ // We don't have to handle being somewhere in the middle of the
+ // stack here, since ResetCurrentInlinedDepth doesn't get called if
+ // there is a valid inlined depth set.
StopInfoSP stop_info_sp = m_thread.GetStopInfo();
if (stop_info_sp) {
switch (stop_info_sp->GetStopReason()) {
@@ -134,7 +129,8 @@ void StackFrameList::ResetCurrentInlinedDepth() {
case eStopReasonException:
case eStopReasonExec:
case eStopReasonSignal:
- // In all these cases we want to stop in the deepest most frame.
+ // In all these cases we want to stop in the deepest most
+ // frame.
m_current_inlined_pc = curr_pc;
m_current_inlined_depth = 0;
break;
@@ -142,17 +138,14 @@ void StackFrameList::ResetCurrentInlinedDepth() {
// FIXME: Figure out what this break point is doing, and set the
// inline depth
// appropriately. Be careful to take into account breakpoints
- // that implement
- // step over prologue, since that should do the default
- // calculation.
- // For now, if the breakpoints corresponding to this hit are all
- // internal,
+ // that implement step over prologue, since that should do the
+ // default calculation. For now, if the breakpoints
+ // corresponding to this hit are all internal,
// I set the stop location to the top of the inlined stack,
// since that will make
- // things like stepping over prologues work right. But if there
- // are any non-internal
- // breakpoints I do to the bottom of the stack, since that was
- // the old behavior.
+ // things like stepping over prologues work right. But if
+ // there are any non-internal breakpoints I do to the bottom of
+ // the stack, since that was the old behavior.
uint32_t bp_site_id = stop_info_sp->GetValue();
BreakpointSiteSP bp_site_sp(
m_thread.GetProcess()->GetBreakpointSiteList().FindByID(
@@ -177,10 +170,9 @@ void StackFrameList::ResetCurrentInlinedDepth() {
LLVM_FALLTHROUGH;
default: {
// Otherwise, we should set ourselves at the container of the
- // inlining, so that the
- // user can descend into them.
- // So first we check whether we have more than one inlined block
- // sharing this PC:
+ // inlining, so that the user can descend into them. So first
+ // we check whether we have more than one inlined block sharing
+ // this PC:
int num_inlined_functions = 0;
for (Block *container_ptr = block_ptr->GetInlinedParent();
@@ -250,13 +242,11 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) {
#if defined(DEBUG_STACK_FRAMES)
StreamFile s(stdout, false);
#endif
- // If we are hiding some frames from the outside world, we need to add those
- // onto the total count of
- // frames to fetch. However, we don't need to do that if end_idx is 0 since
- // in that case we always
- // get the first concrete frame and all the inlined frames below it... And
- // of course, if end_idx is
- // UINT32_MAX that means get all, so just do that...
+ // If we are hiding some frames from the outside world, we need to add
+ // those onto the total count of frames to fetch. However, we don't need
+ // to do that if end_idx is 0 since in that case we always get the first
+ // concrete frame and all the inlined frames below it... And of course, if
+ // end_idx is UINT32_MAX that means get all, so just do that...
uint32_t inlined_depth = 0;
if (end_idx > 0 && end_idx != UINT32_MAX) {
@@ -273,17 +263,17 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) {
lldb::addr_t pc = LLDB_INVALID_ADDRESS;
lldb::addr_t cfa = LLDB_INVALID_ADDRESS;
if (idx == 0) {
- // We might have already created frame zero, only create it
- // if we need to
+ // We might have already created frame zero, only create it if we need
+ // to
if (m_frames.empty()) {
RegisterContextSP reg_ctx_sp(m_thread.GetRegisterContext());
if (reg_ctx_sp) {
const bool success =
unwinder && unwinder->GetFrameInfoAtIndex(idx, cfa, pc);
- // There shouldn't be any way not to get the frame info for frame 0.
- // But if the unwinder can't make one, lets make one by hand with
- // the
+ // There shouldn't be any way not to get the frame info for frame
+ // 0. But if the unwinder can't make one, lets make one by hand
+ // with the
// SP as the CFA and see if that gets any further.
if (!success) {
cfa = reg_ctx_sp->GetSP();
@@ -323,22 +313,20 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) {
if (unwind_block) {
Address curr_frame_address(unwind_frame_sp->GetFrameCodeAddress());
TargetSP target_sp = m_thread.CalculateTarget();
- // Be sure to adjust the frame address to match the address
- // that was used to lookup the symbol context above. If we are
- // in the first concrete frame, then we lookup using the current
- // address, else we decrement the address by one to get the correct
- // location.
+ // Be sure to adjust the frame address to match the address that was
+ // used to lookup the symbol context above. If we are in the first
+ // concrete frame, then we lookup using the current address, else we
+ // decrement the address by one to get the correct location.
if (idx > 0) {
if (curr_frame_address.GetOffset() == 0) {
// If curr_frame_address points to the first address in a section
- // then after
- // adjustment it will point to an other section. In that case
- // resolve the
- // address again to the correct section plus offset form.
+ // then after adjustment it will point to an other section. In that
+ // case resolve the address again to the correct section plus
+ // offset form.
addr_t load_addr = curr_frame_address.GetOpcodeLoadAddress(
- target_sp.get(), eAddressClassCode);
+ target_sp.get(), AddressClass::eCode);
curr_frame_address.SetOpcodeLoadAddress(
- load_addr - 1, target_sp.get(), eAddressClassCode);
+ load_addr - 1, target_sp.get(), AddressClass::eCode);
} else {
curr_frame_address.Slide(-1);
}
@@ -414,8 +402,8 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) {
break;
prev_frame->UpdatePreviousFrameFromCurrentFrame(*curr_frame);
- // Now copy the fixed up previous frame into the current frames
- // so the pointer doesn't change
+ // Now copy the fixed up previous frame into the current frames so the
+ // pointer doesn't change
m_frames[curr_frame_idx] = prev_frame_sp;
// curr_frame->UpdateCurrentFrameFromPreviousFrame (*prev_frame);
@@ -495,9 +483,8 @@ StackFrameSP StackFrameList::GetFrameAtIndex(uint32_t idx) {
if (frame_sp)
return frame_sp;
- // GetFramesUpTo will fill m_frames with as many frames as you asked for,
- // if there are that many. If there weren't then you asked for too many
- // frames.
+ // GetFramesUpTo will fill m_frames with as many frames as you asked for, if
+ // there are that many. If there weren't then you asked for too many frames.
GetFramesUpTo(idx);
if (idx < m_frames.size()) {
if (m_show_inlined_frames) {
@@ -519,8 +506,8 @@ StackFrameSP StackFrameList::GetFrameAtIndex(uint32_t idx) {
Function *function =
frame_sp->GetSymbolContext(eSymbolContextFunction).function;
if (function) {
- // When we aren't showing inline functions we always use
- // the top most function block as the scope.
+ // When we aren't showing inline functions we always use the top
+ // most function block as the scope.
frame_sp->SetSymbolContextScope(&function->GetBlock(false));
} else {
// Set the symbol scope from the symbol regardless if it is nullptr
@@ -534,9 +521,8 @@ StackFrameSP StackFrameList::GetFrameAtIndex(uint32_t idx) {
}
} else if (original_idx == 0) {
// There should ALWAYS be a frame at index 0. If something went wrong with
- // the CurrentInlinedDepth such that
- // there weren't as many frames as we thought taking that into account, then
- // reset the current inlined depth
+ // the CurrentInlinedDepth such that there weren't as many frames as we
+ // thought taking that into account, then reset the current inlined depth
// and return the real zeroth frame.
if (m_frames.empty()) {
// Why do we have a thread with zero frames, that should not ever
@@ -554,11 +540,11 @@ StackFrameSP StackFrameList::GetFrameAtIndex(uint32_t idx) {
StackFrameSP
StackFrameList::GetFrameWithConcreteFrameIndex(uint32_t unwind_idx) {
// First try assuming the unwind index is the same as the frame index. The
- // unwind index is always greater than or equal to the frame index, so it
- // is a good place to start. If we have inlined frames we might have 5
- // concrete frames (frame unwind indexes go from 0-4), but we might have 15
- // frames after we make all the inlined frames. Most of the time the unwind
- // frame index (or the concrete frame index) is the same as the frame index.
+ // unwind index is always greater than or equal to the frame index, so it is
+ // a good place to start. If we have inlined frames we might have 5 concrete
+ // frames (frame unwind indexes go from 0-4), but we might have 15 frames
+ // after we make all the inlined frames. Most of the time the unwind frame
+ // index (or the concrete frame index) is the same as the frame index.
uint32_t frame_idx = unwind_idx;
StackFrameSP frame_sp(GetFrameAtIndex(frame_idx));
while (frame_sp) {
@@ -719,9 +705,9 @@ void StackFrameList::Merge(std::unique_ptr<StackFrameList> &curr_ap,
#if defined(DEBUG_STACK_FRAMES)
s.PutCString("No previous frames, so use current frames...\n");
#endif
- // We either don't have any previous frames, or since we have more than
- // one current frames it means we have all the frames and can safely
- // replace our previous frames.
+ // We either don't have any previous frames, or since we have more than one
+ // current frames it means we have all the frames and can safely replace
+ // our previous frames.
prev_sp.reset(curr_ap.release());
return;
}
@@ -733,8 +719,8 @@ void StackFrameList::Merge(std::unique_ptr<StackFrameList> &curr_ap,
s.PutCString(
"We have more than one current frame, so use current frames...\n");
#endif
- // We have more than one current frames it means we have all the frames
- // and can safely replace our previous frames.
+ // We have more than one current frames it means we have all the frames and
+ // can safely replace our previous frames.
prev_sp.reset(curr_ap.release());
#if defined(DEBUG_STACK_FRAMES)
diff --git a/source/Target/StackID.cpp b/source/Target/StackID.cpp
index 889cf89b9be7..341c902af995 100644
--- a/source/Target/StackID.cpp
+++ b/source/Target/StackID.cpp
@@ -69,12 +69,11 @@ bool lldb_private::operator<(const StackID &lhs, const StackID &rhs) {
// FIXME: We are assuming that the stacks grow downward in memory. That's not
// necessary, but true on
// all the machines we care about at present. If this changes, we'll have to
- // deal with that. The ABI is the
- // agent who knows this ordering, but the StackID has no access to the ABI.
- // The most straightforward way
- // to handle this is to add a "m_grows_downward" bool to the StackID, and set
- // it in the constructor.
- // But I'm not going to waste a bool per StackID on this till we need it.
+ // deal with that. The ABI is the agent who knows this ordering, but the
+ // StackID has no access to the ABI. The most straightforward way to handle
+ // this is to add a "m_grows_downward" bool to the StackID, and set it in the
+ // constructor. But I'm not going to waste a bool per StackID on this till we
+ // need it.
if (lhs_cfa != rhs_cfa)
return lhs_cfa < rhs_cfa;
diff --git a/source/Target/StopInfo.cpp b/source/Target/StopInfo.cpp
index 652ad8a05445..f8b17dc10eca 100644
--- a/source/Target/StopInfo.cpp
+++ b/source/Target/StopInfo.cpp
@@ -63,12 +63,10 @@ bool StopInfo::HasTargetRunSinceMe() {
return true;
} else if (ret_type == eStateStopped) {
// This is a little tricky. We want to count "run and stopped again
- // before you could
- // ask this question as a "TRUE" answer to HasTargetRunSinceMe. But we
- // don't want to
- // include any running of the target done for expressions. So we track
- // both resumes,
- // and resumes caused by expressions, and check if there are any resumes
+ // before you could ask this question as a "TRUE" answer to
+ // HasTargetRunSinceMe. But we don't want to include any running of the
+ // target done for expressions. So we track both resumes, and resumes
+ // caused by expressions, and check if there are any resumes
// NOT caused
// by expressions.
@@ -199,8 +197,7 @@ public:
if (bp_site_sp) {
StreamString strm;
// If we have just hit an internal breakpoint, and it has a kind
- // description, print that instead of the
- // full breakpoint printing:
+ // description, print that instead of the full breakpoint printing:
if (bp_site_sp->IsInternal()) {
size_t num_owners = bp_site_sp->GetNumberOfOwners();
for (size_t idx = 0; idx < num_owners; idx++) {
@@ -258,9 +255,9 @@ public:
protected:
bool ShouldStop(Event *event_ptr) override {
- // This just reports the work done by PerformAction or the synchronous stop.
- // It should
- // only ever get called after they have had a chance to run.
+ // This just reports the work done by PerformAction or the synchronous
+ // stop. It should only ever get called after they have had a chance to
+ // run.
assert(m_should_stop_is_valid);
return m_should_stop;
}
@@ -293,54 +290,47 @@ protected:
if (bp_site_sp) {
// Let's copy the owners list out of the site and store them in a local
- // list. That way if
- // one of the breakpoint actions changes the site, then we won't be
- // operating on a bad list.
+ // list. That way if one of the breakpoint actions changes the site,
+ // then we won't be operating on a bad list.
BreakpointLocationCollection site_locations;
size_t num_owners = bp_site_sp->CopyOwnersList(site_locations);
if (num_owners == 0) {
m_should_stop = true;
} else {
- // We go through each location, and test first its precondition - this
- // overrides everything. Note,
- // we only do this once per breakpoint - not once per location...
- // Then check the condition. If the condition says to stop,
- // then we run the callback for that location. If that callback says
- // to stop as well, then
- // we set m_should_stop to true; we are going to stop.
- // But we still want to give all the breakpoints whose conditions say
- // we are going to stop a
- // chance to run their callbacks.
- // Of course if any callback restarts the target by putting "continue"
- // in the callback, then
+ // We go through each location, and test first its precondition -
+ // this overrides everything. Note, we only do this once per
+ // breakpoint - not once per location... Then check the condition.
+ // If the condition says to stop, then we run the callback for that
+ // location. If that callback says to stop as well, then we set
+ // m_should_stop to true; we are going to stop. But we still want to
+ // give all the breakpoints whose conditions say we are going to stop
+ // a chance to run their callbacks. Of course if any callback
+ // restarts the target by putting "continue" in the callback, then
// we're going to restart, without running the rest of the callbacks.
- // And in this case we will
- // end up not stopping even if another location said we should stop.
- // But that's better than not
- // running all the callbacks.
+ // And in this case we will end up not stopping even if another
+ // location said we should stop. But that's better than not running
+ // all the callbacks.
m_should_stop = false;
// We don't select threads as we go through them testing breakpoint
- // conditions and running commands.
- // So we need to set the thread for expression evaluation here:
+ // conditions and running commands. So we need to set the thread for
+ // expression evaluation here:
ThreadList::ExpressionExecutionThreadPusher thread_pusher(thread_sp);
ExecutionContext exe_ctx(thread_sp->GetStackFrameAtIndex(0));
Process *process = exe_ctx.GetProcessPtr();
if (process->GetModIDRef().IsLastResumeForUserExpression()) {
// If we are in the middle of evaluating an expression, don't run
- // asynchronous breakpoint commands or
- // expressions. That could lead to infinite recursion if the
- // command or condition re-calls the function
- // with this breakpoint.
+ // asynchronous breakpoint commands or expressions. That could
+ // lead to infinite recursion if the command or condition re-calls
+ // the function with this breakpoint.
// TODO: We can keep a list of the breakpoints we've seen while
// running expressions in the nested
// PerformAction calls that can arise when the action runs a
- // function that hits another breakpoint,
- // and only stop running commands when we see the same breakpoint
- // hit a second time.
+ // function that hits another breakpoint, and only stop running
+ // commands when we see the same breakpoint hit a second time.
m_should_stop_is_valid = true;
if (log)
@@ -377,12 +367,11 @@ protected:
StoppointCallbackContext context(event_ptr, exe_ctx, false);
// For safety's sake let's also grab an extra reference to the
- // breakpoint owners of the locations we're
- // going to examine, since the locations are going to have to get back
- // to their breakpoints, and the
- // locations don't keep their owners alive. I'm just sticking the
- // BreakpointSP's in a vector since
- // I'm only using it to locally increment their retain counts.
+ // breakpoint owners of the locations we're going to examine, since
+ // the locations are going to have to get back to their breakpoints,
+ // and the locations don't keep their owners alive. I'm just
+ // sticking the BreakpointSP's in a vector since I'm only using it to
+ // locally increment their retain counts.
std::vector<lldb::BreakpointSP> location_owners;
@@ -404,8 +393,8 @@ protected:
continue;
// The breakpoint site may have many locations associated with it,
- // not all of them valid for
- // this thread. Skip the ones that aren't:
+ // not all of them valid for this thread. Skip the ones that
+ // aren't:
if (!bp_loc_sp->ValidForThisThread(thread_sp.get())) {
if (log) {
log->Printf("Breakpoint %s hit on thread 0x%llx but it was not "
@@ -419,8 +408,7 @@ protected:
internal_breakpoint = bp_loc_sp->GetBreakpoint().IsInternal();
// First run the precondition, but since the precondition is per
- // breakpoint, only run it once
- // per breakpoint.
+ // breakpoint, only run it once per breakpoint.
std::pair<std::unordered_set<break_id_t>::iterator, bool> result =
precondition_breakpoints.insert(
bp_loc_sp->GetBreakpoint().GetID());
@@ -433,9 +421,8 @@ protected:
continue;
// Next run the condition for the breakpoint. If that says we
- // should stop, then we'll run
- // the callback for the breakpoint. If the callback says we
- // shouldn't stop that will win.
+ // should stop, then we'll run the callback for the breakpoint. If
+ // the callback says we shouldn't stop that will win.
if (bp_loc_sp->GetConditionText() != nullptr) {
Status condition_error;
@@ -470,9 +457,8 @@ protected:
}
if (!condition_says_stop) {
// We don't want to increment the hit count of breakpoints if
- // the condition fails.
- // We've already bumped it by the time we get here, so undo
- // the bump:
+ // the condition fails. We've already bumped it by the time
+ // we get here, so undo the bump:
bp_loc_sp->UndoBumpHitCount();
continue;
}
@@ -524,8 +510,8 @@ protected:
thread_sp->GetProcess()->GetTarget().RemoveBreakpointByID(
bp_loc_sp->GetBreakpoint().GetID());
}
- // Also make sure that the callback hasn't continued the target.
- // If it did, when we'll set m_should_start to false and get out of
+ // Also make sure that the callback hasn't continued the target. If
+ // it did, when we'll set m_should_start to false and get out of
// here.
if (HasTargetRunSinceMe()) {
m_should_stop = false;
@@ -551,13 +537,13 @@ protected:
if ((m_should_stop == false || internal_breakpoint)
&& thread_sp->CompletedPlanOverridesBreakpoint()) {
- // Override should_stop decision when we have
- // completed step plan additionally to the breakpoint
+ // Override should_stop decision when we have completed step plan
+ // additionally to the breakpoint
m_should_stop = true;
- // Here we clean the preset stop info so the next
- // GetStopInfo call will find the appropriate stop info,
- // which should be the stop info related to the completed plan
+ // Here we clean the preset stop info so the next GetStopInfo call will
+ // find the appropriate stop info, which should be the stop info
+ // related to the completed plan
thread_sp->ResetStopInfo();
}
@@ -652,8 +638,8 @@ public:
protected:
bool ShouldStopSynchronous(Event *event_ptr) override {
- // ShouldStop() method is idempotent and should not affect hit count.
- // See Process::RunPrivateStateThread()->Process()->HandlePrivateEvent()
+ // ShouldStop() method is idempotent and should not affect hit count. See
+ // Process::RunPrivateStateThread()->Process()->HandlePrivateEvent()
// -->Process()::ShouldBroadcastEvent()->ThreadList::ShouldStop()->
// Thread::ShouldStop()->ThreadPlanBase::ShouldStop()->
// StopInfoWatchpoint::ShouldStop() and
@@ -689,9 +675,9 @@ protected:
}
bool ShouldStop(Event *event_ptr) override {
- // This just reports the work done by PerformAction or the synchronous stop.
- // It should
- // only ever get called after they have had a chance to run.
+ // This just reports the work done by PerformAction or the synchronous
+ // stop. It should only ever get called after they have had a chance to
+ // run.
assert(m_should_stop_is_valid);
return m_should_stop;
}
@@ -699,8 +685,8 @@ protected:
void PerformAction(Event *event_ptr) override {
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS);
// We're going to calculate if we should stop or not in some way during the
- // course of
- // this code. Also by default we're going to stop, so set that here.
+ // course of this code. Also by default we're going to stop, so set that
+ // here.
m_should_stop = true;
@@ -716,10 +702,8 @@ protected:
{
// check if this process is running on an architecture where
- // watchpoints trigger
- // before the associated instruction runs. if so, disable the WP,
- // single-step and then
- // re-enable the watchpoint
+ // watchpoints trigger before the associated instruction runs. if so,
+ // disable the WP, single-step and then re-enable the watchpoint
if (process_sp) {
uint32_t num;
bool wp_triggers_after;
@@ -727,10 +711,9 @@ protected:
if (process_sp->GetWatchpointSupportInfo(num, wp_triggers_after)
.Success()) {
if (!wp_triggers_after) {
- // We need to preserve the watch_index before watchpoint
- // is disable. Since Watchpoint::SetEnabled will clear the
- // watch index.
- // This will fix TestWatchpointIter failure
+ // We need to preserve the watch_index before watchpoint is
+ // disable. Since Watchpoint::SetEnabled will clear the watch
+ // index. This will fix TestWatchpointIter failure
Watchpoint *wp = wp_sp.get();
uint32_t watch_index = wp->GetHardwareIndex();
process_sp->DisableWatchpoint(wp, false);
@@ -759,8 +742,8 @@ protected:
}
// This sentry object makes sure the current watchpoint is disabled
- // while performing watchpoint actions,
- // and it is then enabled after we are finished.
+ // while performing watchpoint actions, and it is then enabled after we
+ // are finished.
WatchpointSentry sentry(process_sp, wp_sp);
/*
@@ -789,16 +772,13 @@ protected:
// TODO: This condition should be checked in the synchronous part of the
// watchpoint code
// (Watchpoint::ShouldStop), so that we avoid pulling an event even if
- // the watchpoint fails
- // the ignore count condition. It is moved here temporarily, because for
- // archs with
- // watchpoint_exceptions_received=before, the code in the previous lines
- // takes care of moving
- // the inferior to next PC. We have to check the ignore count condition
- // after this is done,
- // otherwise we will hit same watchpoint multiple times until we pass
- // ignore condition, but we
- // won't actually be ignoring them.
+ // the watchpoint fails the ignore count condition. It is moved here
+ // temporarily, because for archs with
+ // watchpoint_exceptions_received=before, the code in the previous
+ // lines takes care of moving the inferior to next PC. We have to check
+ // the ignore count condition after this is done, otherwise we will hit
+ // same watchpoint multiple times until we pass ignore condition, but
+ // we won't actually be ignoring them.
if (wp_sp->GetHitCount() <= wp_sp->GetIgnoreCount())
m_should_stop = false;
@@ -824,9 +804,9 @@ protected:
if (result_value_sp->ResolveValue(scalar_value)) {
if (scalar_value.ULongLong(1) == 0) {
// We have been vetoed. This takes precedence over querying
- // the watchpoint whether it should stop (aka ignore count and
- // friends). See also StopInfoWatchpoint::ShouldStop() as
- // well as Process::ProcessEventData::DoOnRemoval().
+ // the watchpoint whether it should stop (aka ignore count
+ // and friends). See also StopInfoWatchpoint::ShouldStop()
+ // as well as Process::ProcessEventData::DoOnRemoval().
m_should_stop = false;
} else
m_should_stop = true;
@@ -877,9 +857,8 @@ protected:
debugger.SetAsyncExecution(old_async);
- // Also make sure that the callback hasn't continued the target.
- // If it did, when we'll set m_should_stop to false and get out of
- // here.
+ // Also make sure that the callback hasn't continued the target. If
+ // it did, when we'll set m_should_stop to false and get out of here.
if (HasTargetRunSinceMe())
m_should_stop = false;
diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp
index fdc10cf48275..3f70741713fb 100644
--- a/source/Target/Target.cpp
+++ b/source/Target/Target.cpp
@@ -87,13 +87,14 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch,
Broadcaster(debugger.GetBroadcasterManager(),
Target::GetStaticBroadcasterClass().AsCString()),
ExecutionContextScope(), m_debugger(debugger), m_platform_sp(platform_sp),
- m_mutex(), m_arch(target_arch),
- m_images(this), m_section_load_history(), m_breakpoint_list(false),
- m_internal_breakpoint_list(true), m_watchpoint_list(), m_process_sp(),
- m_search_filter_sp(), m_image_search_paths(ImageSearchPathsChanged, this),
- m_ast_importer_sp(), m_source_manager_ap(), m_stop_hooks(),
- m_stop_hook_next_id(0), m_valid(true), m_suppress_stop_hooks(false),
- m_is_dummy_target(is_dummy_target)
+ m_mutex(), m_arch(target_arch), m_images(this), m_section_load_history(),
+ m_breakpoint_list(false), m_internal_breakpoint_list(true),
+ m_watchpoint_list(), m_process_sp(), m_search_filter_sp(),
+ m_image_search_paths(ImageSearchPathsChanged, this), m_ast_importer_sp(),
+ m_source_manager_ap(), m_stop_hooks(), m_stop_hook_next_id(0),
+ m_valid(true), m_suppress_stop_hooks(false),
+ m_is_dummy_target(is_dummy_target),
+ m_stats_storage(static_cast<int>(StatisticKind::StatisticMax))
{
SetEventName(eBroadcastBitBreakpointChanged, "breakpoint-changed");
@@ -327,11 +328,7 @@ BreakpointSP Target::CreateBreakpoint(const FileSpecList *containingModules,
bool hardware,
LazyBool move_to_nearest_code) {
FileSpec remapped_file;
- ConstString remapped_path;
- if (GetSourcePathMap().ReverseRemapPath(ConstString(file.GetPath().c_str()),
- remapped_path))
- remapped_file.SetFile(remapped_path.AsCString(), true);
- else
+ if (!GetSourcePathMap().ReverseRemapPath(file, remapped_file))
remapped_file = file;
if (check_inlines == eLazyBoolCalculate) {
@@ -381,8 +378,8 @@ BreakpointSP Target::CreateBreakpoint(lldb::addr_t addr, bool internal,
// Check for any reason we want to move this breakpoint to other address.
addr = GetBreakableLoadAddress(addr);
- // Attempt to resolve our load address if possible, though it is ok if
- // it doesn't resolve to section/offset.
+ // Attempt to resolve our load address if possible, though it is ok if it
+ // doesn't resolve to section/offset.
// Try and resolve as a load address if possible
GetSectionLoadList().ResolveLoadAddress(addr, so_addr);
@@ -536,8 +533,7 @@ SearchFilterSP Target::GetSearchFilterForModuleAndCUList(
SearchFilterSP filter_sp;
if (containingModules == nullptr) {
// We could make a special "CU List only SearchFilter". Better yet was if
- // these could be composable,
- // but that will take a little reworking.
+ // these could be composable, but that will take a little reworking.
filter_sp.reset(new SearchFilterByModuleListAndCU(
shared_from_this(), FileSpecList(), *containingSourceFiles));
@@ -743,8 +739,8 @@ static bool CheckIfWatchpointsExhausted(Target *target, Status &error) {
return true;
}
-// See also Watchpoint::SetWatchpointType(uint32_t type) and
-// the OptionGroupWatchpoint::WatchType enum type.
+// See also Watchpoint::SetWatchpointType(uint32_t type) and the
+// OptionGroupWatchpoint::WatchType enum type.
WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size,
const CompilerType *type, uint32_t kind,
Status &error) {
@@ -775,8 +771,8 @@ WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size,
if (!CheckIfWatchpointsExhausted(this, error))
return wp_sp;
- // Currently we only support one watchpoint per address, with total number
- // of watchpoints limited by the hardware which the inferior is running on.
+ // Currently we only support one watchpoint per address, with total number of
+ // watchpoints limited by the hardware which the inferior is running on.
// Grab the list mutex while doing operations.
const bool notify = false; // Don't notify about all the state changes we do
@@ -813,9 +809,8 @@ WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size,
wp_sp->GetID());
if (error.Fail()) {
- // Enabling the watchpoint on the device side failed.
- // Remove the said watchpoint from the list maintained by the target
- // instance.
+ // Enabling the watchpoint on the device side failed. Remove the said
+ // watchpoint from the list maintained by the target instance.
m_watchpoint_list.Remove(wp_sp->GetID(), true);
// See if we could provide more helpful error message.
if (!OptionGroupWatchpoint::IsWatchSizeSupported(size))
@@ -1027,8 +1022,7 @@ Status Target::SerializeBreakpointsToFile(const FileSpec &file,
Breakpoint *bp = GetBreakpointByID(bp_id).get();
StructuredData::ObjectSP bkpt_save_sp = bp->SerializeToStructuredData();
// If the user explicitly asked to serialize a breakpoint, and we
- // can't, then
- // raise an error:
+ // can't, then raise an error:
if (!bkpt_save_sp) {
error.SetErrorStringWithFormat("Unable to serialize breakpoint %d",
bp_id);
@@ -1141,8 +1135,8 @@ bool Target::RemoveAllWatchpoints(bool end_to_end) {
return true; // Success!
}
-// Assumption: Caller holds the list mutex lock for m_watchpoint_list for end to
-// end operations.
+// Assumption: Caller holds the list mutex lock for m_watchpoint_list for end
+// to end operations.
bool Target::DisableAllWatchpoints(bool end_to_end) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
if (log)
@@ -1171,8 +1165,8 @@ bool Target::DisableAllWatchpoints(bool end_to_end) {
return true; // Success!
}
-// Assumption: Caller holds the list mutex lock for m_watchpoint_list for end to
-// end operations.
+// Assumption: Caller holds the list mutex lock for m_watchpoint_list for end
+// to end operations.
bool Target::EnableAllWatchpoints(bool end_to_end) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
if (log)
@@ -1235,8 +1229,8 @@ bool Target::ClearAllWatchpointHistoricValues() {
return true; // Success!
}
-// Assumption: Caller holds the list mutex lock for m_watchpoint_list
-// during these operations.
+// Assumption: Caller holds the list mutex lock for m_watchpoint_list during
+// these operations.
bool Target::IgnoreAllWatchpoints(uint32_t ignore_count) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
if (log)
@@ -1459,7 +1453,8 @@ bool Target::SetArchitecture(const ArchSpec &arch_spec) {
if (compatible_local_arch || missing_local_arch) {
// If we haven't got a valid arch spec, or the architectures are compatible
- // update the architecture, unless the one we already have is more specified
+ // update the architecture, unless the one we already have is more
+ // specified
if (replace_local_arch)
m_arch = other;
LLDB_LOG(log, "set architecture to {0} ({1})",
@@ -1502,8 +1497,8 @@ bool Target::SetArchitecture(const ArchSpec &arch_spec) {
bool Target::MergeArchitecture(const ArchSpec &arch_spec) {
if (arch_spec.IsValid()) {
if (m_arch.GetSpec().IsCompatibleMatch(arch_spec)) {
- // The current target arch is compatible with "arch_spec", see if we
- // can improve our current architecture using bits from "arch_spec"
+ // The current target arch is compatible with "arch_spec", see if we can
+ // improve our current architecture using bits from "arch_spec"
// Merge bits from arch_spec into "merged_arch" and set our architecture
ArchSpec merged_arch(m_arch.GetSpec());
@@ -1662,8 +1657,8 @@ size_t Target::ReadMemory(const Address &addr, bool prefer_file_cache,
lldb::addr_t *load_addr_ptr) {
error.Clear();
- // if we end up reading this from process memory, we will fill this
- // with the actual load address
+ // if we end up reading this from process memory, we will fill this with the
+ // actual load address
if (load_addr_ptr)
*load_addr_ptr = LLDB_INVALID_ADDRESS;
@@ -1675,16 +1670,16 @@ size_t Target::ReadMemory(const Address &addr, bool prefer_file_cache,
if (!addr.IsSectionOffset()) {
SectionLoadList &section_load_list = GetSectionLoadList();
if (section_load_list.IsEmpty()) {
- // No sections are loaded, so we must assume we are not running
- // yet and anything we are given is a file address.
+ // No sections are loaded, so we must assume we are not running yet and
+ // anything we are given is a file address.
file_addr = addr.GetOffset(); // "addr" doesn't have a section, so its
// offset is the file address
m_images.ResolveFileAddress(file_addr, resolved_addr);
} else {
- // We have at least one section loaded. This can be because
- // we have manually loaded some sections with "target modules load ..."
- // or because we have have a live process that has sections loaded
- // through the dynamic loader
+ // We have at least one section loaded. This can be because we have
+ // manually loaded some sections with "target modules load ..." or
+ // because we have have a live process that has sections loaded through
+ // the dynamic loader
load_addr = addr.GetOffset(); // "addr" doesn't have a section, so its
// offset is the load address
section_load_list.ResolveLoadAddress(load_addr, resolved_addr);
@@ -1731,19 +1726,19 @@ size_t Target::ReadMemory(const Address &addr, bool prefer_file_cache,
*load_addr_ptr = load_addr;
return bytes_read;
}
- // If the address is not section offset we have an address that
- // doesn't resolve to any address in any currently loaded shared
- // libraries and we failed to read memory so there isn't anything
- // more we can do. If it is section offset, we might be able to
- // read cached memory from the object file.
+ // If the address is not section offset we have an address that doesn't
+ // resolve to any address in any currently loaded shared libraries and we
+ // failed to read memory so there isn't anything more we can do. If it is
+ // section offset, we might be able to read cached memory from the object
+ // file.
if (!resolved_addr.IsSectionOffset())
return 0;
}
}
if (!prefer_file_cache && resolved_addr.IsSectionOffset()) {
- // If we didn't already try and read from the object file cache, then
- // try it after failing to read from the process.
+ // If we didn't already try and read from the object file cache, then try
+ // it after failing to read from the process.
return ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error);
}
return 0;
@@ -1760,8 +1755,8 @@ size_t Target::ReadCStringFromMemory(const Address &addr, std::string &out_str,
if (length == 0)
break;
out_str.append(buf, length);
- // If we got "length - 1" bytes, we didn't get the whole C string, we
- // need to read some more characters
+ // If we got "length - 1" bytes, we didn't get the whole C string, we need
+ // to read some more characters
if (length == sizeof(buf) - 1)
curr_addr += length;
else
@@ -1782,9 +1777,9 @@ size_t Target::ReadCStringFromMemory(const Address &addr, char *dst,
addr_t curr_addr = addr.GetLoadAddress(this);
Address address(addr);
- // We could call m_process_sp->GetMemoryCacheLineSize() but I don't
- // think this really needs to be tied to the memory cache subsystem's
- // cache line size, so leave this as a fixed constant.
+ // We could call m_process_sp->GetMemoryCacheLineSize() but I don't think
+ // this really needs to be tied to the memory cache subsystem's cache line
+ // size, so leave this as a fixed constant.
const size_t cache_line_size = 512;
size_t bytes_left = dst_max_len - 1;
@@ -1875,18 +1870,18 @@ bool Target::ReadPointerFromMemory(const Address &addr, bool prefer_file_cache,
if (pointer_vm_addr != LLDB_INVALID_ADDRESS) {
SectionLoadList &section_load_list = GetSectionLoadList();
if (section_load_list.IsEmpty()) {
- // No sections are loaded, so we must assume we are not running
- // yet and anything we are given is a file address.
+ // No sections are loaded, so we must assume we are not running yet and
+ // anything we are given is a file address.
m_images.ResolveFileAddress(pointer_vm_addr, pointer_addr);
} else {
- // We have at least one section loaded. This can be because
- // we have manually loaded some sections with "target modules load ..."
- // or because we have have a live process that has sections loaded
- // through the dynamic loader
+ // We have at least one section loaded. This can be because we have
+ // manually loaded some sections with "target modules load ..." or
+ // because we have have a live process that has sections loaded through
+ // the dynamic loader
section_load_list.ResolveLoadAddress(pointer_vm_addr, pointer_addr);
}
- // We weren't able to resolve the pointer value, so just return
- // an address with no section
+ // We weren't able to resolve the pointer value, so just return an
+ // address with no section
if (!pointer_addr.IsValid())
pointer_addr.SetOffset(pointer_vm_addr);
return true;
@@ -1902,9 +1897,8 @@ ModuleSP Target::GetSharedModule(const ModuleSpec &module_spec,
Status error;
// First see if we already have this module in our module list. If we do,
- // then we're done, we don't need
- // to consult the shared modules list. But only do this if we are passed a
- // UUID.
+ // then we're done, we don't need to consult the shared modules list. But
+ // only do this if we are passed a UUID.
if (module_spec.GetUUID().IsValid())
module_sp = m_images.FindFirstModule(module_spec);
@@ -1959,8 +1953,8 @@ ModuleSP Target::GetSharedModule(const ModuleSpec &module_spec,
}
// We found a module that wasn't in our target list. Let's make sure that
- // there wasn't an equivalent
- // module in the list already, and if there was, let's remove it.
+ // there wasn't an equivalent module in the list already, and if there was,
+ // let's remove it.
if (module_sp) {
ObjectFile *objfile = module_sp->GetObjectFile();
if (objfile) {
@@ -1994,18 +1988,14 @@ ModuleSP Target::GetSharedModule(const ModuleSpec &module_spec,
return ModuleSP();
}
// GetSharedModule is not guaranteed to find the old shared module, for
- // instance
- // in the common case where you pass in the UUID, it is only going to
- // find the one
- // module matching the UUID. In fact, it has no good way to know what
- // the "old module"
- // relevant to this target is, since there might be many copies of a
- // module with this file spec
- // in various running debug sessions, but only one of them will belong
- // to this target.
- // So let's remove the UUID from the module list, and look in the
- // target's module list.
- // Only do this if there is SOMETHING else in the module spec...
+ // instance in the common case where you pass in the UUID, it is only
+ // going to find the one module matching the UUID. In fact, it has no
+ // good way to know what the "old module" relevant to this target is,
+ // since there might be many copies of a module with this file spec in
+ // various running debug sessions, but only one of them will belong to
+ // this target. So let's remove the UUID from the module list, and look
+ // in the target's module list. Only do this if there is SOMETHING else
+ // in the module spec...
if (!old_module_sp) {
if (module_spec.GetUUID().IsValid() &&
!module_spec.GetFileSpec().GetFilename().IsEmpty() &&
@@ -2285,8 +2275,8 @@ ExpressionResults Target::EvaluateExpression(
if (expr.empty())
return execution_results;
- // We shouldn't run stop hooks in expressions.
- // Be sure to reset this if you return anywhere within this function.
+ // We shouldn't run stop hooks in expressions. Be sure to reset this if you
+ // return anywhere within this function.
bool old_suppress_value = m_suppress_stop_hooks;
m_suppress_stop_hooks = true;
@@ -2300,8 +2290,8 @@ ExpressionResults Target::EvaluateExpression(
CalculateExecutionContext(exe_ctx);
}
- // Make sure we aren't just trying to see the value of a persistent
- // variable (something like "$0")
+ // Make sure we aren't just trying to see the value of a persistent variable
+ // (something like "$0")
lldb::ExpressionVariableSP persistent_var_sp;
// Only check for persistent variables the expression starts with a '$'
if (expr[0] == '$')
@@ -2368,16 +2358,16 @@ lldb::addr_t Target::GetCallableLoadAddress(lldb::addr_t load_addr,
case llvm::Triple::mips64:
case llvm::Triple::mips64el:
switch (addr_class) {
- case eAddressClassData:
- case eAddressClassDebug:
+ case AddressClass::eData:
+ case AddressClass::eDebug:
return LLDB_INVALID_ADDRESS;
- case eAddressClassUnknown:
- case eAddressClassInvalid:
- case eAddressClassCode:
- case eAddressClassCodeAlternateISA:
- case eAddressClassRuntime:
- if ((code_addr & 2ull) || (addr_class == eAddressClassCodeAlternateISA))
+ case AddressClass::eUnknown:
+ case AddressClass::eInvalid:
+ case AddressClass::eCode:
+ case AddressClass::eCodeAlternateISA:
+ case AddressClass::eRuntime:
+ if ((code_addr & 2ull) || (addr_class == AddressClass::eCodeAlternateISA))
code_addr |= 1ull;
break;
}
@@ -2386,25 +2376,24 @@ lldb::addr_t Target::GetCallableLoadAddress(lldb::addr_t load_addr,
case llvm::Triple::arm:
case llvm::Triple::thumb:
switch (addr_class) {
- case eAddressClassData:
- case eAddressClassDebug:
+ case AddressClass::eData:
+ case AddressClass::eDebug:
return LLDB_INVALID_ADDRESS;
- case eAddressClassUnknown:
- case eAddressClassInvalid:
- case eAddressClassCode:
- case eAddressClassCodeAlternateISA:
- case eAddressClassRuntime:
+ case AddressClass::eUnknown:
+ case AddressClass::eInvalid:
+ case AddressClass::eCode:
+ case AddressClass::eCodeAlternateISA:
+ case AddressClass::eRuntime:
// Check if bit zero it no set?
if ((code_addr & 1ull) == 0) {
// Bit zero isn't set, check if the address is a multiple of 2?
if (code_addr & 2ull) {
// The address is a multiple of 2 so it must be thumb, set bit zero
code_addr |= 1ull;
- } else if (addr_class == eAddressClassCodeAlternateISA) {
+ } else if (addr_class == AddressClass::eCodeAlternateISA) {
// We checked the address and the address claims to be the alternate
- // ISA
- // which means thumb, so set bit zero.
+ // ISA which means thumb, so set bit zero.
code_addr |= 1ull;
}
}
@@ -2429,15 +2418,15 @@ lldb::addr_t Target::GetOpcodeLoadAddress(lldb::addr_t load_addr,
case llvm::Triple::arm:
case llvm::Triple::thumb:
switch (addr_class) {
- case eAddressClassData:
- case eAddressClassDebug:
+ case AddressClass::eData:
+ case AddressClass::eDebug:
return LLDB_INVALID_ADDRESS;
- case eAddressClassInvalid:
- case eAddressClassUnknown:
- case eAddressClassCode:
- case eAddressClassCodeAlternateISA:
- case eAddressClassRuntime:
+ case AddressClass::eInvalid:
+ case AddressClass::eUnknown:
+ case AddressClass::eCode:
+ case AddressClass::eCodeAlternateISA:
+ case AddressClass::eRuntime:
opcode_addr &= ~(1ull);
break;
}
@@ -2470,8 +2459,8 @@ lldb::addr_t Target::GetBreakableLoadAddress(lldb::addr_t addr) {
SectionLoadList &section_load_list = GetSectionLoadList();
if (section_load_list.IsEmpty())
- // No sections are loaded, so we must assume we are not running yet
- // and need to operate only on file address.
+ // No sections are loaded, so we must assume we are not running yet and
+ // need to operate only on file address.
m_images.ResolveFileAddress(addr, resolved_addr);
else
section_load_list.ResolveLoadAddress(addr, resolved_addr);
@@ -2546,30 +2535,29 @@ lldb::addr_t Target::GetBreakableLoadAddress(lldb::addr_t addr) {
} else if (i == 2) {
// Here we may get one 4-byte instruction or two 2-byte instructions.
if (num_insns == 2) {
- // Looks like there are two 2-byte instructions above our breakpoint
- // target address.
- // Now the upper 2-byte instruction is either a valid 2-byte
- // instruction or could be a part of it's upper 4-byte instruction.
- // In both cases we don't care because in this case lower 2-byte
- // instruction is definitely a valid instruction
- // and whatever i=1 iteration has found out is true.
+ // Looks like there are two 2-byte instructions above our
+ // breakpoint target address. Now the upper 2-byte instruction is
+ // either a valid 2-byte instruction or could be a part of it's
+ // upper 4-byte instruction. In both cases we don't care because in
+ // this case lower 2-byte instruction is definitely a valid
+ // instruction and whatever i=1 iteration has found out is true.
inst_to_choose = 1;
break;
} else if (insn_size == 4) {
// This instruction claims its a valid 4-byte instruction. But it
- // could be a part of it's upper 4-byte instruction.
- // Lets try scanning upper 2 bytes to verify this.
+ // could be a part of it's upper 4-byte instruction. Lets try
+ // scanning upper 2 bytes to verify this.
instruction_list.Append(prev_insn);
inst_to_choose = 2;
}
} else if (i == 3) {
if (insn_size == 4)
// FIXME: We reached here that means instruction at [target - 4] has
- // already claimed to be a 4-byte instruction,
- // and now instruction at [target - 6] is also claiming that it's a
- // 4-byte instruction. This can not be true.
- // In this case we can not decide the valid previous instruction so
- // we let lldb set the breakpoint at the address given by user.
+ // already claimed to be a 4-byte instruction, and now instruction
+ // at [target - 6] is also claiming that it's a 4-byte instruction.
+ // This can not be true. In this case we can not decide the valid
+ // previous instruction so we let lldb set the breakpoint at the
+ // address given by user.
inst_to_choose = 0;
else
// This is straight-forward
@@ -2685,8 +2673,8 @@ void Target::RunStopHooks() {
return;
// <rdar://problem/12027563> make sure we check that we are not stopped
- // because of us running a user expression
- // since in that case we do not want to run the stop-hooks
+ // because of us running a user expression since in that case we do not want
+ // to run the stop-hooks
if (m_process_sp->GetModIDRef().IsLastResumeForUserExpression())
return;
@@ -2975,18 +2963,16 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) {
launch_info.GetFlags().Set(eLaunchFlagDebug);
// Get the value of synchronous execution here. If you wait till after you
- // have started to
- // run, then you could have hit a breakpoint, whose command might switch the
- // value, and
- // then you'll pick up that incorrect value.
+ // have started to run, then you could have hit a breakpoint, whose command
+ // might switch the value, and then you'll pick up that incorrect value.
Debugger &debugger = GetDebugger();
const bool synchronous_execution =
debugger.GetCommandInterpreter().GetSynchronous();
PlatformSP platform_sp(GetPlatform());
- // Finalize the file actions, and if none were given, default to opening
- // up a pseudo terminal
+ // Finalize the file actions, and if none were given, default to opening up a
+ // pseudo terminal
const bool default_to_use_pty = platform_sp ? platform_sp->IsHost() : false;
if (log)
log->Printf("Target::%s have platform=%s, platform_sp->IsHost()=%s, "
@@ -3025,10 +3011,10 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) {
GetPlatform()->DebugProcess(launch_info, debugger, this, error);
// Cleanup the old process since someone might still have a strong
- // reference to this process and we would like to allow it to cleanup
- // as much as it can without the object being destroyed. We try to
- // lock the shared pointer and if that works, then someone else still
- // has a strong reference to the process.
+ // reference to this process and we would like to allow it to cleanup as
+ // much as it can without the object being destroyed. We try to lock the
+ // shared pointer and if that works, then someone else still has a strong
+ // reference to the process.
ProcessSP old_process_sp(process_wp.lock());
if (old_process_sp)
@@ -3152,8 +3138,8 @@ Status Target::Attach(ProcessAttachInfo &attach_info, Stream *stream) {
const ModuleSP old_exec_module_sp = GetExecutableModule();
- // If no process info was specified, then use the target executable
- // name as the process to attach to by default
+ // If no process info was specified, then use the target executable name as
+ // the process to attach to by default
if (!attach_info.ProcessInfoSpecified()) {
if (old_exec_module_sp)
attach_info.GetExecutableFile().GetFilename() =
@@ -3580,9 +3566,8 @@ public:
bool will_modify,
uint32_t idx) const override {
// When getting the value for a key from the target options, we will always
- // try and grab the setting from the current target if there is one. Else we
- // just
- // use the one from this instance.
+ // try and grab the setting from the current target if there is one. Else
+ // we just use the one from this instance.
if (idx == ePropertyEnvVars)
GetHostEnvironmentIfNeeded();
@@ -3611,36 +3596,19 @@ protected:
nullptr, idx, g_properties[idx].default_uint_value != 0)) {
PlatformSP platform_sp(m_target->GetPlatform());
if (platform_sp) {
- StringList env;
- if (platform_sp->GetEnvironment(env)) {
- OptionValueDictionary *env_dict =
- GetPropertyAtIndexAsOptionValueDictionary(nullptr,
- ePropertyEnvVars);
- if (env_dict) {
- const bool can_replace = false;
- const size_t envc = env.GetSize();
- for (size_t idx = 0; idx < envc; idx++) {
- const char *env_entry = env.GetStringAtIndex(idx);
- if (env_entry) {
- const char *equal_pos = ::strchr(env_entry, '=');
- ConstString key;
- // It is ok to have environment variables with no values
- const char *value = nullptr;
- if (equal_pos) {
- key.SetCStringWithLength(env_entry,
- equal_pos - env_entry);
- if (equal_pos[1])
- value = equal_pos + 1;
- } else {
- key.SetCString(env_entry);
- }
- // Don't allow existing keys to be replaced with ones we get
- // from the platform environment
- env_dict->SetValueForKey(
- key, OptionValueSP(new OptionValueString(value)),
- can_replace);
- }
- }
+ Environment env = platform_sp->GetEnvironment();
+ OptionValueDictionary *env_dict =
+ GetPropertyAtIndexAsOptionValueDictionary(nullptr,
+ ePropertyEnvVars);
+ if (env_dict) {
+ const bool can_replace = false;
+ for (const auto &KV : env) {
+ // Don't allow existing keys to be replaced with ones we get
+ // from the platform environment
+ env_dict->SetValueForKey(
+ ConstString(KV.first()),
+ OptionValueSP(new OptionValueString(KV.second.c_str())),
+ can_replace);
}
}
}
@@ -3690,8 +3658,8 @@ TargetProperties::TargetProperties(Target *target)
m_collection_sp.reset(
new TargetOptionValueProperties(target, Target::GetGlobalProperties()));
- // Set callbacks to update launch_info whenever "settins set" updated any of
- // these properties
+ // Set callbacks to update launch_info whenever "settins set" updated any
+ // of these properties
m_collection_sp->SetValueChangedCallback(
ePropertyArg0, TargetProperties::Arg0ValueChangedCallback, this);
m_collection_sp->SetValueChangedCallback(
@@ -3906,15 +3874,19 @@ void TargetProperties::SetRunArguments(const Args &args) {
m_launch_info.GetArguments() = args;
}
-size_t TargetProperties::GetEnvironmentAsArgs(Args &env) const {
+Environment TargetProperties::GetEnvironment() const {
+ // TODO: Get rid of the Args intermediate step
+ Args env;
const uint32_t idx = ePropertyEnvVars;
- return m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, idx, env);
+ m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, idx, env);
+ return Environment(env);
}
-void TargetProperties::SetEnvironmentFromArgs(const Args &env) {
+void TargetProperties::SetEnvironment(Environment env) {
+ // TODO: Get rid of the Args intermediate step
const uint32_t idx = ePropertyEnvVars;
- m_collection_sp->SetPropertyAtIndexFromArgs(nullptr, idx, env);
- m_launch_info.GetEnvironmentEntries() = env;
+ m_collection_sp->SetPropertyAtIndexFromArgs(nullptr, idx, Args(env));
+ m_launch_info.GetEnvironment() = std::move(env);
}
bool TargetProperties::GetSkipPrologue() const {
@@ -4152,7 +4124,7 @@ void TargetProperties::SetProcessLaunchInfo(
m_launch_info = launch_info;
SetArg0(launch_info.GetArg0());
SetRunArguments(launch_info.GetArguments());
- SetEnvironmentFromArgs(launch_info.GetEnvironmentEntries());
+ SetEnvironment(launch_info.GetEnvironment());
const FileAction *input_file_action =
launch_info.GetFileActionForFD(STDIN_FILENO);
if (input_file_action) {
@@ -4193,9 +4165,7 @@ void TargetProperties::EnvVarsValueChangedCallback(void *target_property_ptr,
OptionValue *) {
TargetProperties *this_ =
reinterpret_cast<TargetProperties *>(target_property_ptr);
- Args args;
- if (this_->GetEnvironmentAsArgs(args))
- this_->m_launch_info.GetEnvironmentEntries() = args;
+ this_->m_launch_info.GetEnvironment() = this_->GetEnvironment();
}
void TargetProperties::InputPathValueChangedCallback(void *target_property_ptr,
diff --git a/source/Target/TargetList.cpp b/source/Target/TargetList.cpp
index 5c652aced39f..b9c852b414e2 100644
--- a/source/Target/TargetList.cpp
+++ b/source/Target/TargetList.cpp
@@ -84,9 +84,9 @@ Status TargetList::CreateTargetInternal(
Status error;
PlatformSP platform_sp;
- // This is purposely left empty unless it is specified by triple_cstr.
- // If not initialized via triple_cstr, then the currently selected platform
- // will set the architecture correctly.
+ // This is purposely left empty unless it is specified by triple_cstr. If not
+ // initialized via triple_cstr, then the currently selected platform will set
+ // the architecture correctly.
const ArchSpec arch(triple_str);
if (!triple_str.empty()) {
if (!arch.IsValid()) {
@@ -102,7 +102,7 @@ Status TargetList::CreateTargetInternal(
CommandInterpreter &interpreter = debugger.GetCommandInterpreter();
- // let's see if there is already an existing plaform before we go creating
+ // let's see if there is already an existing platform before we go creating
// another...
platform_sp = debugger.GetPlatformList().GetSelectedPlatform();
@@ -120,11 +120,11 @@ Status TargetList::CreateTargetInternal(
if (!user_exe_path.empty()) {
ModuleSpecList module_specs;
ModuleSpec module_spec;
- module_spec.GetFileSpec().SetFile(user_exe_path, true);
+ module_spec.GetFileSpec().SetFile(user_exe_path, true,
+ FileSpec::Style::native);
// Resolve the executable in case we are given a path to a application
- // bundle
- // like a .app bundle on MacOSX
+ // bundle like a .app bundle on MacOSX
Host::ResolveExecutableInBundle(module_spec.GetFileSpec());
lldb::offset_t file_offset = 0;
@@ -140,7 +140,8 @@ Status TargetList::CreateTargetInternal(
if (platform_arch.IsCompatibleMatch(
matching_module_spec.GetArchitecture())) {
// If the OS or vendor weren't specified, then adopt the module's
- // architecture so that the platform matching can be more accurate
+ // architecture so that the platform matching can be more
+ // accurate
if (!platform_arch.TripleOSWasSpecified() ||
!platform_arch.TripleVendorWasSpecified()) {
prefer_platform_arch = true;
@@ -194,7 +195,8 @@ Status TargetList::CreateTargetInternal(
}
}
- // Next check the host platform it if wasn't already checked above
+ // Next check the host platform it if wasn't already checked
+ // above
if (host_platform_sp &&
(!platform_sp ||
host_platform_sp->GetName() != platform_sp->GetName())) {
@@ -231,7 +233,7 @@ Status TargetList::CreateTargetInternal(
}
if (platform_ptr) {
- // All platforms for all modules in the exectuable match, so we can
+ // All platforms for all modules in the executable match, so we can
// select this platform
platform_sp = platforms.front();
} else if (more_than_one_platforms == false) {
@@ -275,8 +277,7 @@ Status TargetList::CreateTargetInternal(
}
} else if (platform_arch.IsValid()) {
// if "arch" isn't valid, yet "platform_arch" is, it means we have an
- // executable file with
- // a single architecture which should be used
+ // executable file with a single architecture which should be used
ArchSpec fixed_platform_arch;
if (!platform_sp->IsCompatibleArchitecture(platform_arch, false,
&fixed_platform_arch)) {
@@ -367,16 +368,12 @@ Status TargetList::CreateTargetInternal(Debugger &debugger,
user_exe_path_is_bundle = true;
if (file.IsRelative() && !user_exe_path.empty()) {
- // Ignore paths that start with "./" and "../"
- if (!user_exe_path.startswith("./") && !user_exe_path.startswith("../")) {
- llvm::SmallString<64> cwd;
- if (! llvm::sys::fs::current_path(cwd)) {
- cwd += '/';
- cwd += user_exe_path;
- FileSpec cwd_file(cwd, false);
- if (cwd_file.Exists())
- file = cwd_file;
- }
+ llvm::SmallString<64> cwd;
+ if (! llvm::sys::fs::current_path(cwd)) {
+ FileSpec cwd_file(cwd.c_str(), false);
+ cwd_file.AppendPathComponent(file);
+ if (cwd_file.Exists())
+ file = cwd_file;
}
}
@@ -410,8 +407,8 @@ Status TargetList::CreateTargetInternal(Debugger &debugger,
sizeof(resolved_bundle_exe_path));
}
} else {
- // No file was specified, just create an empty target with any arch
- // if a valid arch was specified
+ // No file was specified, just create an empty target with any arch if a
+ // valid arch was specified
target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target));
}
diff --git a/source/Target/Thread.cpp b/source/Target/Thread.cpp
index 217cbccedf6e..5ac1de7ae01b 100644
--- a/source/Target/Thread.cpp
+++ b/source/Target/Thread.cpp
@@ -105,9 +105,8 @@ public:
bool will_modify,
uint32_t idx) const override {
// When getting the value for a key from the thread options, we will always
- // try and grab the setting from the current thread if there is one. Else we
- // just
- // use the one from this instance.
+ // try and grab the setting from the current thread if there is one. Else
+ // we just use the one from this instance.
if (exe_ctx) {
Thread *thread = exe_ctx->GetThreadPtr();
if (thread) {
@@ -275,8 +274,8 @@ Thread::~Thread() {
void Thread::DestroyThread() {
// Tell any plans on the plan stacks that the thread is being destroyed since
- // any plans that have a thread go away in the middle of might need
- // to do cleanup, or in some cases NOT do cleanup...
+ // any plans that have a thread go away in the middle of might need to do
+ // cleanup, or in some cases NOT do cleanup...
for (auto plan : m_plan_stack)
plan->ThreadDestroyed();
@@ -291,11 +290,10 @@ void Thread::DestroyThread() {
m_discarded_plan_stack.clear();
m_completed_plan_stack.clear();
- // Push a ThreadPlanNull on the plan stack. That way we can continue assuming
- // that the
- // plan stack is never empty, but if somebody errantly asks questions of a
- // destroyed thread
- // without checking first whether it is destroyed, they won't crash.
+ // Push a ThreadPlanNull on the plan stack. That way we can continue
+ // assuming that the plan stack is never empty, but if somebody errantly asks
+ // questions of a destroyed thread without checking first whether it is
+ // destroyed, they won't crash.
ThreadPlanSP null_plan_sp(new ThreadPlanNull(*this));
m_plan_stack.push_back(null_plan_sp);
@@ -385,11 +383,10 @@ lldb::StopInfoSP Thread::GetStopInfo() {
ProcessSP process_sp(GetProcess());
const uint32_t stop_id = process_sp ? process_sp->GetStopID() : UINT32_MAX;
- // Here we select the stop info according to priorirty:
- // - m_stop_info_sp (if not trace) - preset value
- // - completed plan stop info - new value with plan from completed plan stack
- // - m_stop_info_sp (trace stop reason is OK now)
- // - ask GetPrivateStopInfo to set stop info
+ // Here we select the stop info according to priorirty: - m_stop_info_sp (if
+ // not trace) - preset value - completed plan stop info - new value with plan
+ // from completed plan stack - m_stop_info_sp (trace stop reason is OK now) -
+ // ask GetPrivateStopInfo to set stop info
bool have_valid_stop_info = m_stop_info_sp &&
m_stop_info_sp ->IsValid() &&
@@ -432,17 +429,17 @@ lldb::StopInfoSP Thread::GetPrivateStopInfo() {
}
}
- // The stop info can be manually set by calling Thread::SetStopInfo()
- // prior to this function ever getting called, so we can't rely on
- // "m_stop_info_stop_id != process_stop_id" as the condition for
- // the if statement below, we must also check the stop info to see
- // if we need to override it. See the header documentation in
- // Process::GetStopInfoOverrideCallback() for more information on
- // the stop info override callback.
+ // The stop info can be manually set by calling Thread::SetStopInfo() prior
+ // to this function ever getting called, so we can't rely on
+ // "m_stop_info_stop_id != process_stop_id" as the condition for the if
+ // statement below, we must also check the stop info to see if we need to
+ // override it. See the header documentation in
+ // Process::GetStopInfoOverrideCallback() for more information on the stop
+ // info override callback.
if (m_stop_info_override_stop_id != process_stop_id) {
m_stop_info_override_stop_id = process_stop_id;
if (m_stop_info_sp) {
- if (Architecture *arch =
+ if (const Architecture *arch =
process_sp->GetTarget().GetArchitecturePlugin())
arch->OverrideStopInfo(*this);
}
@@ -509,9 +506,8 @@ void Thread::SetShouldReportStop(Vote vote) {
void Thread::SetStopInfoToNothing() {
// Note, we can't just NULL out the private reason, or the native thread
- // implementation will try to
- // go calculate it again. For now, just set it to a Unix Signal with an
- // invalid signal number.
+ // implementation will try to go calculate it again. For now, just set it to
+ // a Unix Signal with an invalid signal number.
SetStopInfo(
StopInfo::CreateStopReasonWithSignal(*this, LLDB_INVALID_SIGNAL_NUMBER));
}
@@ -604,10 +600,8 @@ void Thread::WillStop() {
void Thread::SetupForResume() {
if (GetResumeState() != eStateSuspended) {
// If we're at a breakpoint push the step-over breakpoint plan. Do this
- // before
- // telling the current plan it will resume, since we might change what the
- // current
- // plan is.
+ // before telling the current plan it will resume, since we might change
+ // what the current plan is.
lldb::RegisterContextSP reg_ctx_sp(GetRegisterContext());
if (reg_ctx_sp) {
@@ -615,9 +609,8 @@ void Thread::SetupForResume() {
BreakpointSiteSP bp_site_sp =
GetProcess()->GetBreakpointSiteList().FindByAddress(thread_pc);
if (bp_site_sp) {
- // Note, don't assume there's a ThreadPlanStepOverBreakpoint, the target
- // may not require anything
- // special to step over a breakpoint.
+ // Note, don't assume there's a ThreadPlanStepOverBreakpoint, the
+ // target may not require anything special to step over a breakpoint.
ThreadPlan *cur_plan = GetCurrentPlan();
@@ -669,11 +662,9 @@ bool Thread::ShouldResume(StateType resume_state) {
GetPrivateStopInfo();
// This is a little dubious, but we are trying to limit how often we actually
- // fetch stop info from
- // the target, 'cause that slows down single stepping. So assume that if we
- // got to the point where
- // we're about to resume, and we haven't yet had to fetch the stop reason,
- // then it doesn't need to know
+ // fetch stop info from the target, 'cause that slows down single stepping.
+ // So assume that if we got to the point where we're about to resume, and we
+ // haven't yet had to fetch the stop reason, then it doesn't need to know
// about the fact that we are resuming...
const uint32_t process_stop_id = GetProcess()->GetStopID();
if (m_stop_info_stop_id == process_stop_id &&
@@ -684,9 +675,9 @@ bool Thread::ShouldResume(StateType resume_state) {
}
// Tell all the plans that we are about to resume in case they need to clear
- // any state.
- // We distinguish between the plan on the top of the stack and the lower
- // plans in case a plan needs to do any special business before it runs.
+ // any state. We distinguish between the plan on the top of the stack and the
+ // lower plans in case a plan needs to do any special business before it
+ // runs.
bool need_to_resume = false;
ThreadPlan *plan_ptr = GetCurrentPlan();
@@ -698,8 +689,7 @@ bool Thread::ShouldResume(StateType resume_state) {
}
// If the WillResume for the plan says we are faking a resume, then it will
- // have set an appropriate stop info.
- // In that case, don't reset it here.
+ // have set an appropriate stop info. In that case, don't reset it here.
if (need_to_resume && resume_state != eStateSuspended) {
m_stop_info_sp.reset();
@@ -743,9 +733,8 @@ bool Thread::ShouldStop(Event *event_ptr) {
}
// Based on the current thread plan and process stop info, check if this
- // thread caused the process to stop. NOTE: this must take place before
- // the plan is moved from the current plan stack to the completed plan
- // stack.
+ // thread caused the process to stop. NOTE: this must take place before the
+ // plan is moved from the current plan stack to the completed plan stack.
if (!ThreadStoppedForAReason()) {
if (log)
log->Printf("Thread::%s for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64
@@ -775,10 +764,9 @@ bool Thread::ShouldStop(Event *event_ptr) {
current_plan->DoTraceLog();
// First query the stop info's ShouldStopSynchronous. This handles
- // "synchronous" stop reasons, for example the breakpoint
- // command on internal breakpoints. If a synchronous stop reason says we
- // should not stop, then we don't have to
- // do any more work on this stop.
+ // "synchronous" stop reasons, for example the breakpoint command on internal
+ // breakpoints. If a synchronous stop reason says we should not stop, then
+ // we don't have to do any more work on this stop.
StopInfoSP private_stop_info(GetPrivateStopInfo());
if (private_stop_info &&
!private_stop_info->ShouldStopSynchronous(event_ptr)) {
@@ -788,8 +776,8 @@ bool Thread::ShouldStop(Event *event_ptr) {
return false;
}
- // If we've already been restarted, don't query the plans since the state they
- // would examine is not current.
+ // If we've already been restarted, don't query the plans since the state
+ // they would examine is not current.
if (Process::ProcessEventData::GetRestartedFromEvent(event_ptr))
return false;
@@ -798,12 +786,10 @@ bool Thread::ShouldStop(Event *event_ptr) {
GetStackFrameList()->CalculateCurrentInlinedDepth();
// If the base plan doesn't understand why we stopped, then we have to find a
- // plan that does.
- // If that plan is still working, then we don't need to do any more work. If
- // the plan that explains
- // the stop is done, then we should pop all the plans below it, and pop it,
- // and then let the plans above it decide
- // whether they still need to do more work.
+ // plan that does. If that plan is still working, then we don't need to do
+ // any more work. If the plan that explains the stop is done, then we should
+ // pop all the plans below it, and pop it, and then let the plans above it
+ // decide whether they still need to do more work.
bool done_processing_current_plan = false;
@@ -812,16 +798,16 @@ bool Thread::ShouldStop(Event *event_ptr) {
done_processing_current_plan = true;
should_stop = false;
} else {
- // If the current plan doesn't explain the stop, then find one that
- // does and let it handle the situation.
+ // If the current plan doesn't explain the stop, then find one that does
+ // and let it handle the situation.
ThreadPlan *plan_ptr = current_plan;
while ((plan_ptr = GetPreviousPlan(plan_ptr)) != nullptr) {
if (plan_ptr->PlanExplainsStop(event_ptr)) {
should_stop = plan_ptr->ShouldStop(event_ptr);
- // plan_ptr explains the stop, next check whether plan_ptr is done, if
- // so, then we should take it
- // and all the plans below it off the stack.
+ // plan_ptr explains the stop, next check whether plan_ptr is done,
+ // if so, then we should take it and all the plans below it off the
+ // stack.
if (plan_ptr->MischiefManaged()) {
// We're going to pop the plans up to and including the plan that
@@ -833,9 +819,9 @@ bool Thread::ShouldStop(Event *event_ptr) {
current_plan->WillStop();
PopPlan();
} while ((current_plan = GetCurrentPlan()) != prev_plan_ptr);
- // Now, if the responsible plan was not "Okay to discard" then we're
- // done,
- // otherwise we forward this to the next plan in the stack below.
+ // Now, if the responsible plan was not "Okay to discard" then
+ // we're done, otherwise we forward this to the next plan in the
+ // stack below.
done_processing_current_plan =
(plan_ptr->IsMasterPlan() && !plan_ptr->OkayToDiscard());
} else
@@ -860,9 +846,9 @@ bool Thread::ShouldStop(Event *event_ptr) {
if (log)
log->Printf("Base plan says should stop: %i.", should_stop);
} else {
- // Otherwise, don't let the base plan override what the other plans say to
- // do, since
- // presumably if there were other plans they would know what to do...
+ // Otherwise, don't let the base plan override what the other plans say
+ // to do, since presumably if there were other plans they would know what
+ // to do...
while (1) {
if (PlanIsBasePlan(current_plan))
break;
@@ -875,9 +861,8 @@ bool Thread::ShouldStop(Event *event_ptr) {
if (should_stop)
current_plan->WillStop();
- // If a Master Plan wants to stop, and wants to stick on the stack, we
- // let it.
- // Otherwise, see if the plan's parent wants to stop.
+ // If a Master Plan wants to stop, and wants to stick on the stack,
+ // we let it. Otherwise, see if the plan's parent wants to stop.
if (should_stop && current_plan->IsMasterPlan() &&
!current_plan->OkayToDiscard()) {
@@ -902,18 +887,16 @@ bool Thread::ShouldStop(Event *event_ptr) {
}
// One other potential problem is that we set up a master plan, then stop in
- // before it is complete - for instance
- // by hitting a breakpoint during a step-over - then do some step/finish/etc
- // operations that wind up
- // past the end point condition of the initial plan. We don't want to strand
- // the original plan on the stack,
- // This code clears stale plans off the stack.
+ // before it is complete - for instance by hitting a breakpoint during a
+ // step-over - then do some step/finish/etc operations that wind up past the
+ // end point condition of the initial plan. We don't want to strand the
+ // original plan on the stack, This code clears stale plans off the stack.
if (should_stop) {
ThreadPlan *plan_ptr = GetCurrentPlan();
- // Discard the stale plans and all plans below them in the stack,
- // plus move the completed plans to the completed plan stack
+ // Discard the stale plans and all plans below them in the stack, plus move
+ // the completed plans to the completed plan stack
while (!PlanIsBasePlan(plan_ptr)) {
bool stale = plan_ptr->IsPlanStale();
ThreadPlan *examined_plan = plan_ptr;
@@ -928,8 +911,9 @@ bool Thread::ShouldStop(Event *event_ptr) {
DiscardPlan();
}
if (examined_plan->IsPlanComplete()) {
- // plan is complete but does not explain the stop (example: step to a line
- // with breakpoint), let us move the plan to completed_plan_stack anyway
+ // plan is complete but does not explain the stop (example: step to a
+ // line with breakpoint), let us move the plan to
+ // completed_plan_stack anyway
PopPlan();
} else
DiscardPlan();
@@ -1097,8 +1081,8 @@ void Thread::DiscardPlan() {
}
ThreadPlan *Thread::GetCurrentPlan() {
- // There will always be at least the base plan. If somebody is mucking with a
- // thread with an empty plan stack, we should assert right away.
+ // There will always be at least the base plan. If somebody is mucking with
+ // a thread with an empty plan stack, we should assert right away.
return m_plan_stack.empty() ? nullptr : m_plan_stack.back().get();
}
@@ -1212,8 +1196,7 @@ void Thread::SetTracer(lldb::ThreadPlanTracerSP &tracer_sp) {
bool Thread::DiscardUserThreadPlansUpToIndex(uint32_t thread_index) {
// Count the user thread plans from the back end to get the number of the one
- // we want
- // to discard:
+ // we want to discard:
uint32_t idx = 0;
ThreadPlan *up_to_plan_ptr = nullptr;
@@ -1249,8 +1232,7 @@ void Thread::DiscardThreadPlansUpToPlan(ThreadPlan *up_to_plan_ptr) {
int stack_size = m_plan_stack.size();
// If the input plan is nullptr, discard all plans. Otherwise make sure this
- // plan is in the
- // stack, and if so discard up to and including it.
+ // plan is in the stack, and if so discard up to and including it.
if (up_to_plan_ptr == nullptr) {
for (int i = stack_size - 1; i > 0; i--)
@@ -1314,8 +1296,7 @@ void Thread::DiscardThreadPlans(bool force) {
// Now discard the master plan itself.
// The bottom-most plan never gets discarded. "OkayToDiscard" for it
- // means
- // discard it's dependent plans, but not it...
+ // means discard it's dependent plans, but not it...
if (master_plan_idx > 0) {
DiscardPlan();
}
@@ -1340,8 +1321,7 @@ Status Thread::UnwindInnermostExpression() {
int stack_size = m_plan_stack.size();
// If the input plan is nullptr, discard all plans. Otherwise make sure this
- // plan is in the
- // stack, and if so discard up to and including it.
+ // plan is in the stack, and if so discard up to and including it.
for (int i = stack_size - 1; i > 0; i--) {
if (m_plan_stack[i]->GetKind() == ThreadPlan::eKindCallFunction) {
@@ -1380,7 +1360,8 @@ ThreadPlanSP Thread::QueueThreadPlanForStepOverRange(
return thread_plan_sp;
}
-// Call the QueueThreadPlanForStepOverRange method which takes an address range.
+// Call the QueueThreadPlanForStepOverRange method which takes an address
+// range.
ThreadPlanSP Thread::QueueThreadPlanForStepOverRange(
bool abort_other_plans, const LineEntry &line_entry,
const SymbolContext &addr_context, lldb::RunMode stop_other_threads,
@@ -1500,11 +1481,9 @@ lldb::ThreadPlanSP Thread::QueueThreadPlanForStepScripted(
ThreadPlanSP thread_plan_sp(new ThreadPlanPython(*this, class_name));
QueueThreadPlan(thread_plan_sp, abort_other_plans);
// This seems a little funny, but I don't want to have to split up the
- // constructor and the
- // DidPush in the scripted plan, that seems annoying.
- // That means the constructor has to be in DidPush.
- // So I have to validate the plan AFTER pushing it, and then take it off
- // again...
+ // constructor and the DidPush in the scripted plan, that seems annoying.
+ // That means the constructor has to be in DidPush. So I have to validate the
+ // plan AFTER pushing it, and then take it off again...
if (!thread_plan_sp->ValidatePlan(nullptr)) {
DiscardThreadPlansUpToPlan(thread_plan_sp);
return ThreadPlanSP();
@@ -1701,10 +1680,9 @@ Status Thread::ReturnFromFrame(lldb::StackFrameSP frame_sp,
return return_error;
}
- // Now write the return registers for the chosen frame:
- // Note, we can't use ReadAllRegisterValues->WriteAllRegisterValues, since the
- // read & write
- // cook their data
+ // Now write the return registers for the chosen frame: Note, we can't use
+ // ReadAllRegisterValues->WriteAllRegisterValues, since the read & write cook
+ // their data
StackFrameSP youngest_frame_sp = thread->GetStackFrameAtIndex(0);
if (youngest_frame_sp) {
@@ -1754,13 +1732,11 @@ Status Thread::JumpToLine(const FileSpec &file, uint32_t line,
target->GetImages().FindAddressesForLine(target_sp, file, line, sc.function,
within_function, outside_function);
- // If possible, we try and stay within the current function.
- // Within a function, we accept multiple locations (optimized code may do
- // this,
- // there's no solution here so we do the best we can).
- // However if we're trying to leave the function, we don't know how to pick
- // the
- // right location, so if there's more than one then we bail.
+ // If possible, we try and stay within the current function. Within a
+ // function, we accept multiple locations (optimized code may do this,
+ // there's no solution here so we do the best we can). However if we're
+ // trying to leave the function, we don't know how to pick the right
+ // location, so if there's more than one then we bail.
if (!within_function.empty())
candidates = within_function;
else if (outside_function.size() == 1 && can_leave_function)
@@ -1836,8 +1812,8 @@ lldb::addr_t Thread::GetThreadPointer() { return LLDB_INVALID_ADDRESS; }
addr_t Thread::GetThreadLocalData(const ModuleSP module,
lldb::addr_t tls_file_addr) {
- // The default implementation is to ask the dynamic loader for it.
- // This can be overridden for specific platforms.
+ // The default implementation is to ask the dynamic loader for it. This can
+ // be overridden for specific platforms.
DynamicLoader *loader = GetProcess()->GetDynamicLoader();
if (loader)
return loader->GetThreadLocalData(module, shared_from_this(),
@@ -2096,10 +2072,8 @@ void Thread::Flush() {
bool Thread::IsStillAtLastBreakpointHit() {
// If we are currently stopped at a breakpoint, always return that stopinfo
- // and don't reset it.
- // This allows threads to maintain their breakpoint stopinfo, such as when
- // thread-stepping in
- // multithreaded programs.
+ // and don't reset it. This allows threads to maintain their breakpoint
+ // stopinfo, such as when thread-stepping in multithreaded programs.
if (m_stop_info_sp) {
StopReason stop_reason = m_stop_info_sp->GetStopReason();
if (stop_reason == lldb::eStopReasonBreakpoint) {
diff --git a/source/Target/ThreadList.cpp b/source/Target/ThreadList.cpp
index 4cf8f9061a89..ee57a401f742 100644
--- a/source/Target/ThreadList.cpp
+++ b/source/Target/ThreadList.cpp
@@ -40,8 +40,8 @@ ThreadList::ThreadList(const ThreadList &rhs)
const ThreadList &ThreadList::operator=(const ThreadList &rhs) {
if (this != &rhs) {
- // Lock both mutexes to make sure neither side changes anyone on us
- // while the assignment occurs
+ // Lock both mutexes to make sure neither side changes anyone on us while
+ // the assignment occurs
std::lock_guard<std::recursive_mutex> guard(GetMutex());
std::lock_guard<std::recursive_mutex> rhs_guard(rhs.GetMutex());
@@ -54,9 +54,8 @@ const ThreadList &ThreadList::operator=(const ThreadList &rhs) {
}
ThreadList::~ThreadList() {
- // Clear the thread list. Clear will take the mutex lock
- // which will ensure that if anyone is using the list
- // they won't get it removed while using it.
+ // Clear the thread list. Clear will take the mutex lock which will ensure
+ // that if anyone is using the list they won't get it removed while using it.
Clear();
}
@@ -195,6 +194,20 @@ ThreadSP ThreadList::GetThreadSPForThreadPtr(Thread *thread_ptr) {
return thread_sp;
}
+ThreadSP ThreadList::GetBackingThread(const ThreadSP &real_thread) {
+ std::lock_guard<std::recursive_mutex> guard(GetMutex());
+
+ ThreadSP thread_sp;
+ const uint32_t num_threads = m_threads.size();
+ for (uint32_t idx = 0; idx < num_threads; ++idx) {
+ if (m_threads[idx]->GetBackingThread() == real_thread) {
+ thread_sp = m_threads[idx];
+ break;
+ }
+ }
+ return thread_sp;
+}
+
ThreadSP ThreadList::FindThreadByIndexID(uint32_t index_id, bool can_update) {
std::lock_guard<std::recursive_mutex> guard(GetMutex());
@@ -217,13 +230,13 @@ bool ThreadList::ShouldStop(Event *event_ptr) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
- // The ShouldStop method of the threads can do a whole lot of work,
- // figuring out whether the thread plan conditions are met. So we don't want
- // to keep the ThreadList locked the whole time we are doing this.
+ // The ShouldStop method of the threads can do a whole lot of work, figuring
+ // out whether the thread plan conditions are met. So we don't want to keep
+ // the ThreadList locked the whole time we are doing this.
// FIXME: It is possible that running code could cause new threads
- // to be created. If that happens, we will miss asking them whether
- // they should stop. This is not a big deal since we haven't had
- // a chance to hang any interesting operations on those threads yet.
+ // to be created. If that happens, we will miss asking them whether they
+ // should stop. This is not a big deal since we haven't had a chance to hang
+ // any interesting operations on those threads yet.
collection threads_copy;
{
@@ -233,25 +246,21 @@ bool ThreadList::ShouldStop(Event *event_ptr) {
m_process->UpdateThreadListIfNeeded();
for (lldb::ThreadSP thread_sp : m_threads) {
// This is an optimization... If we didn't let a thread run in between
- // the previous stop and this
- // one, we shouldn't have to consult it for ShouldStop. So just leave it
- // off the list we are going to
- // inspect.
- // On Linux, if a thread-specific conditional breakpoint was hit, it won't
- // necessarily be the thread
- // that hit the breakpoint itself that evaluates the conditional
- // expression, so the thread that hit
- // the breakpoint could still be asked to stop, even though it hasn't been
- // allowed to run since the
- // previous stop.
+ // the previous stop and this one, we shouldn't have to consult it for
+ // ShouldStop. So just leave it off the list we are going to inspect. On
+ // Linux, if a thread-specific conditional breakpoint was hit, it won't
+ // necessarily be the thread that hit the breakpoint itself that
+ // evaluates the conditional expression, so the thread that hit the
+ // breakpoint could still be asked to stop, even though it hasn't been
+ // allowed to run since the previous stop.
if (thread_sp->GetTemporaryResumeState() != eStateSuspended ||
thread_sp->IsStillAtLastBreakpointHit())
threads_copy.push_back(thread_sp);
}
// It is possible the threads we were allowing to run all exited and then
- // maybe the user interrupted
- // or something, then fall back on looking at all threads:
+ // maybe the user interrupted or something, then fall back on looking at
+ // all threads:
if (threads_copy.size() == 0)
threads_copy = m_threads;
@@ -282,12 +291,11 @@ bool ThreadList::ShouldStop(Event *event_ptr) {
}
// Now we run through all the threads and get their stop info's. We want to
- // make sure to do this first before
- // we start running the ShouldStop, because one thread's ShouldStop could
- // destroy information (like deleting a
- // thread specific breakpoint another thread had stopped at) which could lead
- // us to compute the StopInfo incorrectly.
- // We don't need to use it here, we just want to make sure it gets computed.
+ // make sure to do this first before we start running the ShouldStop, because
+ // one thread's ShouldStop could destroy information (like deleting a thread
+ // specific breakpoint another thread had stopped at) which could lead us to
+ // compute the StopInfo incorrectly. We don't need to use it here, we just
+ // want to make sure it gets computed.
for (pos = threads_copy.begin(); pos != end; ++pos) {
ThreadSP thread_sp(*pos);
@@ -298,27 +306,24 @@ bool ThreadList::ShouldStop(Event *event_ptr) {
ThreadSP thread_sp(*pos);
// We should never get a stop for which no thread had a stop reason, but
- // sometimes we do see this -
- // for instance when we first connect to a remote stub. In that case we
- // should stop, since we can't figure out
- // the right thing to do and stopping gives the user control over what to do
- // in this instance.
+ // sometimes we do see this - for instance when we first connect to a
+ // remote stub. In that case we should stop, since we can't figure out the
+ // right thing to do and stopping gives the user control over what to do in
+ // this instance.
//
// Note, this causes a problem when you have a thread specific breakpoint,
- // and a bunch of threads hit the breakpoint,
- // but not the thread which we are waiting for. All the threads that are
- // not "supposed" to hit the breakpoint
- // are marked as having no stop reason, which is right, they should not show
- // a stop reason. But that triggers this
- // code and causes us to stop seemingly for no reason.
+ // and a bunch of threads hit the breakpoint, but not the thread which we
+ // are waiting for. All the threads that are not "supposed" to hit the
+ // breakpoint are marked as having no stop reason, which is right, they
+ // should not show a stop reason. But that triggers this code and causes
+ // us to stop seemingly for no reason.
//
// Since the only way we ever saw this error was on first attach, I'm only
- // going to trigger set did_anybody_stop_for_a_reason
- // to true unless this is the first stop.
+ // going to trigger set did_anybody_stop_for_a_reason to true unless this
+ // is the first stop.
//
// If this becomes a problem, we'll have to have another StopReason like
- // "StopInfoHidden" which will look invalid
- // everywhere but at this check.
+ // "StopInfoHidden" which will look invalid everywhere but at this check.
if (thread_sp->GetProcess()->GetStopID() > 1)
did_anybody_stop_for_a_reason = true;
@@ -365,8 +370,8 @@ Vote ThreadList::ShouldReportStop(Event *event_ptr) {
log->Printf("ThreadList::%s %" PRIu64 " threads", __FUNCTION__,
(uint64_t)m_threads.size());
- // Run through the threads and ask whether we should report this event.
- // For stopping, a YES vote wins over everything. A NO vote wins over NO
+ // Run through the threads and ask whether we should report this event. For
+ // stopping, a YES vote wins over everything. A NO vote wins over NO
// opinion.
for (pos = m_threads.begin(); pos != end; ++pos) {
ThreadSP thread_sp(*pos);
@@ -413,8 +418,8 @@ Vote ThreadList::ShouldReportRun(Event *event_ptr) {
m_process->UpdateThreadListIfNeeded();
collection::iterator pos, end = m_threads.end();
- // Run through the threads and ask whether we should report this event.
- // The rule is NO vote wins over everything, a YES vote wins over no opinion.
+ // Run through the threads and ask whether we should report this event. The
+ // rule is NO vote wins over everything, a YES vote wins over no opinion.
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
@@ -471,8 +476,8 @@ void ThreadList::RefreshStateAfterStop() {
}
void ThreadList::DiscardThreadPlans() {
- // You don't need to update the thread list here, because only threads
- // that you currently know about have any thread plans.
+ // You don't need to update the thread list here, because only threads that
+ // you currently know about have any thread plans.
std::lock_guard<std::recursive_mutex> guard(GetMutex());
collection::iterator pos, end = m_threads.end();
@@ -481,9 +486,9 @@ void ThreadList::DiscardThreadPlans() {
}
bool ThreadList::WillResume() {
- // Run through the threads and perform their momentary actions.
- // But we only do this for threads that are running, user suspended
- // threads stay where they are.
+ // Run through the threads and perform their momentary actions. But we only
+ // do this for threads that are running, user suspended threads stay where
+ // they are.
std::lock_guard<std::recursive_mutex> guard(GetMutex());
m_process->UpdateThreadListIfNeeded();
@@ -491,14 +496,11 @@ bool ThreadList::WillResume() {
collection::iterator pos, end = m_threads.end();
// See if any thread wants to run stopping others. If it does, then we won't
- // setup the other threads for resume, since they aren't going to get a chance
- // to run. This is necessary because the SetupForResume might add
- // "StopOthers"
- // plans which would then get to be part of the who-gets-to-run negotiation,
- // but
- // they're coming in after the fact, and the threads that are already set up
- // should
- // take priority.
+ // setup the other threads for resume, since they aren't going to get a
+ // chance to run. This is necessary because the SetupForResume might add
+ // "StopOthers" plans which would then get to be part of the who-gets-to-run
+ // negotiation, but they're coming in after the fact, and the threads that
+ // are already set up should take priority.
bool wants_solo_run = false;
@@ -530,11 +532,9 @@ bool ThreadList::WillResume() {
}
// Give all the threads that are likely to run a last chance to set up their
- // state before we
- // negotiate who is actually going to get a chance to run...
+ // state before we negotiate who is actually going to get a chance to run...
// Don't set to resume suspended threads, and if any thread wanted to stop
- // others, only
- // call setup on the threads that request StopOthers...
+ // others, only call setup on the threads that request StopOthers...
for (pos = m_threads.begin(); pos != end; ++pos) {
if ((*pos)->GetResumeState() != eStateSuspended &&
@@ -636,13 +636,12 @@ void ThreadList::DidStop() {
std::lock_guard<std::recursive_mutex> guard(GetMutex());
collection::iterator pos, end = m_threads.end();
for (pos = m_threads.begin(); pos != end; ++pos) {
- // Notify threads that the process just stopped.
- // Note, this currently assumes that all threads in the list
- // stop when the process stops. In the future we will want to support
- // a debugging model where some threads continue to run while others
- // are stopped. We either need to handle that somehow here or
- // create a special thread list containing only threads which will
- // stop in the code that calls this method (currently
+ // Notify threads that the process just stopped. Note, this currently
+ // assumes that all threads in the list stop when the process stops. In
+ // the future we will want to support a debugging model where some threads
+ // continue to run while others are stopped. We either need to handle that
+ // somehow here or create a special thread list containing only threads
+ // which will stop in the code that calls this method (currently
// Process::SetPrivateState).
ThreadSP thread_sp(*pos);
if (StateIsRunningState(thread_sp->GetState()))
@@ -703,8 +702,8 @@ void ThreadList::NotifySelectedThreadChanged(lldb::tid_t tid) {
void ThreadList::Update(ThreadList &rhs) {
if (this != &rhs) {
- // Lock both mutexes to make sure neither side changes anyone on us
- // while the assignment occurs
+ // Lock both mutexes to make sure neither side changes anyone on us while
+ // the assignment occurs
std::lock_guard<std::recursive_mutex> guard(GetMutex());
m_process = rhs.m_process;
@@ -712,13 +711,12 @@ void ThreadList::Update(ThreadList &rhs) {
m_threads.swap(rhs.m_threads);
m_selected_tid = rhs.m_selected_tid;
- // Now we look for threads that we are done with and
- // make sure to clear them up as much as possible so
- // anyone with a shared pointer will still have a reference,
- // but the thread won't be of much use. Using std::weak_ptr
- // for all backward references (such as a thread to a process)
- // will eventually solve this issue for us, but for now, we
- // need to work around the issue
+ // Now we look for threads that we are done with and make sure to clear
+ // them up as much as possible so anyone with a shared pointer will still
+ // have a reference, but the thread won't be of much use. Using
+ // std::weak_ptr for all backward references (such as a thread to a
+ // process) will eventually solve this issue for us, but for now, we need
+ // to work around the issue
collection::iterator rhs_pos, rhs_end = rhs.m_threads.end();
for (rhs_pos = rhs.m_threads.begin(); rhs_pos != rhs_end; ++rhs_pos) {
const lldb::tid_t tid = (*rhs_pos)->GetID();
diff --git a/source/Target/ThreadPlan.cpp b/source/Target/ThreadPlan.cpp
index 27c9e2aa9c00..31ee1e922494 100644
--- a/source/Target/ThreadPlan.cpp
+++ b/source/Target/ThreadPlan.cpp
@@ -100,8 +100,8 @@ bool ThreadPlan::StopOthers() {
}
void ThreadPlan::SetStopOthers(bool new_value) {
- // SetStopOthers doesn't work up the hierarchy. You have to set the
- // explicit ThreadPlan you want to affect.
+ // SetStopOthers doesn't work up the hierarchy. You have to set the explicit
+ // ThreadPlan you want to affect.
}
bool ThreadPlan::WillResume(StateType resume_state, bool current_plan) {
diff --git a/source/Target/ThreadPlanBase.cpp b/source/Target/ThreadPlanBase.cpp
index d1c2f6dd1206..65b114584177 100644
--- a/source/Target/ThreadPlanBase.cpp
+++ b/source/Target/ThreadPlanBase.cpp
@@ -28,8 +28,8 @@ using namespace lldb;
using namespace lldb_private;
//----------------------------------------------------------------------
-// ThreadPlanBase: This one always stops, and never has anything particular
-// to do.
+// ThreadPlanBase: This one always stops, and never has anything particular to
+// do.
// FIXME: The "signal handling" policies should probably go here.
//----------------------------------------------------------------------
@@ -59,8 +59,8 @@ void ThreadPlanBase::GetDescription(Stream *s, lldb::DescriptionLevel level) {
bool ThreadPlanBase::ValidatePlan(Stream *error) { return true; }
bool ThreadPlanBase::DoPlanExplainsStop(Event *event_ptr) {
- // The base plan should defer to its tracer, since by default it
- // always handles the stop.
+ // The base plan should defer to its tracer, since by default it always
+ // handles the stop.
if (TracerExplainsStop())
return false;
else
@@ -99,10 +99,9 @@ bool ThreadPlanBase::ShouldStop(Event *event_ptr) {
case eStopReasonBreakpoint:
case eStopReasonWatchpoint:
if (stop_info_sp->ShouldStopSynchronous(event_ptr)) {
- // If we are going to stop for a breakpoint, then unship the other plans
- // at this point. Don't force the discard, however, so Master plans can
- // stay
- // in place if they want to.
+ // If we are going to stop for a breakpoint, then unship the other
+ // plans at this point. Don't force the discard, however, so Master
+ // plans can stay in place if they want to.
if (log)
log->Printf(
"Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
@@ -112,9 +111,8 @@ bool ThreadPlanBase::ShouldStop(Event *event_ptr) {
return true;
}
// If we aren't going to stop at this breakpoint, and it is internal,
- // don't report this stop or the subsequent running event.
- // Otherwise we will post the stopped & running, but the stopped event
- // will get marked
+ // don't report this stop or the subsequent running event. Otherwise we
+ // will post the stopped & running, but the stopped event will get marked
// with "restarted" so the UI will know to wait and expect the consequent
// "running".
if (stop_info_sp->ShouldNotify(event_ptr)) {
@@ -131,10 +129,9 @@ bool ThreadPlanBase::ShouldStop(Event *event_ptr) {
break;
case eStopReasonException:
- // If we crashed, discard thread plans and stop. Don't force the discard,
- // however,
- // since on rerun the target may clean up this exception and continue
- // normally from there.
+ // If we crashed, discard thread plans and stop. Don't force the
+ // discard, however, since on rerun the target may clean up this
+ // exception and continue normally from there.
if (log)
log->Printf(
"Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
@@ -144,10 +141,9 @@ bool ThreadPlanBase::ShouldStop(Event *event_ptr) {
return true;
case eStopReasonExec:
- // If we crashed, discard thread plans and stop. Don't force the discard,
- // however,
- // since on rerun the target may clean up this exception and continue
- // normally from there.
+ // If we crashed, discard thread plans and stop. Don't force the
+ // discard, however, since on rerun the target may clean up this
+ // exception and continue normally from there.
if (log)
log->Printf(
"Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
@@ -198,8 +194,7 @@ bool ThreadPlanBase::WillStop() { return true; }
bool ThreadPlanBase::DoWillResume(lldb::StateType resume_state,
bool current_plan) {
// Reset these to the default values so we don't set them wrong, then not get
- // asked
- // for a while, then return the wrong answer.
+ // asked for a while, then return the wrong answer.
m_run_vote = eVoteNoOpinion;
m_stop_vote = eVoteNo;
return true;
diff --git a/source/Target/ThreadPlanCallFunction.cpp b/source/Target/ThreadPlanCallFunction.cpp
index e3b9ae15dc95..18beda42fb64 100644
--- a/source/Target/ThreadPlanCallFunction.cpp
+++ b/source/Target/ThreadPlanCallFunction.cpp
@@ -15,6 +15,7 @@
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Address.h"
+#include "lldb/Core/DumpRegisterValue.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/ABI.h"
@@ -56,8 +57,7 @@ bool ThreadPlanCallFunction::ConstructorSetup(
m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
// If we can't read memory at the point of the process where we are planning
- // to put our function, we're
- // not going to get any further...
+ // to put our function, we're not going to get any further...
Status error;
process_sp->ReadUnsignedIntegerFromMemory(m_function_sp, 4, 0, error);
if (!error.Success()) {
@@ -187,7 +187,8 @@ void ThreadPlanCallFunction::ReportRegisterState(const char *message) {
reg_idx < num_registers; ++reg_idx) {
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_idx);
if (reg_ctx->ReadRegister(reg_info, reg_value)) {
- reg_value.Dump(&strm, reg_info, true, false, eFormatDefault);
+ DumpRegisterValue(reg_value, &strm, reg_info, true, false,
+ eFormatDefault);
strm.EOL();
}
}
@@ -278,9 +279,8 @@ bool ThreadPlanCallFunction::DoPlanExplainsStop(Event *event_ptr) {
LIBLLDB_LOG_PROCESS));
m_real_stop_info_sp = GetPrivateStopInfo();
- // If our subplan knows why we stopped, even if it's done (which would forward
- // the question to us)
- // we answer yes.
+ // If our subplan knows why we stopped, even if it's done (which would
+ // forward the question to us) we answer yes.
if (m_subplan_sp && m_subplan_sp->PlanExplainsStop(event_ptr)) {
SetPlanComplete();
return true;
@@ -302,8 +302,8 @@ bool ThreadPlanCallFunction::DoPlanExplainsStop(Event *event_ptr) {
return true;
// One more quirk here. If this event was from Halt interrupting the target,
- // then we should not consider
- // ourselves complete. Return true to acknowledge the stop.
+ // then we should not consider ourselves complete. Return true to
+ // acknowledge the stop.
if (Process::ProcessEventData::GetInterruptedFromEvent(event_ptr)) {
if (log)
log->Printf("ThreadPlanCallFunction::PlanExplainsStop: The event is an "
@@ -312,8 +312,8 @@ bool ThreadPlanCallFunction::DoPlanExplainsStop(Event *event_ptr) {
}
// We control breakpoints separately from other "stop reasons." So first,
// check the case where we stopped for an internal breakpoint, in that case,
- // continue on.
- // If it is not an internal breakpoint, consult m_ignore_breakpoints.
+ // continue on. If it is not an internal breakpoint, consult
+ // m_ignore_breakpoints.
if (stop_reason == eStopReasonBreakpoint) {
ProcessSP process_sp(m_thread.CalculateProcess());
@@ -364,15 +364,13 @@ bool ThreadPlanCallFunction::DoPlanExplainsStop(Event *event_ptr) {
// should be propagated up the stack.
return false;
} else {
- // If the subplan is running, any crashes are attributable to us.
- // If we want to discard the plan, then we say we explain the stop
- // but if we are going to be discarded, let whoever is above us
- // explain the stop.
- // But don't discard the plan if the stop would restart itself (for instance
- // if it is a
- // signal that is set not to stop. Check that here first. We just say we
- // explain the stop
- // but aren't done and everything will continue on from there.
+ // If the subplan is running, any crashes are attributable to us. If we
+ // want to discard the plan, then we say we explain the stop but if we are
+ // going to be discarded, let whoever is above us explain the stop. But
+ // don't discard the plan if the stop would restart itself (for instance if
+ // it is a signal that is set not to stop. Check that here first. We just
+ // say we explain the stop but aren't done and everything will continue on
+ // from there.
if (m_real_stop_info_sp &&
m_real_stop_info_sp->ShouldStopSynchronous(event_ptr)) {
@@ -385,8 +383,8 @@ bool ThreadPlanCallFunction::DoPlanExplainsStop(Event *event_ptr) {
bool ThreadPlanCallFunction::ShouldStop(Event *event_ptr) {
// We do some computation in DoPlanExplainsStop that may or may not set the
- // plan as complete.
- // We need to do that here to make sure our state is correct.
+ // plan as complete. We need to do that here to make sure our state is
+ // correct.
DoPlanExplainsStop(event_ptr);
if (IsPlanComplete()) {
@@ -405,9 +403,8 @@ void ThreadPlanCallFunction::DidPush() {
//#define SINGLE_STEP_EXPRESSIONS
// Now set the thread state to "no reason" so we don't run with whatever
- // signal was outstanding...
- // Wait till the plan is pushed so we aren't changing the stop info till we're
- // about to run.
+ // signal was outstanding... Wait till the plan is pushed so we aren't
+ // changing the stop info till we're about to run.
GetThread().SetStopInfoToNothing();
@@ -483,10 +480,9 @@ bool ThreadPlanCallFunction::BreakpointsExplainStop() {
SetPlanComplete(false);
- // If the user has set the ObjC language breakpoint, it would normally get
- // priority over our internal
- // catcher breakpoint, but in this case we can't let that happen, so force
- // the ShouldStop here.
+ // If the user has set the ObjC language breakpoint, it would normally
+ // get priority over our internal catcher breakpoint, but in this case we
+ // can't let that happen, so force the ShouldStop here.
stop_info_sp->OverrideShouldStop(true);
return true;
}
diff --git a/source/Target/ThreadPlanCallOnFunctionExit.cpp b/source/Target/ThreadPlanCallOnFunctionExit.cpp
index 0dae98f03ef5..e8ea73f3c6a0 100644
--- a/source/Target/ThreadPlanCallOnFunctionExit.cpp
+++ b/source/Target/ThreadPlanCallOnFunctionExit.cpp
@@ -23,8 +23,8 @@ ThreadPlanCallOnFunctionExit::ThreadPlanCallOnFunctionExit(
}
void ThreadPlanCallOnFunctionExit::DidPush() {
- // We now want to queue the "step out" thread plan so it executes
- // and completes.
+ // We now want to queue the "step out" thread plan so it executes and
+ // completes.
// Set stop vote to eVoteNo.
m_step_out_threadplan_sp = GetThread().QueueThreadPlanForStepOut(
@@ -59,9 +59,9 @@ bool ThreadPlanCallOnFunctionExit::ValidatePlan(Stream *error) {
}
bool ThreadPlanCallOnFunctionExit::ShouldStop(Event *event_ptr) {
- // If this is where we find out that an internal stop came in, then:
- // Check if the step-out plan completed. If it did, then we want to
- // run the callback here (our reason for living...)
+ // If this is where we find out that an internal stop came in, then: Check if
+ // the step-out plan completed. If it did, then we want to run the callback
+ // here (our reason for living...)
if (m_step_out_threadplan_sp && m_step_out_threadplan_sp->IsPlanComplete()) {
m_callback();
@@ -71,8 +71,8 @@ bool ThreadPlanCallOnFunctionExit::ShouldStop(Event *event_ptr) {
// Indicate that this plan is done and can be discarded.
SetPlanComplete();
- // We're done now, but we want to return false so that we
- // don't cause the thread to really stop.
+ // We're done now, but we want to return false so that we don't cause the
+ // thread to really stop.
}
return false;
@@ -80,21 +80,20 @@ bool ThreadPlanCallOnFunctionExit::ShouldStop(Event *event_ptr) {
bool ThreadPlanCallOnFunctionExit::WillStop() {
// The code looks like the return value is ignored via ThreadList::
- // ShouldStop().
- // This is called when we really are going to stop. We don't care
- // and don't need to do anything here.
+ // ShouldStop(). This is called when we really are going to stop. We don't
+ // care and don't need to do anything here.
return false;
}
bool ThreadPlanCallOnFunctionExit::DoPlanExplainsStop(Event *event_ptr) {
- // We don't ever explain a stop. The only stop that is relevant
- // to us directly is the step_out plan we added to do the heavy lifting
- // of getting us past the current method.
+ // We don't ever explain a stop. The only stop that is relevant to us
+ // directly is the step_out plan we added to do the heavy lifting of getting
+ // us past the current method.
return false;
}
lldb::StateType ThreadPlanCallOnFunctionExit::GetPlanRunState() {
- // This value doesn't matter - we'll never be the top thread plan, so
- // nobody will ask us this question.
+ // This value doesn't matter - we'll never be the top thread plan, so nobody
+ // will ask us this question.
return eStateRunning;
}
diff --git a/source/Target/ThreadPlanCallUserExpression.cpp b/source/Target/ThreadPlanCallUserExpression.cpp
index 15cbd0baa9a6..7bf0dd39993e 100644
--- a/source/Target/ThreadPlanCallUserExpression.cpp
+++ b/source/Target/ThreadPlanCallUserExpression.cpp
@@ -44,8 +44,8 @@ ThreadPlanCallUserExpression::ThreadPlanCallUserExpression(
lldb::UserExpressionSP &user_expression_sp)
: ThreadPlanCallFunction(thread, function, CompilerType(), args, options),
m_user_expression_sp(user_expression_sp) {
- // User expressions are generally "User generated" so we should set them up to
- // stop when done.
+ // User expressions are generally "User generated" so we should set them up
+ // to stop when done.
SetIsMasterPlan(true);
SetOkayToDiscard(false);
}
diff --git a/source/Target/ThreadPlanPython.cpp b/source/Target/ThreadPlanPython.cpp
index af5c76518382..7796b8a0ab20 100644
--- a/source/Target/ThreadPlanPython.cpp
+++ b/source/Target/ThreadPlanPython.cpp
@@ -59,8 +59,7 @@ bool ThreadPlanPython::ValidatePlan(Stream *error) {
void ThreadPlanPython::DidPush() {
// We set up the script side in DidPush, so that it can push other plans in
- // the constructor,
- // and doesn't have to care about the details of DidPush.
+ // the constructor, and doesn't have to care about the details of DidPush.
if (!m_class_name.empty()) {
ScriptInterpreter *script_interp = m_thread.GetProcess()
diff --git a/source/Target/ThreadPlanRunToAddress.cpp b/source/Target/ThreadPlanRunToAddress.cpp
index 44de724b608c..6d1a8b5c27ff 100644
--- a/source/Target/ThreadPlanRunToAddress.cpp
+++ b/source/Target/ThreadPlanRunToAddress.cpp
@@ -133,8 +133,7 @@ void ThreadPlanRunToAddress::GetDescription(Stream *s,
}
bool ThreadPlanRunToAddress::ValidatePlan(Stream *error) {
- // If we couldn't set the breakpoint for some reason, then this won't
- // work.
+ // If we couldn't set the breakpoint for some reason, then this won't work.
bool all_bps_good = true;
size_t num_break_ids = m_break_ids.size();
diff --git a/source/Target/ThreadPlanShouldStopHere.cpp b/source/Target/ThreadPlanShouldStopHere.cpp
index 42aaa4227cf9..c7afe0d9a8a7 100644
--- a/source/Target/ThreadPlanShouldStopHere.cpp
+++ b/source/Target/ThreadPlanShouldStopHere.cpp
@@ -86,8 +86,8 @@ bool ThreadPlanShouldStopHere::DefaultShouldStopHereCallback(
// Always avoid code with line number 0.
// FIXME: At present the ShouldStop and the StepFromHere calculate this
// independently. If this ever
- // becomes expensive (this one isn't) we can try to have this set a state that
- // the StepFromHere can use.
+ // becomes expensive (this one isn't) we can try to have this set a state
+ // that the StepFromHere can use.
if (frame) {
SymbolContext sc;
sc = frame->GetSymbolContext(eSymbolContextLineEntry);
@@ -104,9 +104,8 @@ ThreadPlanSP ThreadPlanShouldStopHere::DefaultStepFromHereCallback(
const bool stop_others = false;
const size_t frame_index = 0;
ThreadPlanSP return_plan_sp;
- // If we are stepping through code at line number 0, then we need to step over
- // this range. Otherwise
- // we will step out.
+ // If we are stepping through code at line number 0, then we need to step
+ // over this range. Otherwise we will step out.
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get();
@@ -119,8 +118,7 @@ ThreadPlanSP ThreadPlanShouldStopHere::DefaultStepFromHereCallback(
AddressRange range = sc.line_entry.range;
// If the whole function is marked line 0 just step out, that's easier &
- // faster than continuing
- // to step through it.
+ // faster than continuing to step through it.
bool just_step_out = false;
if (sc.symbol && sc.symbol->ValueIsAddress()) {
Address symbol_end = sc.symbol->GetAddress();
diff --git a/source/Target/ThreadPlanStepInRange.cpp b/source/Target/ThreadPlanStepInRange.cpp
index 6c5a9954f23f..6405c135a33e 100644
--- a/source/Target/ThreadPlanStepInRange.cpp
+++ b/source/Target/ThreadPlanStepInRange.cpp
@@ -12,11 +12,13 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Target/ThreadPlanStepInRange.h"
+#include "lldb/Core/Architecture.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlanStepOut.h"
@@ -33,8 +35,7 @@ uint32_t ThreadPlanStepInRange::s_default_flag_values =
//----------------------------------------------------------------------
// ThreadPlanStepInRange: Step through a stack range, either stepping over or
-// into
-// based on the value of \a type.
+// into based on the value of \a type.
//----------------------------------------------------------------------
ThreadPlanStepInRange::ThreadPlanStepInRange(
@@ -162,15 +163,14 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) {
if (m_virtual_step) {
// If we've just completed a virtual step, all we need to do is check for a
- // ShouldStopHere plan, and otherwise
- // we're done.
+ // ShouldStopHere plan, and otherwise we're done.
// FIXME - This can be both a step in and a step out. Probably should
// record which in the m_virtual_step.
m_sub_plan_sp = CheckShouldStopHereAndQueueStepOut(eFrameCompareYounger);
} else {
// Stepping through should be done running other threads in general, since
- // we're setting a breakpoint and
- // continuing. So only stop others if we are explicitly told to do so.
+ // we're setting a breakpoint and continuing. So only stop others if we
+ // are explicitly told to do so.
bool stop_others = (m_stop_others == lldb::eOnlyThisThread);
@@ -183,9 +183,8 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) {
// A caveat to this is if we think the frame is older but we're actually
// in a trampoline.
// I'm going to make the assumption that you wouldn't RETURN to a
- // trampoline. So if we are
- // in a trampoline we think the frame is older because the trampoline
- // confused the backtracer.
+ // trampoline. So if we are in a trampoline we think the frame is older
+ // because the trampoline confused the backtracer.
m_sub_plan_sp = m_thread.QueueThreadPlanForStepThrough(m_stack_id, false,
stop_others);
if (!m_sub_plan_sp) {
@@ -202,19 +201,15 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) {
"Thought I stepped out, but in fact arrived at a trampoline.");
}
} else if (frame_order == eFrameCompareEqual && InSymbol()) {
- // If we are not in a place we should step through, we're done.
- // One tricky bit here is that some stubs don't push a frame, so we have
- // to check
- // both the case of a frame that is younger, or the same as this frame.
- // However, if the frame is the same, and we are still in the symbol we
- // started
- // in, the we don't need to do this. This first check isn't strictly
- // necessary,
- // but it is more efficient.
+ // If we are not in a place we should step through, we're done. One
+ // tricky bit here is that some stubs don't push a frame, so we have to
+ // check both the case of a frame that is younger, or the same as this
+ // frame. However, if the frame is the same, and we are still in the
+ // symbol we started in, the we don't need to do this. This first check
+ // isn't strictly necessary, but it is more efficient.
// If we're still in the range, keep going, either by running to the next
- // branch breakpoint, or by
- // stepping.
+ // branch breakpoint, or by stepping.
if (InRange()) {
SetNextBranchBreakpoint();
return false;
@@ -242,15 +237,13 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) {
log->Printf("No step through plan found.");
}
- // If not, give the "should_stop" callback a chance to push a plan to get us
- // out of here.
- // But only do that if we actually have stepped in.
+ // If not, give the "should_stop" callback a chance to push a plan to get
+ // us out of here. But only do that if we actually have stepped in.
if (!m_sub_plan_sp && frame_order == eFrameCompareYounger)
m_sub_plan_sp = CheckShouldStopHereAndQueueStepOut(frame_order);
// If we've stepped in and we are going to stop here, check to see if we
- // were asked to
- // run past the prologue, and if so do that.
+ // were asked to run past the prologue, and if so do that.
if (!m_sub_plan_sp && frame_order == eFrameCompareYounger &&
m_step_past_prologue) {
@@ -277,6 +270,17 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) {
bytes_to_skip = sc.symbol->GetPrologueByteSize();
}
+ if (bytes_to_skip == 0 && sc.symbol) {
+ TargetSP target = m_thread.CalculateTarget();
+ const Architecture *arch = target->GetArchitecturePlugin();
+ if (arch) {
+ Address curr_sec_addr;
+ target->GetSectionLoadList().ResolveLoadAddress(curr_addr,
+ curr_sec_addr);
+ bytes_to_skip = arch->GetBytesToSkip(*sc.symbol, curr_sec_addr);
+ }
+ }
+
if (bytes_to_skip != 0) {
func_start_address.Slide(bytes_to_skip);
log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP);
@@ -400,8 +404,8 @@ bool ThreadPlanStepInRange::DefaultShouldStopHereCallback(
SymbolContext sc = frame->GetSymbolContext(
eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol);
if (sc.symbol != nullptr) {
- // First try an exact match, since that's cheap with ConstStrings. Then
- // do a strstr compare.
+ // First try an exact match, since that's cheap with ConstStrings.
+ // Then do a strstr compare.
if (step_in_range_plan->m_step_into_target == sc.GetFunctionName()) {
should_stop_here = true;
} else {
@@ -436,25 +440,19 @@ bool ThreadPlanStepInRange::DefaultShouldStopHereCallback(
bool ThreadPlanStepInRange::DoPlanExplainsStop(Event *event_ptr) {
// We always explain a stop. Either we've just done a single step, in which
- // case we'll do our ordinary processing, or we stopped for some
- // reason that isn't handled by our sub-plans, in which case we want to just
- // stop right
- // away.
- // In general, we don't want to mark the plan as complete for unexplained
- // stops.
- // For instance, if you step in to some code with no debug info, so you step
- // out
- // and in the course of that hit a breakpoint, then you want to stop & show
- // the user
- // the breakpoint, but not unship the step in plan, since you still may want
- // to complete that
- // plan when you continue. This is particularly true when doing "step in to
- // target function."
+ // case we'll do our ordinary processing, or we stopped for some reason that
+ // isn't handled by our sub-plans, in which case we want to just stop right
+ // away. In general, we don't want to mark the plan as complete for
+ // unexplained stops. For instance, if you step in to some code with no debug
+ // info, so you step out and in the course of that hit a breakpoint, then you
+ // want to stop & show the user the breakpoint, but not unship the step in
+ // plan, since you still may want to complete that plan when you continue.
+ // This is particularly true when doing "step in to target function."
// stepping.
//
- // The only variation is that if we are doing "step by running to next branch"
- // in which case
- // if we hit our branch breakpoint we don't set the plan to complete.
+ // The only variation is that if we are doing "step by running to next
+ // branch" in which case if we hit our branch breakpoint we don't set the
+ // plan to complete.
bool return_value = false;
diff --git a/source/Target/ThreadPlanStepInstruction.cpp b/source/Target/ThreadPlanStepInstruction.cpp
index ca45960e1ed5..dd8f129a935b 100644
--- a/source/Target/ThreadPlanStepInstruction.cpp
+++ b/source/Target/ThreadPlanStepInstruction.cpp
@@ -76,8 +76,8 @@ void ThreadPlanStepInstruction::GetDescription(Stream *s,
}
bool ThreadPlanStepInstruction::ValidatePlan(Stream *error) {
- // Since we read the instruction we're stepping over from the thread,
- // this plan will always work.
+ // Since we read the instruction we're stepping over from the thread, this
+ // plan will always work.
return true;
}
@@ -106,8 +106,8 @@ bool ThreadPlanStepInstruction::IsPlanStale() {
return (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr);
} else if (cur_frame_id < m_stack_id) {
// If the current frame is younger than the start frame and we are stepping
- // over, then we need to continue,
- // but if we are doing just one step, we're done.
+ // over, then we need to continue, but if we are doing just one step, we're
+ // done.
return !m_step_over;
} else {
if (log) {
@@ -140,8 +140,7 @@ bool ThreadPlanStepInstruction::ShouldStop(Event *event_ptr) {
return true;
} else {
// We are still stepping, reset the start pc, and in case we've
- // stepped out,
- // reset the current stack id.
+ // stepped out, reset the current stack id.
SetUpState();
return false;
}
@@ -154,9 +153,8 @@ bool ThreadPlanStepInstruction::ShouldStop(Event *event_ptr) {
if (return_frame->GetStackID() != m_parent_frame_id ||
m_start_has_symbol) {
// next-instruction shouldn't step out of inlined functions. But we
- // may have stepped into a
- // real function that starts with an inlined function, and we do want
- // to step out of that...
+ // may have stepped into a real function that starts with an inlined
+ // function, and we do want to step out of that...
if (cur_frame_sp->IsInlined()) {
StackFrameSP parent_frame_sp =
@@ -190,9 +188,8 @@ bool ThreadPlanStepInstruction::ShouldStop(Event *event_ptr) {
log->Printf("%s.", s.GetData());
}
- // StepInstruction should probably have the tri-state RunMode, but for
- // now it is safer to
- // run others.
+ // StepInstruction should probably have the tri-state RunMode, but
+ // for now it is safer to run others.
const bool stop_others = false;
m_thread.QueueThreadPlanForStepOutNoShouldStop(
false, nullptr, true, stop_others, eVoteNo, eVoteNoOpinion, 0);
@@ -222,8 +219,7 @@ bool ThreadPlanStepInstruction::ShouldStop(Event *event_ptr) {
return true;
} else {
// We are still stepping, reset the start pc, and in case we've stepped
- // in or out,
- // reset the current stack id.
+ // in or out, reset the current stack id.
SetUpState();
return false;
}
diff --git a/source/Target/ThreadPlanStepOut.cpp b/source/Target/ThreadPlanStepOut.cpp
index 6b6ed06e9b37..f2db6e4b6f42 100644
--- a/source/Target/ThreadPlanStepOut.cpp
+++ b/source/Target/ThreadPlanStepOut.cpp
@@ -63,17 +63,14 @@ ThreadPlanStepOut::ThreadPlanStepOut(
m_step_out_to_id = return_frame_sp->GetStackID();
m_immediate_step_from_id = immediate_return_from_sp->GetStackID();
- // If the frame directly below the one we are returning to is inlined, we have
- // to be
- // a little more careful. It is non-trivial to determine the real "return
- // code address" for
- // an inlined frame, so we have to work our way to that frame and then step
- // out.
+ // If the frame directly below the one we are returning to is inlined, we
+ // have to be a little more careful. It is non-trivial to determine the real
+ // "return code address" for an inlined frame, so we have to work our way to
+ // that frame and then step out.
if (immediate_return_from_sp && immediate_return_from_sp->IsInlined()) {
if (frame_idx > 0) {
// First queue a plan that gets us to this inlined frame, and when we get
- // there we'll queue a second
- // plan that walks us out of this frame.
+ // there we'll queue a second plan that walks us out of this frame.
m_step_out_to_inline_plan_sp.reset(new ThreadPlanStepOut(
m_thread, nullptr, false, stop_others, eVoteNoOpinion, eVoteNoOpinion,
frame_idx - 1, eLazyBoolNo, continue_to_next_branch));
@@ -81,8 +78,8 @@ ThreadPlanStepOut::ThreadPlanStepOut(
->SetShouldStopHereCallbacks(nullptr, nullptr);
m_step_out_to_inline_plan_sp->SetPrivate(true);
} else {
- // If we're already at the inlined frame we're stepping through, then just
- // do that now.
+ // If we're already at the inlined frame we're stepping through, then
+ // just do that now.
QueueInlinedStepPlan(false);
}
} else if (return_frame_sp) {
@@ -217,8 +214,8 @@ bool ThreadPlanStepOut::ValidatePlan(Stream *error) {
}
bool ThreadPlanStepOut::DoPlanExplainsStop(Event *event_ptr) {
- // If the step out plan is done, then we just need to step through the inlined
- // frame.
+ // If the step out plan is done, then we just need to step through the
+ // inlined frame.
if (m_step_out_to_inline_plan_sp) {
return m_step_out_to_inline_plan_sp->MischiefManaged();
} else if (m_step_through_inline_plan_sp) {
@@ -233,15 +230,14 @@ bool ThreadPlanStepOut::DoPlanExplainsStop(Event *event_ptr) {
}
// We don't explain signals or breakpoints (breakpoints that handle stepping
- // in or
- // out will be handled by a child plan.
+ // in or out will be handled by a child plan.
StopInfoSP stop_info_sp = GetPrivateStopInfo();
if (stop_info_sp) {
StopReason reason = stop_info_sp->GetStopReason();
if (reason == eStopReasonBreakpoint) {
- // If this is OUR breakpoint, we're fine, otherwise we don't know why this
- // happened...
+ // If this is OUR breakpoint, we're fine, otherwise we don't know why
+ // this happened...
BreakpointSiteSP site_sp(
m_thread.GetProcess()->GetBreakpointSiteList().FindByID(
stop_info_sp->GetValue()));
@@ -268,11 +264,10 @@ bool ThreadPlanStepOut::DoPlanExplainsStop(Event *event_ptr) {
}
// If there was only one owner, then we're done. But if we also hit
- // some
- // user breakpoint on our way out, we should mark ourselves as done, but
- // also not claim to explain the stop, since it is more important to
- // report
- // the user breakpoint than the step out completion.
+ // some user breakpoint on our way out, we should mark ourselves as
+ // done, but also not claim to explain the stop, since it is more
+ // important to report the user breakpoint than the step out
+ // completion.
if (site_sp->GetNumberOfOwners() == 1)
return true;
@@ -320,9 +315,8 @@ bool ThreadPlanStepOut::ShouldStop(Event *event_ptr) {
done = !(frame_zero_id < m_step_out_to_id);
}
- // The normal step out computations think we are done, so all we need to do is
- // consult the ShouldStopHere,
- // and we are done.
+ // The normal step out computations think we are done, so all we need to do
+ // is consult the ShouldStopHere, and we are done.
if (done) {
if (InvokeShouldStopHereCallback(eFrameCompareOlder)) {
@@ -377,8 +371,7 @@ bool ThreadPlanStepOut::MischiefManaged() {
// I also check the stack depth, since if we've blown past the breakpoint
// for some
// reason and we're now stopping for some other reason altogether, then
- // we're done
- // with this step out operation.
+ // we're done with this step out operation.
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (log)
@@ -397,10 +390,8 @@ bool ThreadPlanStepOut::MischiefManaged() {
bool ThreadPlanStepOut::QueueInlinedStepPlan(bool queue_now) {
// Now figure out the range of this inlined block, and set up a "step through
- // range"
- // plan for that. If we've been provided with a context, then use the block
- // in that
- // context.
+ // range" plan for that. If we've been provided with a context, then use the
+ // block in that context.
StackFrameSP immediate_return_from_sp(m_thread.GetStackFrameAtIndex(0));
if (!immediate_return_from_sp)
return false;
@@ -477,8 +468,8 @@ void ThreadPlanStepOut::CalculateReturnValue() {
}
bool ThreadPlanStepOut::IsPlanStale() {
- // If we are still lower on the stack than the frame we are returning to, then
- // there's something for us to do. Otherwise, we're stale.
+ // If we are still lower on the stack than the frame we are returning to,
+ // then there's something for us to do. Otherwise, we're stale.
StackID frame_zero_id = m_thread.GetStackFrameAtIndex(0)->GetStackID();
return !(frame_zero_id < m_step_out_to_id);
diff --git a/source/Target/ThreadPlanStepOverBreakpoint.cpp b/source/Target/ThreadPlanStepOverBreakpoint.cpp
index 3896a0b24714..7497dbff1729 100644
--- a/source/Target/ThreadPlanStepOverBreakpoint.cpp
+++ b/source/Target/ThreadPlanStepOverBreakpoint.cpp
@@ -31,8 +31,8 @@ ThreadPlanStepOverBreakpoint::ThreadPlanStepOverBreakpoint(Thread &thread)
ThreadPlan::eKindStepOverBreakpoint, "Step over breakpoint trap",
thread, eVoteNo,
eVoteNoOpinion), // We need to report the run since this happens
- // first in the thread plan stack when stepping
- // over a breakpoint
+ // first in the thread plan stack when stepping over
+ // a breakpoint
m_breakpoint_addr(LLDB_INVALID_ADDRESS),
m_auto_continue(false), m_reenabled_breakpoint_site(false)
@@ -57,42 +57,58 @@ bool ThreadPlanStepOverBreakpoint::DoPlanExplainsStop(Event *event_ptr) {
StopInfoSP stop_info_sp = GetPrivateStopInfo();
if (stop_info_sp) {
// It's a little surprising that we stop here for a breakpoint hit.
- // However, when you single step ONTO a breakpoint
- // we still want to call that a breakpoint hit, and trigger the actions,
- // etc. Otherwise you would see the
+ // However, when you single step ONTO a breakpoint we still want to call
+ // that a breakpoint hit, and trigger the actions, etc. Otherwise you
+ // would see the
// PC at the breakpoint without having triggered the actions, then you'd
// continue, the PC wouldn't change,
- // and you'd see the breakpoint hit, which would be odd.
- // So the lower levels fake "step onto breakpoint address" and return that
- // as a breakpoint. So our trace
- // step COULD appear as a breakpoint hit if the next instruction also
- // contained a breakpoint.
+ // and you'd see the breakpoint hit, which would be odd. So the lower
+ // levels fake "step onto breakpoint address" and return that as a
+ // breakpoint. So our trace step COULD appear as a breakpoint hit if the
+ // next instruction also contained a breakpoint.
StopReason reason = stop_info_sp->GetStopReason();
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+
+ if (log)
+ log->Printf("Step over breakpoint stopped for reason: %s.",
+ Thread::StopReasonAsCString(reason));
+
switch (reason) {
- case eStopReasonTrace:
- case eStopReasonNone:
- return true;
- case eStopReasonBreakpoint:
- // It's a little surprising that we stop here for a breakpoint hit.
- // However, when you single step ONTO a
- // breakpoint we still want to call that a breakpoint hit, and trigger the
- // actions, etc. Otherwise you
- // would see the PC at the breakpoint without having triggered the
- // actions, then you'd continue, the PC
- // wouldn't change, and you'd see the breakpoint hit, which would be odd.
- // So the lower levels fake "step onto breakpoint address" and return that
- // as a breakpoint hit. So our trace
- // step COULD appear as a breakpoint hit if the next instruction also
- // contained a breakpoint. We don't want
- // to handle that, since we really don't know what to do with breakpoint
- // hits. But make sure we don't set
- // ourselves to auto-continue or we'll wrench control away from the plans
- // that can deal with this.
- SetAutoContinue(false);
- return false;
- default:
- return false;
+ case eStopReasonTrace:
+ case eStopReasonNone:
+ return true;
+ case eStopReasonBreakpoint:
+ {
+ // It's a little surprising that we stop here for a breakpoint hit.
+ // However, when you single step ONTO a breakpoint we still want to call
+ // that a breakpoint hit, and trigger the actions, etc. Otherwise you
+ // would see the PC at the breakpoint without having triggered the
+ // actions, then you'd continue, the PC wouldn't change, and you'd see
+ // the breakpoint hit, which would be odd. So the lower levels fake
+ // "step onto breakpoint address" and return that as a breakpoint hit.
+ // So our trace step COULD appear as a breakpoint hit if the next
+ // instruction also contained a breakpoint. We don't want to handle
+ // that, since we really don't know what to do with breakpoint hits.
+ // But make sure we don't set ourselves to auto-continue or we'll wrench
+ // control away from the plans that can deal with this.
+ // Be careful, however, as we may have "seen a breakpoint under the PC
+ // because we stopped without changing the PC, in which case we do want
+ // to re-claim this stop so we'll try again.
+ lldb::addr_t pc_addr = m_thread.GetRegisterContext()->GetPC();
+
+ if (pc_addr == m_breakpoint_addr) {
+ if (log)
+ log->Printf("Got breakpoint stop reason but pc: 0x%" PRIx64
+ "hasn't changed.", pc_addr);
+ return true;
+ }
+
+ SetAutoContinue(false);
+ return false;
+ }
+ default:
+ return false;
}
}
return false;
@@ -114,8 +130,10 @@ bool ThreadPlanStepOverBreakpoint::DoWillResume(StateType resume_state,
BreakpointSiteSP bp_site_sp(
m_thread.GetProcess()->GetBreakpointSiteList().FindByAddress(
m_breakpoint_addr));
- if (bp_site_sp && bp_site_sp->IsEnabled())
+ if (bp_site_sp && bp_site_sp->IsEnabled()) {
m_thread.GetProcess()->DisableBreakpointSite(bp_site_sp.get());
+ m_reenabled_breakpoint_site = false;
+ }
}
return true;
}
@@ -125,13 +143,16 @@ bool ThreadPlanStepOverBreakpoint::WillStop() {
return true;
}
+void ThreadPlanStepOverBreakpoint::WillPop() {
+ ReenableBreakpointSite();
+}
+
bool ThreadPlanStepOverBreakpoint::MischiefManaged() {
lldb::addr_t pc_addr = m_thread.GetRegisterContext()->GetPC();
if (pc_addr == m_breakpoint_addr) {
// If we are still at the PC of our breakpoint, then for some reason we
- // didn't
- // get a chance to run.
+ // didn't get a chance to run.
return false;
} else {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
diff --git a/source/Target/ThreadPlanStepOverRange.cpp b/source/Target/ThreadPlanStepOverRange.cpp
index d5778fb5e8d7..b88d25b707eb 100644
--- a/source/Target/ThreadPlanStepOverRange.cpp
+++ b/source/Target/ThreadPlanStepOverRange.cpp
@@ -32,8 +32,7 @@ uint32_t ThreadPlanStepOverRange::s_default_flag_values = 0;
//----------------------------------------------------------------------
// ThreadPlanStepOverRange: Step through a stack range, either stepping over or
-// into
-// based on the value of \a type.
+// into based on the value of \a type.
//----------------------------------------------------------------------
ThreadPlanStepOverRange::ThreadPlanStepOverRange(
@@ -91,21 +90,17 @@ void ThreadPlanStepOverRange::SetupAvoidNoDebug(
else
GetFlags().Clear(ThreadPlanShouldStopHere::eStepOutAvoidNoDebug);
// Step Over plans should always avoid no-debug on step in. Seems like you
- // shouldn't
- // have to say this, but a tail call looks more like a step in that a step
- // out, so
- // we want to catch this case.
+ // shouldn't have to say this, but a tail call looks more like a step in that
+ // a step out, so we want to catch this case.
GetFlags().Set(ThreadPlanShouldStopHere::eStepInAvoidNoDebug);
}
bool ThreadPlanStepOverRange::IsEquivalentContext(
const SymbolContext &context) {
- // Match as much as is specified in the m_addr_context:
- // This is a fairly loose sanity check. Note, sometimes the target doesn't
- // get filled
- // in so I left out the target check. And sometimes the module comes in as
- // the .o file from the
- // inlined range, so I left that out too...
+ // Match as much as is specified in the m_addr_context: This is a fairly
+ // loose sanity check. Note, sometimes the target doesn't get filled in so I
+ // left out the target check. And sometimes the module comes in as the .o
+ // file from the inlined range, so I left that out too...
if (m_addr_context.comp_unit) {
if (m_addr_context.comp_unit != context.comp_unit)
return false;
@@ -113,8 +108,8 @@ bool ThreadPlanStepOverRange::IsEquivalentContext(
if (m_addr_context.function != context.function)
return false;
// It is okay to return to a different block of a straight function, we
- // only have to
- // be more careful if returning from one inlined block to another.
+ // only have to be more careful if returning from one inlined block to
+ // another.
if (m_addr_context.block->GetInlinedFunctionInfo() == nullptr &&
context.block->GetInlinedFunctionInfo() == nullptr)
return true;
@@ -140,8 +135,8 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) {
}
// If we're out of the range but in the same frame or in our caller's frame
- // then we should stop.
- // When stepping out we only stop others if we are forcing running one thread.
+ // then we should stop. When stepping out we only stop others if we are
+ // forcing running one thread.
bool stop_others = (m_stop_others == lldb::eOnlyThisThread);
ThreadPlanSP new_plan_sp;
FrameComparison frame_order = CompareCurrentFrameToStartFrame();
@@ -152,11 +147,9 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) {
// A caveat to this is if we think the frame is older but we're actually in
// a trampoline.
// I'm going to make the assumption that you wouldn't RETURN to a
- // trampoline. So if we are
- // in a trampoline we think the frame is older because the trampoline
- // confused the backtracer.
- // As below, we step through first, and then try to figure out how to get
- // back out again.
+ // trampoline. So if we are in a trampoline we think the frame is older
+ // because the trampoline confused the backtracer. As below, we step
+ // through first, and then try to figure out how to get back out again.
new_plan_sp =
m_thread.QueueThreadPlanForStepThrough(m_stack_id, false, stop_others);
@@ -166,8 +159,7 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) {
"Thought I stepped out, but in fact arrived at a trampoline.");
} else if (frame_order == eFrameCompareYounger) {
// Make sure we really are in a new frame. Do that by unwinding and seeing
- // if the
- // start function really is our start function...
+ // if the start function really is our start function...
for (uint32_t i = 1;; ++i) {
StackFrameSP older_frame_sp = m_thread.GetStackFrameAtIndex(i);
if (!older_frame_sp) {
@@ -200,28 +192,23 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) {
if (!InSymbol()) {
// This one is a little tricky. Sometimes we may be in a stub or
- // something similar,
- // in which case we need to get out of there. But if we are in a stub
- // then it's
- // likely going to be hard to get out from here. It is probably easiest
- // to step into the
- // stub, and then it will be straight-forward to step out.
+ // something similar, in which case we need to get out of there. But if
+ // we are in a stub then it's likely going to be hard to get out from
+ // here. It is probably easiest to step into the stub, and then it will
+ // be straight-forward to step out.
new_plan_sp = m_thread.QueueThreadPlanForStepThrough(m_stack_id, false,
stop_others);
} else {
- // The current clang (at least through 424) doesn't always get the address
- // range for the
- // DW_TAG_inlined_subroutines right, so that when you leave the inlined
- // range the line table says
- // you are still in the source file of the inlining function. This is
- // bad, because now you are missing
- // the stack frame for the function containing the inlining, and if you
- // sensibly do "finish" to get
- // out of this function you will instead exit the containing function.
- // To work around this, we check whether we are still in the source file
- // we started in, and if not assume
- // it is an error, and push a plan to get us out of this line and back to
- // the containing file.
+ // The current clang (at least through 424) doesn't always get the
+ // address range for the DW_TAG_inlined_subroutines right, so that when
+ // you leave the inlined range the line table says you are still in the
+ // source file of the inlining function. This is bad, because now you
+ // are missing the stack frame for the function containing the inlining,
+ // and if you sensibly do "finish" to get out of this function you will
+ // instead exit the containing function. To work around this, we check
+ // whether we are still in the source file we started in, and if not
+ // assume it is an error, and push a plan to get us out of this line and
+ // back to the containing file.
if (m_addr_context.line_entry.IsValid()) {
SymbolContext sc;
@@ -244,14 +231,11 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) {
bool step_past_remaining_inline = false;
if (entry_idx > 0) {
// We require the previous line entry and the current line
- // entry come
- // from the same file.
- // The other requirement is that the previous line table entry
- // be part of an
- // inlined block, we don't want to step past cases where
- // people have inlined
- // some code fragment by using #include <source-fragment.c>
- // directly.
+ // entry come from the same file. The other requirement is
+ // that the previous line table entry be part of an inlined
+ // block, we don't want to step past cases where people have
+ // inlined some code fragment by using #include <source-
+ // fragment.c> directly.
LineEntry prev_line_entry;
if (line_table->GetLineEntryAtIndex(entry_idx - 1,
prev_line_entry) &&
@@ -338,8 +322,7 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) {
if (!new_plan_sp) {
// For efficiencies sake, we know we're done here so we don't have to do
- // this
- // calculation again in MischiefManaged.
+ // this calculation again in MischiefManaged.
SetPlanComplete();
return true;
} else
@@ -347,16 +330,12 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) {
}
bool ThreadPlanStepOverRange::DoPlanExplainsStop(Event *event_ptr) {
- // For crashes, breakpoint hits, signals, etc, let the base plan (or some plan
- // above us)
- // handle the stop. That way the user can see the stop, step around, and then
- // when they
- // are done, continue and have their step complete. The exception is if we've
- // hit our
- // "run to next branch" breakpoint.
- // Note, unlike the step in range plan, we don't mark ourselves complete if we
- // hit an
- // unexplained breakpoint/crash.
+ // For crashes, breakpoint hits, signals, etc, let the base plan (or some
+ // plan above us) handle the stop. That way the user can see the stop, step
+ // around, and then when they are done, continue and have their step
+ // complete. The exception is if we've hit our "run to next branch"
+ // breakpoint. Note, unlike the step in range plan, we don't mark ourselves
+ // complete if we hit an unexplained breakpoint/crash.
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
StopInfoSP stop_info_sp = GetPrivateStopInfo();
@@ -387,8 +366,8 @@ bool ThreadPlanStepOverRange::DoWillResume(lldb::StateType resume_state,
m_first_resume = false;
if (resume_state == eStateStepping && current_plan) {
// See if we are about to step over an inlined call in the middle of the
- // inlined stack, if so figure
- // out its extents and reset our range to step over that.
+ // inlined stack, if so figure out its extents and reset our range to
+ // step over that.
bool in_inlined_stack = m_thread.DecrementCurrentInlinedDepth();
if (in_inlined_stack) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
diff --git a/source/Target/ThreadPlanStepRange.cpp b/source/Target/ThreadPlanStepRange.cpp
index 09e606f490a6..5a71119015eb 100644
--- a/source/Target/ThreadPlanStepRange.cpp
+++ b/source/Target/ThreadPlanStepRange.cpp
@@ -31,8 +31,8 @@ using namespace lldb;
using namespace lldb_private;
//----------------------------------------------------------------------
-// ThreadPlanStepRange: Step through a stack range, either stepping over or into
-// based on the value of \a type.
+// ThreadPlanStepRange: Step through a stack range, either stepping over or
+// into based on the value of \a type.
//----------------------------------------------------------------------
ThreadPlanStepRange::ThreadPlanStepRange(ThreadPlanKind kind, const char *name,
@@ -74,15 +74,14 @@ Vote ThreadPlanStepRange::ShouldReportStop(Event *event_ptr) {
}
void ThreadPlanStepRange::AddRange(const AddressRange &new_range) {
- // For now I'm just adding the ranges. At some point we may want to
- // condense the ranges if they overlap, though I don't think it is likely
- // to be very important.
+ // For now I'm just adding the ranges. At some point we may want to condense
+ // the ranges if they overlap, though I don't think it is likely to be very
+ // important.
m_address_ranges.push_back(new_range);
// Fill the slot for this address range with an empty DisassemblerSP in the
- // instruction ranges. I want the
- // indices to match, but I don't want to do the work to disassemble this range
- // if I don't step into it.
+ // instruction ranges. I want the indices to match, but I don't want to do
+ // the work to disassemble this range if I don't step into it.
m_instruction_ranges.push_back(DisassemblerSP());
}
@@ -158,12 +157,11 @@ bool ThreadPlanStepRange::InRange() {
} else if (new_context.line_entry.range.GetBaseAddress().GetLoadAddress(
m_thread.CalculateTarget().get()) != pc_load_addr) {
// Another thing that sometimes happens here is that we step out of
- // one line into the MIDDLE of another
- // line. So far I mostly see this due to bugs in the debug
- // information.
- // But we probably don't want to be in the middle of a line range, so
- // in that case reset the stepping
- // range to the line we've stepped into the middle of and continue.
+ // one line into the MIDDLE of another line. So far I mostly see
+ // this due to bugs in the debug information. But we probably don't
+ // want to be in the middle of a line range, so in that case reset
+ // the stepping range to the line we've stepped into the middle of
+ // and continue.
m_addr_context = new_context;
m_address_ranges.clear();
AddRange(m_addr_context.line_entry.range);
@@ -260,9 +258,8 @@ InstructionList *ThreadPlanStepRange::GetInstructionsForAddress(
return nullptr;
else {
// Find where we are in the instruction list as well. If we aren't at
- // an instruction,
- // return nullptr. In this case, we're probably lost, and shouldn't try
- // to do anything fancy.
+ // an instruction, return nullptr. In this case, we're probably lost,
+ // and shouldn't try to do anything fancy.
insn_offset =
m_instruction_ranges[i]
@@ -297,8 +294,7 @@ bool ThreadPlanStepRange::SetNextBranchBreakpoint() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
// Stepping through ranges using breakpoints doesn't work yet, but with this
- // off we fall back to instruction
- // single stepping.
+ // off we fall back to instruction single stepping.
if (!m_use_fast_step)
return false;
@@ -383,9 +379,8 @@ bool ThreadPlanStepRange::NextRangeBreakpointExplainsStop(
size_t num_owners = bp_site_sp->GetNumberOfOwners();
bool explains_stop = true;
// If all the owners are internal, then we are probably just stepping over
- // this range from multiple threads,
- // or multiple frames, so we want to continue. If one is not internal, then
- // we should not explain the stop,
+ // this range from multiple threads, or multiple frames, so we want to
+ // continue. If one is not internal, then we should not explain the stop,
// and let the user breakpoint handle the stop.
for (size_t i = 0; i < num_owners; i++) {
if (!bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().IsInternal()) {
@@ -418,8 +413,8 @@ bool ThreadPlanStepRange::MischiefManaged() {
// I do this check first because we might have stepped somewhere that will
// fool InRange into
// thinking it needs to step past the end of that line. This happens, for
- // instance, when stepping
- // over inlined code that is in the middle of the current line.
+ // instance, when stepping over inlined code that is in the middle of the
+ // current line.
if (!m_no_more_plans)
return false;
@@ -457,8 +452,8 @@ bool ThreadPlanStepRange::IsPlanStale() {
}
return true;
} else if (frame_order == eFrameCompareEqual && InSymbol()) {
- // If we are not in a place we should step through, we've gotten stale.
- // One tricky bit here is that some stubs don't push a frame, so we should.
+ // If we are not in a place we should step through, we've gotten stale. One
+ // tricky bit here is that some stubs don't push a frame, so we should.
// check that we are in the same symbol.
if (!InRange()) {
// Set plan Complete when we reach next instruction just after the range
diff --git a/source/Target/ThreadPlanStepThrough.cpp b/source/Target/ThreadPlanStepThrough.cpp
index 46aadb00f2ab..c039a32f5515 100644
--- a/source/Target/ThreadPlanStepThrough.cpp
+++ b/source/Target/ThreadPlanStepThrough.cpp
@@ -26,9 +26,8 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// ThreadPlanStepThrough: If the current instruction is a trampoline, step
-// through it
-// If it is the beginning of the prologue of a function, step through that as
-// well.
+// through it If it is the beginning of the prologue of a function, step
+// through that as well.
// FIXME: At present only handles DYLD trampolines.
//----------------------------------------------------------------------
@@ -49,9 +48,8 @@ ThreadPlanStepThrough::ThreadPlanStepThrough(Thread &thread,
m_start_address = GetThread().GetRegisterContext()->GetPC(0);
// We are going to return back to the concrete frame 1, we might pass by
- // some inlined code that we're in
- // the middle of by doing this, but it's easier than trying to figure out
- // where the inlined code might return to.
+ // some inlined code that we're in the middle of by doing this, but it's
+ // easier than trying to figure out where the inlined code might return to.
StackFrameSP return_frame_sp = m_thread.GetFrameWithStackID(m_stack_id);
@@ -136,10 +134,8 @@ bool ThreadPlanStepThrough::ValidatePlan(Stream *error) {
bool ThreadPlanStepThrough::DoPlanExplainsStop(Event *event_ptr) {
// If we have a sub-plan, it will have been asked first if we explain the
- // stop, and
- // we won't get asked. The only time we would be the one directly asked this
- // question
- // is if we hit our backstop breakpoint.
+ // stop, and we won't get asked. The only time we would be the one directly
+ // asked this question is if we hit our backstop breakpoint.
return HitOurBackstopBreakpoint();
}
@@ -156,8 +152,7 @@ bool ThreadPlanStepThrough::ShouldStop(Event *event_ptr) {
}
// If we don't have a sub-plan, then we're also done (can't see how we would
- // ever get here
- // without a plan, but just in case.
+ // ever get here without a plan, but just in case.
if (!m_sub_plan_sp) {
SetPlanComplete();
@@ -165,15 +160,13 @@ bool ThreadPlanStepThrough::ShouldStop(Event *event_ptr) {
}
// If the current sub plan is not done, we don't want to stop. Actually, we
- // probably won't
- // ever get here in this state, since we generally won't get asked any
- // questions if out
- // current sub-plan is not done...
+ // probably won't ever get here in this state, since we generally won't get
+ // asked any questions if out current sub-plan is not done...
if (!m_sub_plan_sp->IsPlanComplete())
return false;
- // If our current sub plan failed, then let's just run to our backstop. If we
- // can't do that then just stop.
+ // If our current sub plan failed, then let's just run to our backstop. If
+ // we can't do that then just stop.
if (!m_sub_plan_sp->PlanSucceeded()) {
if (m_backstop_bkpt_id != LLDB_INVALID_BREAK_ID) {
m_sub_plan_sp.reset();
@@ -185,8 +178,7 @@ bool ThreadPlanStepThrough::ShouldStop(Event *event_ptr) {
}
// Next see if there is a specific step through plan at our current pc (these
- // might
- // chain, for instance stepping through a dylib trampoline to the objc
+ // might chain, for instance stepping through a dylib trampoline to the objc
// dispatch function...)
LookForPlanToStepThroughFromCurrentPC();
if (m_sub_plan_sp) {
diff --git a/source/Target/ThreadPlanStepUntil.cpp b/source/Target/ThreadPlanStepUntil.cpp
index 01f5f948a28c..9984ee925c86 100644
--- a/source/Target/ThreadPlanStepUntil.cpp
+++ b/source/Target/ThreadPlanStepUntil.cpp
@@ -151,8 +151,8 @@ void ThreadPlanStepUntil::AnalyzeStop() {
StopReason reason = stop_info_sp->GetStopReason();
if (reason == eStopReasonBreakpoint) {
- // If this is OUR breakpoint, we're fine, otherwise we don't know why this
- // happened...
+ // If this is OUR breakpoint, we're fine, otherwise we don't know why
+ // this happened...
BreakpointSiteSP this_site =
m_thread.GetProcess()->GetBreakpointSiteList().FindByID(
stop_info_sp->GetValue());
@@ -163,18 +163,13 @@ void ThreadPlanStepUntil::AnalyzeStop() {
if (this_site->IsBreakpointAtThisSite(m_return_bp_id)) {
// If we are at our "step out" breakpoint, and the stack depth has
- // shrunk, then
- // this is indeed our stop.
- // If the stack depth has grown, then we've hit our step out breakpoint
- // recursively.
- // If we are the only breakpoint at that location, then we do explain
- // the stop, and
- // we'll just continue.
- // If there was another breakpoint here, then we don't explain the stop,
- // but we won't
- // mark ourselves Completed, because maybe that breakpoint will
- // continue, and then
- // we'll finish the "until".
+ // shrunk, then this is indeed our stop. If the stack depth has grown,
+ // then we've hit our step out breakpoint recursively. If we are the
+ // only breakpoint at that location, then we do explain the stop, and
+ // we'll just continue. If there was another breakpoint here, then we
+ // don't explain the stop, but we won't mark ourselves Completed,
+ // because maybe that breakpoint will continue, and then we'll finish
+ // the "until".
bool done;
StackID cur_frame_zero_id;
@@ -209,8 +204,8 @@ void ThreadPlanStepUntil::AnalyzeStop() {
else {
StackFrameSP older_frame_sp = m_thread.GetStackFrameAtIndex(1);
- // But if we can't even unwind one frame we should just get out of
- // here & stop...
+ // But if we can't even unwind one frame we should just get out
+ // of here & stop...
if (older_frame_sp) {
const SymbolContext &older_context =
older_frame_sp->GetSymbolContext(eSymbolContextEverything);
@@ -230,8 +225,8 @@ void ThreadPlanStepUntil::AnalyzeStop() {
// Otherwise we've hit this breakpoint recursively. If we're the
// only breakpoint here, then we do explain the stop, and we'll
- // continue.
- // If not then we should let higher plans handle this stop.
+ // continue. If not then we should let higher plans handle this
+ // stop.
if (this_site->GetNumberOfOwners() == 1)
m_explains_stop = true;
else {
@@ -242,8 +237,8 @@ void ThreadPlanStepUntil::AnalyzeStop() {
}
}
}
- // If we get here we haven't hit any of our breakpoints, so let the higher
- // plans take care of the stop.
+ // If we get here we haven't hit any of our breakpoints, so let the
+ // higher plans take care of the stop.
m_explains_stop = false;
return;
} else if (IsUsuallyUnexplainedStopReason(reason)) {
@@ -256,16 +251,15 @@ void ThreadPlanStepUntil::AnalyzeStop() {
bool ThreadPlanStepUntil::DoPlanExplainsStop(Event *event_ptr) {
// We don't explain signals or breakpoints (breakpoints that handle stepping
- // in or
- // out will be handled by a child plan.
+ // in or out will be handled by a child plan.
AnalyzeStop();
return m_explains_stop;
}
bool ThreadPlanStepUntil::ShouldStop(Event *event_ptr) {
- // If we've told our self in ExplainsStop that we plan to continue, then
- // do so here. Otherwise, as long as this thread has stopped for a reason,
- // we will stop.
+ // If we've told our self in ExplainsStop that we plan to continue, then do
+ // so here. Otherwise, as long as this thread has stopped for a reason, we
+ // will stop.
StopInfoSP stop_info_sp = GetPrivateStopInfo();
if (!stop_info_sp || stop_info_sp->GetStopReason() == eStopReasonNone)
diff --git a/source/Target/ThreadPlanTracer.cpp b/source/Target/ThreadPlanTracer.cpp
index 5057ca0a711b..acbbd4d8bcc2 100644
--- a/source/Target/ThreadPlanTracer.cpp
+++ b/source/Target/ThreadPlanTracer.cpp
@@ -13,6 +13,7 @@
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Disassembler.h"
+#include "lldb/Core/DumpRegisterValue.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/State.h"
#include "lldb/Core/StreamFile.h"
@@ -217,7 +218,8 @@ void ThreadPlanAssemblyTracer::Log() {
reg_value != m_register_values[reg_num]) {
if (reg_value.GetType() != RegisterValue::eTypeInvalid) {
stream->PutCString("\n\t");
- reg_value.Dump(stream, reg_info, true, false, eFormatDefault);
+ DumpRegisterValue(reg_value, stream, reg_info, true, false,
+ eFormatDefault);
}
}
m_register_values[reg_num] = reg_value;
diff --git a/source/Target/UnixSignals.cpp b/source/Target/UnixSignals.cpp
index 150c6619859f..9cfb1b74adee 100644
--- a/source/Target/UnixSignals.cpp
+++ b/source/Target/UnixSignals.cpp
@@ -66,9 +66,8 @@ UnixSignals::~UnixSignals() = default;
void UnixSignals::Reset() {
// This builds one standard set of Unix Signals. If yours aren't quite in
- // this
- // order, you can either subclass this class, and use Add & Remove to change
- // them
+ // this order, you can either subclass this class, and use Add & Remove to
+ // change them
// or you can subclass and build them afresh in your constructor;
//
// Note: the signals below are the Darwin signals. Do not change these!
@@ -306,8 +305,8 @@ UnixSignals::GetFilteredSignals(llvm::Optional<bool> should_suppress,
bool signal_notify = false;
GetSignalInfo(signo, signal_suppress, signal_stop, signal_notify);
- // If any of filtering conditions are not met,
- // we move on to the next signal.
+ // If any of filtering conditions are not met, we move on to the next
+ // signal.
if (should_suppress.hasValue() &&
signal_suppress != should_suppress.getValue())
continue;
diff --git a/source/Utility/ArchSpec.cpp b/source/Utility/ArchSpec.cpp
index a10fe78260bb..320f2d9d1144 100644
--- a/source/Utility/ArchSpec.cpp
+++ b/source/Utility/ArchSpec.cpp
@@ -9,6 +9,7 @@
#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/Log.h"
#include "lldb/Utility/NameMatches.h"
#include "lldb/Utility/Stream.h" // for Stream
#include "lldb/Utility/StringList.h"
@@ -223,8 +224,8 @@ static const CoreDefinition g_core_definitions[] = {
"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.
+// 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");
@@ -244,17 +245,22 @@ struct ArchDefinition {
const char *name;
};
-size_t ArchSpec::AutoComplete(llvm::StringRef name, StringList &matches) {
- if (!name.empty()) {
+void ArchSpec::ListSupportedArchNames(StringList &list) {
+ for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i)
+ list.AppendString(g_core_definitions[i].name);
+}
+
+size_t ArchSpec::AutoComplete(CompletionRequest &request) {
+ if (!request.GetCursorArgumentPrefix().empty()) {
for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) {
- if (NameMatches(g_core_definitions[i].name, NameMatch::StartsWith, name))
- matches.AppendString(g_core_definitions[i].name);
+ if (NameMatches(g_core_definitions[i].name, NameMatch::StartsWith,
+ request.GetCursorArgumentPrefix()))
+ request.GetMatches().AppendString(g_core_definitions[i].name);
}
} else {
- for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i)
- matches.AppendString(g_core_definitions[i].name);
+ ListSupportedArchNames(request.GetMatches());
}
- return matches.GetSize();
+ return request.GetMatches().GetSize();
}
#define CPU_ANY (UINT32_MAX)
@@ -890,7 +896,12 @@ void ArchSpec::MergeFrom(const ArchSpec &other) {
GetTriple().setOS(other.GetTriple().getOS());
if (GetTriple().getArch() == llvm::Triple::UnknownArch) {
GetTriple().setArch(other.GetTriple().getArch());
- UpdateCore();
+
+ // MachO unknown64 isn't really invalid as the debugger can still obtain
+ // information from the binary, e.g. line tables. As such, we don't update
+ // the core here.
+ if (other.GetCore() != eCore_uknownMach64)
+ UpdateCore();
}
if (GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
!TripleVendorWasSpecified()) {
@@ -898,9 +909,8 @@ void ArchSpec::MergeFrom(const ArchSpec &other) {
GetTriple().setEnvironment(other.GetTriple().getEnvironment());
}
// If this and other are both arm ArchSpecs and this ArchSpec is a generic
- // "some kind of arm"
- // spec but the other ArchSpec is a specific arm core, adopt the specific arm
- // core.
+ // "some kind of arm" spec but the other ArchSpec is a specific arm core,
+ // adopt the specific arm core.
if (GetTriple().getArch() == llvm::Triple::arm &&
other.GetTriple().getArch() == llvm::Triple::arm &&
IsCompatibleMatch(other) && GetCore() == ArchSpec::eCore_arm_generic &&
@@ -926,24 +936,21 @@ bool ArchSpec::SetArchitecture(ArchitectureType arch_type, uint32_t cpu,
if (core_def) {
m_core = core_def->core;
update_triple = false;
- // Always use the architecture name because it might be more descriptive
- // than the architecture enum ("armv7" -> llvm::Triple::arm).
+ // Always use the architecture name because it might be more
+ // descriptive than the architecture enum ("armv7" ->
+ // llvm::Triple::arm).
m_triple.setArchName(llvm::StringRef(core_def->name));
if (arch_type == eArchTypeMachO) {
m_triple.setVendor(llvm::Triple::Apple);
// Don't set the OS. It could be simulator, macosx, ios, watchos,
- // tvos. We could
- // get close with the cpu type - but we can't get it right all of the
- // time. Better
- // to leave this unset so other sections of code will set it when they
- // have more
- // information.
+ // tvos. We could get close with the cpu type - but we can't get it
+ // right all of the time. Better to leave this unset so other
+ // sections of code will set it when they have more information.
// NB: don't call m_triple.setOS (llvm::Triple::UnknownOS). That sets
// the OSName to
// "unknown" and the ArchSpec::TripleVendorWasSpecified() method says
- // that any
- // OSName setting means it was specified.
+ // that any OSName setting means it was specified.
} else if (arch_type == eArchTypeELF) {
switch (os) {
case llvm::ELF::ELFOSABI_AIX:
@@ -972,10 +979,15 @@ bool ArchSpec::SetArchitecture(ArchitectureType arch_type, uint32_t cpu,
m_triple.setVendor(llvm::Triple::UnknownVendor);
m_triple.setOS(llvm::Triple::UnknownOS);
}
- // Fall back onto setting the machine type if the arch by name failed...
+ // Fall back onto setting the machine type if the arch by name
+ // failed...
if (m_triple.getArch() == llvm::Triple::UnknownArch)
m_triple.setArch(core_def->machine);
}
+ } else {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET | LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_PLATFORM));
+ if (log)
+ log->Printf("Unable to find a core definition for cpu 0x%" PRIx32 " sub %" PRId32, cpu, sub);
}
}
CoreUpdated(update_triple);
@@ -1015,10 +1027,9 @@ static bool isCompatibleEnvironment(llvm::Triple::EnvironmentType lhs,
return true;
// If one of the environment is Android and the other one is EABI then they
- // are considered to
- // be compatible. This is required as a workaround for shared libraries
- // compiled for Android
- // without the NOTE section indicating that they are using the Android ABI.
+ // are considered to be compatible. This is required as a workaround for
+ // shared libraries compiled for Android without the NOTE section indicating
+ // that they are using the Android ABI.
if ((lhs == llvm::Triple::Android && rhs == llvm::Triple::EABI) ||
(rhs == llvm::Triple::Android && lhs == llvm::Triple::EABI) ||
(lhs == llvm::Triple::GNUEABI && rhs == llvm::Triple::EABI) ||
@@ -1050,8 +1061,8 @@ bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const {
if (lhs_triple_vendor != rhs_triple_vendor) {
const bool rhs_vendor_specified = rhs.TripleVendorWasSpecified();
const bool lhs_vendor_specified = TripleVendorWasSpecified();
- // Both architectures had the vendor specified, so if they aren't
- // equal then we return false
+ // Both architectures had the vendor specified, so if they aren't equal
+ // then we return false
if (rhs_vendor_specified && lhs_vendor_specified)
return false;
@@ -1066,8 +1077,8 @@ bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const {
if (lhs_triple_os != rhs_triple_os) {
const bool rhs_os_specified = rhs.TripleOSWasSpecified();
const bool lhs_os_specified = TripleOSWasSpecified();
- // Both architectures had the OS specified, so if they aren't
- // equal then we return false
+ // Both architectures had the OS specified, so if they aren't equal then
+ // we return false
if (rhs_os_specified && lhs_os_specified)
return false;
@@ -1094,9 +1105,9 @@ void ArchSpec::UpdateCore() {
const CoreDefinition *core_def = FindCoreDefinition(arch_name);
if (core_def) {
m_core = core_def->core;
- // Set the byte order to the default byte order for an architecture.
- // This can be modified if needed for cases when cores handle both
- // big and little endian
+ // Set the byte order to the default byte order for an architecture. This
+ // can be modified if needed for cases when cores handle both big and
+ // little endian
m_byte_order = core_def->default_byte_order;
} else {
Clear();
@@ -1193,9 +1204,8 @@ static bool cores_match(const ArchSpec::Core core1, const ArchSpec::Core core2,
break;
// v. https://en.wikipedia.org/wiki/ARM_Cortex-M#Silicon_customization
- // Cortex-M0 - ARMv6-M - armv6m
- // Cortex-M3 - ARMv7-M - armv7m
- // Cortex-M4 - ARMv7E-M - armv7em
+ // Cortex-M0 - ARMv6-M - armv6m Cortex-M3 - ARMv7-M - armv7m Cortex-M4 -
+ // ARMv7E-M - armv7em
case ArchSpec::eCore_arm_armv7em:
if (!enforce_exact_match) {
if (core2 == ArchSpec::eCore_arm_generic)
@@ -1211,9 +1221,8 @@ static bool cores_match(const ArchSpec::Core core1, const ArchSpec::Core core2,
break;
// v. https://en.wikipedia.org/wiki/ARM_Cortex-M#Silicon_customization
- // Cortex-M0 - ARMv6-M - armv6m
- // Cortex-M3 - ARMv7-M - armv7m
- // Cortex-M4 - ARMv7E-M - armv7em
+ // Cortex-M0 - ARMv6-M - armv6m Cortex-M3 - ARMv7-M - armv7m Cortex-M4 -
+ // ARMv7E-M - armv7em
case ArchSpec::eCore_arm_armv7m:
if (!enforce_exact_match) {
if (core2 == ArchSpec::eCore_arm_generic)
@@ -1411,6 +1420,11 @@ bool lldb_private::operator<(const ArchSpec &lhs, const ArchSpec &rhs) {
return lhs_core < rhs_core;
}
+
+bool lldb_private::operator==(const ArchSpec &lhs, const ArchSpec &rhs) {
+ return lhs.GetCore() == rhs.GetCore();
+}
+
bool ArchSpec::IsFullySpecifiedTriple() const {
const auto &user_specified_triple = GetTriple();
@@ -1456,9 +1470,8 @@ bool ArchSpec::IsAlwaysThumbInstructions() const {
// Cortex-M0 through Cortex-M7 are ARM processor cores which can only
// execute thumb instructions. We map the cores to arch names like this:
//
- // Cortex-M0, Cortex-M0+, Cortex-M1: armv6m
- // Cortex-M3: armv7m
- // Cortex-M4, Cortex-M7: armv7em
+ // Cortex-M0, Cortex-M0+, Cortex-M1: armv6m Cortex-M3: armv7m Cortex-M4,
+ // Cortex-M7: armv7em
if (GetCore() == ArchSpec::Core::eCore_arm_armv7m ||
GetCore() == ArchSpec::Core::eCore_arm_armv7em ||
diff --git a/source/Utility/Args.cpp b/source/Utility/Args.cpp
new file mode 100644
index 000000000000..3b5cf1715fb3
--- /dev/null
+++ b/source/Utility/Args.cpp
@@ -0,0 +1,726 @@
+//===-- Args.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/Utility/Args.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Stream.h"
+#include "lldb/Utility/StringList.h"
+#include "llvm/ADT/StringSwitch.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+// A helper function for argument parsing.
+// Parses the initial part of the first argument using normal double quote
+// rules: backslash escapes the double quote and itself. The parsed string is
+// appended to the second argument. The function returns the unparsed portion
+// of the string, starting at the closing quote.
+static llvm::StringRef ParseDoubleQuotes(llvm::StringRef quoted,
+ std::string &result) {
+ // Inside double quotes, '\' and '"' are special.
+ static const char *k_escapable_characters = "\"\\";
+ while (true) {
+ // Skip over over regular characters and append them.
+ size_t regular = quoted.find_first_of(k_escapable_characters);
+ result += quoted.substr(0, regular);
+ quoted = quoted.substr(regular);
+
+ // If we have reached the end of string or the closing quote, we're done.
+ if (quoted.empty() || quoted.front() == '"')
+ break;
+
+ // We have found a backslash.
+ quoted = quoted.drop_front();
+
+ if (quoted.empty()) {
+ // A lone backslash at the end of string, let's just append it.
+ result += '\\';
+ break;
+ }
+
+ // If the character after the backslash is not a whitelisted escapable
+ // character, we leave the character sequence untouched.
+ if (strchr(k_escapable_characters, quoted.front()) == nullptr)
+ result += '\\';
+
+ result += quoted.front();
+ quoted = quoted.drop_front();
+ }
+
+ return quoted;
+}
+
+static size_t ArgvToArgc(const char **argv) {
+ if (!argv)
+ return 0;
+ size_t count = 0;
+ while (*argv++)
+ ++count;
+ return count;
+}
+
+// Trims all whitespace that can separate command line arguments from the left
+// side of the string.
+static llvm::StringRef ltrimForArgs(llvm::StringRef str) {
+ static const char *k_space_separators = " \t";
+ return str.ltrim(k_space_separators);
+}
+
+// A helper function for SetCommandString. Parses a single argument from the
+// command string, processing quotes and backslashes in a shell-like manner.
+// The function returns a tuple consisting of the parsed argument, the quote
+// char used, and the unparsed portion of the string starting at the first
+// unqouted, unescaped whitespace character.
+static std::tuple<std::string, char, llvm::StringRef>
+ParseSingleArgument(llvm::StringRef command) {
+ // Argument can be split into multiple discontiguous pieces, for example:
+ // "Hello ""World"
+ // this would result in a single argument "Hello World" (without the quotes)
+ // since the quotes would be removed and there is not space between the
+ // strings.
+ std::string arg;
+
+ // Since we can have multiple quotes that form a single command in a command
+ // like: "Hello "world'!' (which will make a single argument "Hello world!")
+ // we remember the first quote character we encounter and use that for the
+ // quote character.
+ char first_quote_char = '\0';
+
+ bool arg_complete = false;
+ do {
+ // Skip over over regular characters and append them.
+ size_t regular = command.find_first_of(" \t\"'`\\");
+ arg += command.substr(0, regular);
+ command = command.substr(regular);
+
+ if (command.empty())
+ break;
+
+ char special = command.front();
+ command = command.drop_front();
+ switch (special) {
+ case '\\':
+ if (command.empty()) {
+ arg += '\\';
+ break;
+ }
+
+ // If the character after the backslash is not a whitelisted escapable
+ // character, we leave the character sequence untouched.
+ if (strchr(" \t\\'\"`", command.front()) == nullptr)
+ arg += '\\';
+
+ arg += command.front();
+ command = command.drop_front();
+
+ break;
+
+ case ' ':
+ case '\t':
+ // We are not inside any quotes, we just found a space after an argument.
+ // We are done.
+ arg_complete = true;
+ break;
+
+ case '"':
+ case '\'':
+ case '`':
+ // We found the start of a quote scope.
+ if (first_quote_char == '\0')
+ first_quote_char = special;
+
+ if (special == '"')
+ command = ParseDoubleQuotes(command, arg);
+ else {
+ // For single quotes, we simply skip ahead to the matching quote
+ // character (or the end of the string).
+ size_t quoted = command.find(special);
+ arg += command.substr(0, quoted);
+ command = command.substr(quoted);
+ }
+
+ // If we found a closing quote, skip it.
+ if (!command.empty())
+ command = command.drop_front();
+
+ break;
+ }
+ } while (!arg_complete);
+
+ return std::make_tuple(arg, first_quote_char, command);
+}
+
+Args::ArgEntry::ArgEntry(llvm::StringRef str, char quote) : quote(quote) {
+ size_t size = str.size();
+ ptr.reset(new char[size + 1]);
+
+ ::memcpy(data(), str.data() ? str.data() : "", size);
+ ptr[size] = 0;
+ ref = llvm::StringRef(c_str(), size);
+}
+
+//----------------------------------------------------------------------
+// Args constructor
+//----------------------------------------------------------------------
+Args::Args(llvm::StringRef command) { SetCommandString(command); }
+
+Args::Args(const Args &rhs) { *this = rhs; }
+
+Args::Args(const StringList &list) : Args() {
+ for (size_t i = 0; i < list.GetSize(); ++i)
+ AppendArgument(list[i]);
+}
+
+Args &Args::operator=(const Args &rhs) {
+ Clear();
+
+ m_argv.clear();
+ m_entries.clear();
+ for (auto &entry : rhs.m_entries) {
+ m_entries.emplace_back(entry.ref, entry.quote);
+ m_argv.push_back(m_entries.back().data());
+ }
+ m_argv.push_back(nullptr);
+ return *this;
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+Args::~Args() {}
+
+void Args::Dump(Stream &s, const char *label_name) const {
+ if (!label_name)
+ return;
+
+ int i = 0;
+ for (auto &entry : m_entries) {
+ s.Indent();
+ s.Format("{0}[{1}]=\"{2}\"\n", label_name, i++, entry.ref);
+ }
+ s.Format("{0}[{1}]=NULL\n", label_name, i);
+ s.EOL();
+}
+
+bool Args::GetCommandString(std::string &command) const {
+ command.clear();
+
+ for (size_t i = 0; i < m_entries.size(); ++i) {
+ if (i > 0)
+ command += ' ';
+ command += m_entries[i].ref;
+ }
+
+ return !m_entries.empty();
+}
+
+bool Args::GetQuotedCommandString(std::string &command) const {
+ command.clear();
+
+ for (size_t i = 0; i < m_entries.size(); ++i) {
+ if (i > 0)
+ command += ' ';
+
+ if (m_entries[i].quote) {
+ command += m_entries[i].quote;
+ command += m_entries[i].ref;
+ command += m_entries[i].quote;
+ } else {
+ command += m_entries[i].ref;
+ }
+ }
+
+ return !m_entries.empty();
+}
+
+void Args::SetCommandString(llvm::StringRef command) {
+ Clear();
+ m_argv.clear();
+
+ command = ltrimForArgs(command);
+ std::string arg;
+ char quote;
+ while (!command.empty()) {
+ std::tie(arg, quote, command) = ParseSingleArgument(command);
+ m_entries.emplace_back(arg, quote);
+ m_argv.push_back(m_entries.back().data());
+ command = ltrimForArgs(command);
+ }
+ m_argv.push_back(nullptr);
+}
+
+size_t Args::GetArgumentCount() const { return m_entries.size(); }
+
+const char *Args::GetArgumentAtIndex(size_t idx) const {
+ if (idx < m_argv.size())
+ return m_argv[idx];
+ return nullptr;
+}
+
+char Args::GetArgumentQuoteCharAtIndex(size_t idx) const {
+ if (idx < m_entries.size())
+ return m_entries[idx].quote;
+ return '\0';
+}
+
+char **Args::GetArgumentVector() {
+ assert(!m_argv.empty());
+ // TODO: functions like execve and posix_spawnp exhibit undefined behavior
+ // when argv or envp is null. So the code below is actually wrong. However,
+ // other code in LLDB depends on it being null. The code has been acting
+ // this way for some time, so it makes sense to leave it this way until
+ // someone has the time to come along and fix it.
+ return (m_argv.size() > 1) ? m_argv.data() : nullptr;
+}
+
+const char **Args::GetConstArgumentVector() const {
+ assert(!m_argv.empty());
+ return (m_argv.size() > 1) ? const_cast<const char **>(m_argv.data())
+ : nullptr;
+}
+
+void Args::Shift() {
+ // Don't pop the last NULL terminator from the argv array
+ if (m_entries.empty())
+ return;
+ m_argv.erase(m_argv.begin());
+ m_entries.erase(m_entries.begin());
+}
+
+void Args::Unshift(llvm::StringRef arg_str, char quote_char) {
+ InsertArgumentAtIndex(0, arg_str, quote_char);
+}
+
+void Args::AppendArguments(const Args &rhs) {
+ assert(m_argv.size() == m_entries.size() + 1);
+ assert(m_argv.back() == nullptr);
+ m_argv.pop_back();
+ for (auto &entry : rhs.m_entries) {
+ m_entries.emplace_back(entry.ref, entry.quote);
+ m_argv.push_back(m_entries.back().data());
+ }
+ m_argv.push_back(nullptr);
+}
+
+void Args::AppendArguments(const char **argv) {
+ size_t argc = ArgvToArgc(argv);
+
+ assert(m_argv.size() == m_entries.size() + 1);
+ assert(m_argv.back() == nullptr);
+ m_argv.pop_back();
+ for (auto arg : llvm::makeArrayRef(argv, argc)) {
+ m_entries.emplace_back(arg, '\0');
+ m_argv.push_back(m_entries.back().data());
+ }
+
+ m_argv.push_back(nullptr);
+}
+
+void Args::AppendArgument(llvm::StringRef arg_str, char quote_char) {
+ InsertArgumentAtIndex(GetArgumentCount(), arg_str, quote_char);
+}
+
+void Args::InsertArgumentAtIndex(size_t idx, llvm::StringRef arg_str,
+ char quote_char) {
+ assert(m_argv.size() == m_entries.size() + 1);
+ assert(m_argv.back() == nullptr);
+
+ if (idx > m_entries.size())
+ return;
+ m_entries.emplace(m_entries.begin() + idx, arg_str, quote_char);
+ m_argv.insert(m_argv.begin() + idx, m_entries[idx].data());
+}
+
+void Args::ReplaceArgumentAtIndex(size_t idx, llvm::StringRef arg_str,
+ char quote_char) {
+ assert(m_argv.size() == m_entries.size() + 1);
+ assert(m_argv.back() == nullptr);
+
+ if (idx >= m_entries.size())
+ return;
+
+ if (arg_str.size() > m_entries[idx].ref.size()) {
+ m_entries[idx] = ArgEntry(arg_str, quote_char);
+ m_argv[idx] = m_entries[idx].data();
+ } else {
+ const char *src_data = arg_str.data() ? arg_str.data() : "";
+ ::memcpy(m_entries[idx].data(), src_data, arg_str.size());
+ m_entries[idx].ptr[arg_str.size()] = 0;
+ m_entries[idx].ref = m_entries[idx].ref.take_front(arg_str.size());
+ }
+}
+
+void Args::DeleteArgumentAtIndex(size_t idx) {
+ if (idx >= m_entries.size())
+ return;
+
+ m_argv.erase(m_argv.begin() + idx);
+ m_entries.erase(m_entries.begin() + idx);
+}
+
+void Args::SetArguments(size_t argc, const char **argv) {
+ Clear();
+
+ auto args = llvm::makeArrayRef(argv, argc);
+ m_entries.resize(argc);
+ m_argv.resize(argc + 1);
+ for (size_t i = 0; i < args.size(); ++i) {
+ char quote =
+ ((args[i][0] == '\'') || (args[i][0] == '"') || (args[i][0] == '`'))
+ ? args[i][0]
+ : '\0';
+
+ m_entries[i] = ArgEntry(args[i], quote);
+ m_argv[i] = m_entries[i].data();
+ }
+}
+
+void Args::SetArguments(const char **argv) {
+ SetArguments(ArgvToArgc(argv), argv);
+}
+
+void Args::Clear() {
+ m_entries.clear();
+ m_argv.clear();
+ m_argv.push_back(nullptr);
+}
+
+const char *Args::StripSpaces(std::string &s, bool leading, bool trailing,
+ bool return_null_if_empty) {
+ static const char *k_white_space = " \t\v";
+ if (!s.empty()) {
+ if (leading) {
+ size_t pos = s.find_first_not_of(k_white_space);
+ if (pos == std::string::npos)
+ s.clear();
+ else if (pos > 0)
+ s.erase(0, pos);
+ }
+
+ if (trailing) {
+ size_t rpos = s.find_last_not_of(k_white_space);
+ if (rpos != std::string::npos && rpos + 1 < s.size())
+ s.erase(rpos + 1);
+ }
+ }
+ if (return_null_if_empty && s.empty())
+ return nullptr;
+ return s.c_str();
+}
+
+const char *Args::GetShellSafeArgument(const FileSpec &shell,
+ const char *unsafe_arg,
+ std::string &safe_arg) {
+ struct ShellDescriptor {
+ ConstString m_basename;
+ const char *m_escapables;
+ };
+
+ static ShellDescriptor g_Shells[] = {{ConstString("bash"), " '\"<>()&"},
+ {ConstString("tcsh"), " '\"<>()&$"},
+ {ConstString("sh"), " '\"<>()&"}};
+
+ // safe minimal set
+ const char *escapables = " '\"";
+
+ if (auto basename = shell.GetFilename()) {
+ for (const auto &Shell : g_Shells) {
+ if (Shell.m_basename == basename) {
+ escapables = Shell.m_escapables;
+ break;
+ }
+ }
+ }
+
+ safe_arg.assign(unsafe_arg);
+ size_t prev_pos = 0;
+ while (prev_pos < safe_arg.size()) {
+ // Escape spaces and quotes
+ size_t pos = safe_arg.find_first_of(escapables, prev_pos);
+ if (pos != std::string::npos) {
+ safe_arg.insert(pos, 1, '\\');
+ prev_pos = pos + 2;
+ } else
+ break;
+ }
+ return safe_arg.c_str();
+}
+
+lldb::Encoding Args::StringToEncoding(llvm::StringRef s,
+ lldb::Encoding fail_value) {
+ return llvm::StringSwitch<lldb::Encoding>(s)
+ .Case("uint", eEncodingUint)
+ .Case("sint", eEncodingSint)
+ .Case("ieee754", eEncodingIEEE754)
+ .Case("vector", eEncodingVector)
+ .Default(fail_value);
+}
+
+uint32_t Args::StringToGenericRegister(llvm::StringRef s) {
+ if (s.empty())
+ return LLDB_INVALID_REGNUM;
+ uint32_t result = llvm::StringSwitch<uint32_t>(s)
+ .Case("pc", LLDB_REGNUM_GENERIC_PC)
+ .Case("sp", LLDB_REGNUM_GENERIC_SP)
+ .Case("fp", LLDB_REGNUM_GENERIC_FP)
+ .Cases("ra", "lr", LLDB_REGNUM_GENERIC_RA)
+ .Case("flags", LLDB_REGNUM_GENERIC_FLAGS)
+ .Case("arg1", LLDB_REGNUM_GENERIC_ARG1)
+ .Case("arg2", LLDB_REGNUM_GENERIC_ARG2)
+ .Case("arg3", LLDB_REGNUM_GENERIC_ARG3)
+ .Case("arg4", LLDB_REGNUM_GENERIC_ARG4)
+ .Case("arg5", LLDB_REGNUM_GENERIC_ARG5)
+ .Case("arg6", LLDB_REGNUM_GENERIC_ARG6)
+ .Case("arg7", LLDB_REGNUM_GENERIC_ARG7)
+ .Case("arg8", LLDB_REGNUM_GENERIC_ARG8)
+ .Default(LLDB_INVALID_REGNUM);
+ return result;
+}
+
+void Args::EncodeEscapeSequences(const char *src, std::string &dst) {
+ dst.clear();
+ if (src) {
+ for (const char *p = src; *p != '\0'; ++p) {
+ size_t non_special_chars = ::strcspn(p, "\\");
+ if (non_special_chars > 0) {
+ dst.append(p, non_special_chars);
+ p += non_special_chars;
+ if (*p == '\0')
+ break;
+ }
+
+ if (*p == '\\') {
+ ++p; // skip the slash
+ switch (*p) {
+ case 'a':
+ dst.append(1, '\a');
+ break;
+ case 'b':
+ dst.append(1, '\b');
+ break;
+ case 'f':
+ dst.append(1, '\f');
+ break;
+ case 'n':
+ dst.append(1, '\n');
+ break;
+ case 'r':
+ dst.append(1, '\r');
+ break;
+ case 't':
+ dst.append(1, '\t');
+ break;
+ case 'v':
+ dst.append(1, '\v');
+ break;
+ case '\\':
+ dst.append(1, '\\');
+ break;
+ case '\'':
+ dst.append(1, '\'');
+ break;
+ case '"':
+ dst.append(1, '"');
+ break;
+ case '0':
+ // 1 to 3 octal chars
+ {
+ // Make a string that can hold onto the initial zero char, up to 3
+ // octal digits, and a terminating NULL.
+ char oct_str[5] = {'\0', '\0', '\0', '\0', '\0'};
+
+ int i;
+ for (i = 0; (p[i] >= '0' && p[i] <= '7') && i < 4; ++i)
+ oct_str[i] = p[i];
+
+ // We don't want to consume the last octal character since the main
+ // for loop will do this for us, so we advance p by one less than i
+ // (even if i is zero)
+ p += i - 1;
+ unsigned long octal_value = ::strtoul(oct_str, nullptr, 8);
+ if (octal_value <= UINT8_MAX) {
+ dst.append(1, (char)octal_value);
+ }
+ }
+ break;
+
+ case 'x':
+ // hex number in the format
+ if (isxdigit(p[1])) {
+ ++p; // Skip the 'x'
+
+ // Make a string that can hold onto two hex chars plus a
+ // NULL terminator
+ char hex_str[3] = {*p, '\0', '\0'};
+ if (isxdigit(p[1])) {
+ ++p; // Skip the first of the two hex chars
+ hex_str[1] = *p;
+ }
+
+ unsigned long hex_value = strtoul(hex_str, nullptr, 16);
+ if (hex_value <= UINT8_MAX)
+ dst.append(1, (char)hex_value);
+ } else {
+ dst.append(1, 'x');
+ }
+ break;
+
+ default:
+ // Just desensitize any other character by just printing what came
+ // after the '\'
+ dst.append(1, *p);
+ break;
+ }
+ }
+ }
+ }
+}
+
+void Args::ExpandEscapedCharacters(const char *src, std::string &dst) {
+ dst.clear();
+ if (src) {
+ for (const char *p = src; *p != '\0'; ++p) {
+ if (isprint(*p))
+ dst.append(1, *p);
+ else {
+ switch (*p) {
+ case '\a':
+ dst.append("\\a");
+ break;
+ case '\b':
+ dst.append("\\b");
+ break;
+ case '\f':
+ dst.append("\\f");
+ break;
+ case '\n':
+ dst.append("\\n");
+ break;
+ case '\r':
+ dst.append("\\r");
+ break;
+ case '\t':
+ dst.append("\\t");
+ break;
+ case '\v':
+ dst.append("\\v");
+ break;
+ case '\'':
+ dst.append("\\'");
+ break;
+ case '"':
+ dst.append("\\\"");
+ break;
+ case '\\':
+ dst.append("\\\\");
+ break;
+ default: {
+ // Just encode as octal
+ dst.append("\\0");
+ char octal_str[32];
+ snprintf(octal_str, sizeof(octal_str), "%o", *p);
+ dst.append(octal_str);
+ } break;
+ }
+ }
+ }
+ }
+}
+
+std::string Args::EscapeLLDBCommandArgument(const std::string &arg,
+ char quote_char) {
+ const char *chars_to_escape = nullptr;
+ switch (quote_char) {
+ case '\0':
+ chars_to_escape = " \t\\'\"`";
+ break;
+ case '\'':
+ chars_to_escape = "";
+ break;
+ case '"':
+ chars_to_escape = "$\"`\\";
+ break;
+ default:
+ assert(false && "Unhandled quote character");
+ }
+
+ std::string res;
+ res.reserve(arg.size());
+ for (char c : arg) {
+ if (::strchr(chars_to_escape, c))
+ res.push_back('\\');
+ res.push_back(c);
+ }
+ return res;
+}
+
+OptionsWithRaw::OptionsWithRaw(llvm::StringRef arg_string) {
+ SetFromString(arg_string);
+}
+
+void OptionsWithRaw::SetFromString(llvm::StringRef arg_string) {
+ const llvm::StringRef original_args = arg_string;
+
+ arg_string = ltrimForArgs(arg_string);
+ std::string arg;
+ char quote;
+
+ // If the string doesn't start with a dash, we just have no options and just
+ // a raw part.
+ if (!arg_string.startswith("-")) {
+ m_suffix = original_args;
+ return;
+ }
+
+ bool found_suffix = false;
+
+ while (!arg_string.empty()) {
+ // The length of the prefix before parsing.
+ std::size_t prev_prefix_length = original_args.size() - arg_string.size();
+
+ // Parse the next argument from the remaining string.
+ std::tie(arg, quote, arg_string) = ParseSingleArgument(arg_string);
+
+ // If we get an unquoted '--' argument, then we reached the suffix part
+ // of the command.
+ Args::ArgEntry entry(arg, quote);
+ if (!entry.IsQuoted() && arg == "--") {
+ // The remaining line is the raw suffix, and the line we parsed so far
+ // needs to be interpreted as arguments.
+ m_has_args = true;
+ m_suffix = arg_string;
+ found_suffix = true;
+
+ // The length of the prefix after parsing.
+ std::size_t prefix_length = original_args.size() - arg_string.size();
+
+ // Take the string we know contains all the arguments and actually parse
+ // it as proper arguments.
+ llvm::StringRef prefix = original_args.take_front(prev_prefix_length);
+ m_args = Args(prefix);
+ m_arg_string = prefix;
+
+ // We also record the part of the string that contains the arguments plus
+ // the delimiter.
+ m_arg_string_with_delimiter = original_args.take_front(prefix_length);
+
+ // As the rest of the string became the raw suffix, we are done here.
+ break;
+ }
+
+ arg_string = ltrimForArgs(arg_string);
+ }
+
+ // If we didn't find a suffix delimiter, the whole string is the raw suffix.
+ if (!found_suffix) {
+ found_suffix = true;
+ m_suffix = original_args;
+ }
+}
diff --git a/source/Utility/CMakeLists.txt b/source/Utility/CMakeLists.txt
index 1a0fb6f86c57..91f3c8773731 100644
--- a/source/Utility/CMakeLists.txt
+++ b/source/Utility/CMakeLists.txt
@@ -41,16 +41,18 @@ endif()
add_lldb_library(lldbUtility
ArchSpec.cpp
+ Args.cpp
Baton.cpp
Connection.cpp
ConstString.cpp
+ CompletionRequest.cpp
DataBufferHeap.cpp
DataBufferLLVM.cpp
DataEncoder.cpp
DataExtractor.cpp
+ Environment.cpp
FastDemangle.cpp
FileSpec.cpp
- History.cpp
IOObject.cpp
JSON.cpp
LLDBAssert.cpp
diff --git a/source/Utility/CompletionRequest.cpp b/source/Utility/CompletionRequest.cpp
new file mode 100644
index 000000000000..1b7697a35860
--- /dev/null
+++ b/source/Utility/CompletionRequest.cpp
@@ -0,0 +1,59 @@
+//===-- CompletionRequest.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/Utility/CompletionRequest.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+CompletionRequest::CompletionRequest(llvm::StringRef command_line,
+ unsigned raw_cursor_pos,
+ int match_start_point,
+ int max_return_elements,
+ StringList &matches)
+ : m_command(command_line), m_raw_cursor_pos(raw_cursor_pos),
+ m_match_start_point(match_start_point),
+ m_max_return_elements(max_return_elements), m_matches(&matches) {
+
+ // We parse the argument up to the cursor, so the last argument in
+ // parsed_line is the one containing the cursor, and the cursor is after the
+ // last character.
+ m_parsed_line = Args(command_line);
+ m_partial_parsed_line = Args(command_line.substr(0, raw_cursor_pos));
+
+ m_cursor_index = m_partial_parsed_line.GetArgumentCount() - 1;
+
+ if (m_cursor_index == -1)
+ m_cursor_char_position = 0;
+ else
+ m_cursor_char_position =
+ strlen(m_partial_parsed_line.GetArgumentAtIndex(m_cursor_index));
+
+ matches.Clear();
+
+ const char *cursor = command_line.data() + raw_cursor_pos;
+ if (raw_cursor_pos > 0 && cursor[-1] == ' ') {
+ // We are just after a space. If we are in an argument, then we will
+ // continue parsing, but if we are between arguments, then we have to
+ // complete whatever the next element would be. We can distinguish the two
+ // cases because if we are in an argument (e.g. because the space is
+ // protected by a quote) then the space will also be in the parsed
+ // argument...
+
+ const char *current_elem =
+ m_partial_parsed_line.GetArgumentAtIndex(m_cursor_index);
+ if (m_cursor_char_position == 0 ||
+ current_elem[m_cursor_char_position - 1] != ' ') {
+ m_parsed_line.InsertArgumentAtIndex(m_cursor_index + 1, llvm::StringRef(),
+ '\0');
+ m_cursor_index++;
+ m_cursor_char_position = 0;
+ }
+ }
+}
diff --git a/source/Utility/ConstString.cpp b/source/Utility/ConstString.cpp
index 49cf8a6d864d..5ef4b2faa3b8 100644
--- a/source/Utility/ConstString.cpp
+++ b/source/Utility/ConstString.cpp
@@ -11,10 +11,10 @@
#include "lldb/Utility/Stream.h"
-#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/iterator.h" // for iterator_facade_base
#include "llvm/Support/Allocator.h" // for BumpPtrAllocator
+#include "llvm/Support/DJB.h" // for djbHash
#include "llvm/Support/FormatProviders.h" // for format_provider
#include "llvm/Support/RWMutex.h"
#include "llvm/Support/Threading.h"
@@ -43,8 +43,8 @@ public:
static size_t GetConstCStringLength(const char *ccstr) {
if (ccstr != nullptr) {
- // Since the entry is read only, and we derive the entry entirely from the
- // pointer, we don't need the lock.
+ // Since the entry is read only, and we derive the entry entirely from
+ // the pointer, we don't need the lock.
const StringPoolEntryType &entry = GetStringMapEntryFromKeyData(ccstr);
return entry.getKey().size();
}
@@ -155,9 +155,8 @@ public:
}
//------------------------------------------------------------------
- // Return the size in bytes that this object and any items in its
- // collection of uniqued strings + data count values takes in
- // memory.
+ // Return the size in bytes that this object and any items in its collection
+ // of uniqued strings + data count values takes in memory.
//------------------------------------------------------------------
size_t MemorySize() const {
size_t mem_size = sizeof(Pool);
@@ -171,7 +170,7 @@ public:
protected:
uint8_t hash(const llvm::StringRef &s) const {
- uint32_t h = llvm::HashString(s);
+ uint32_t h = llvm::djbHash(s);
return ((h >> 24) ^ (h >> 16) ^ (h >> 8) ^ h) & 0xff;
}
@@ -184,15 +183,14 @@ protected:
};
//----------------------------------------------------------------------
-// Frameworks and dylibs aren't supposed to have global C++
-// initializers so we hide the string pool in a static function so
-// that it will get initialized on the first call to this static
-// function.
+// Frameworks and dylibs aren't supposed to have global C++ initializers so we
+// hide the string pool in a static function so that it will get initialized on
+// the first call to this static function.
//
-// Note, for now we make the string pool a pointer to the pool, because
-// we can't guarantee that some objects won't get destroyed after the
-// global destructor chain is run, and trying to make sure no destructors
-// touch ConstStrings is difficult. So we leak the pool instead.
+// Note, for now we make the string pool a pointer to the pool, because we
+// can't guarantee that some objects won't get destroyed after the global
+// destructor chain is run, and trying to make sure no destructors touch
+// ConstStrings is difficult. So we leak the pool instead.
//----------------------------------------------------------------------
static Pool &StringPool() {
static llvm::once_flag g_pool_initialization_flag;
@@ -246,8 +244,8 @@ bool ConstString::Equals(const ConstString &lhs, const ConstString &rhs,
return true;
// Since the pointers weren't equal, and identical ConstStrings always have
- // identical pointers,
- // the result must be false for case sensitive equality test.
+ // identical pointers, the result must be false for case sensitive equality
+ // test.
if (case_sensitive)
return false;
diff --git a/source/Utility/DataBufferHeap.cpp b/source/Utility/DataBufferHeap.cpp
index aa1c3d37ae62..e686ee8d35e5 100644
--- a/source/Utility/DataBufferHeap.cpp
+++ b/source/Utility/DataBufferHeap.cpp
@@ -22,8 +22,7 @@ using namespace lldb_private;
DataBufferHeap::DataBufferHeap() : m_data() {}
//----------------------------------------------------------------------
-// Initialize this class with "n" characters and fill the buffer
-// with "ch".
+// Initialize this class with "n" characters and fill the buffer with "ch".
//----------------------------------------------------------------------
DataBufferHeap::DataBufferHeap(lldb::offset_t n, uint8_t ch) : m_data() {
if (n < m_data.max_size())
@@ -31,8 +30,7 @@ DataBufferHeap::DataBufferHeap(lldb::offset_t n, uint8_t ch) : m_data() {
}
//----------------------------------------------------------------------
-// Initialize this class with a copy of the "n" bytes from the "bytes"
-// buffer.
+// Initialize this class with a copy of the "n" bytes from the "bytes" buffer.
//----------------------------------------------------------------------
DataBufferHeap::DataBufferHeap(const void *src, lldb::offset_t src_len)
: m_data() {
@@ -40,22 +38,21 @@ DataBufferHeap::DataBufferHeap(const void *src, lldb::offset_t src_len)
}
//----------------------------------------------------------------------
-// Virtual destructor since this class inherits from a pure virtual
-// base class.
+// Virtual destructor since this class inherits from a pure virtual base class.
//----------------------------------------------------------------------
DataBufferHeap::~DataBufferHeap() = default;
//----------------------------------------------------------------------
-// Return a pointer to the bytes owned by this object, or nullptr if
-// the object contains no bytes.
+// Return a pointer to the bytes owned by this object, or nullptr if the object
+// contains no bytes.
//----------------------------------------------------------------------
uint8_t *DataBufferHeap::GetBytes() {
return (m_data.empty() ? nullptr : m_data.data());
}
//----------------------------------------------------------------------
-// Return a const pointer to the bytes owned by this object, or nullptr
-// if the object contains no bytes.
+// Return a const pointer to the bytes owned by this object, or nullptr if the
+// object contains no bytes.
//----------------------------------------------------------------------
const uint8_t *DataBufferHeap::GetBytes() const {
return (m_data.empty() ? nullptr : m_data.data());
@@ -67,8 +64,8 @@ const uint8_t *DataBufferHeap::GetBytes() const {
uint64_t DataBufferHeap::GetByteSize() const { return m_data.size(); }
//----------------------------------------------------------------------
-// Sets the number of bytes that this object should be able to
-// contain. This can be used prior to copying data into the buffer.
+// Sets the number of bytes that this object should be able to contain. This
+// can be used prior to copying data into the buffer.
//----------------------------------------------------------------------
uint64_t DataBufferHeap::SetByteSize(uint64_t new_size) {
m_data.resize(new_size);
diff --git a/source/Utility/DataEncoder.cpp b/source/Utility/DataEncoder.cpp
index 433a15bc9523..7edee3c2f279 100644
--- a/source/Utility/DataEncoder.cpp
+++ b/source/Utility/DataEncoder.cpp
@@ -34,8 +34,8 @@ DataEncoder::DataEncoder()
m_data_sp() {}
//----------------------------------------------------------------------
-// This constructor allows us to use data that is owned by someone else.
-// The data must stay around as long as this object is valid.
+// This constructor allows us to use data that is owned by someone else. The
+// data must stay around as long as this object is valid.
//----------------------------------------------------------------------
DataEncoder::DataEncoder(void *data, uint32_t length, ByteOrder endian,
uint8_t addr_size)
@@ -43,11 +43,10 @@ DataEncoder::DataEncoder(void *data, uint32_t length, ByteOrder endian,
m_byte_order(endian), m_addr_size(addr_size), m_data_sp() {}
//----------------------------------------------------------------------
-// Make a shared pointer reference to the shared data in "data_sp" and
-// set the endian swapping setting to "swap", and the address size to
-// "addr_size". The shared data reference will ensure the data lives
-// as long as any DataEncoder objects exist that have a reference to
-// this data.
+// Make a shared pointer reference to the shared data in "data_sp" and set the
+// endian swapping setting to "swap", and the address size to "addr_size". The
+// shared data reference will ensure the data lives as long as any DataEncoder
+// objects exist that have a reference to this data.
//----------------------------------------------------------------------
DataEncoder::DataEncoder(const DataBufferSP &data_sp, ByteOrder endian,
uint8_t addr_size)
@@ -59,9 +58,8 @@ DataEncoder::DataEncoder(const DataBufferSP &data_sp, ByteOrder endian,
DataEncoder::~DataEncoder() = default;
//------------------------------------------------------------------
-// Clears the object contents back to a default invalid state, and
-// release any references to shared data that this object may
-// contain.
+// Clears the object contents back to a default invalid state, and release any
+// references to shared data that this object may contain.
//------------------------------------------------------------------
void DataEncoder::Clear() {
m_start = nullptr;
@@ -72,8 +70,8 @@ void DataEncoder::Clear() {
}
//------------------------------------------------------------------
-// If this object contains shared data, this function returns the
-// offset into that shared data. Else zero is returned.
+// If this object contains shared data, this function returns the offset into
+// that shared data. Else zero is returned.
//------------------------------------------------------------------
size_t DataEncoder::GetSharedDataOffset() const {
if (m_start != nullptr) {
@@ -90,13 +88,12 @@ size_t DataEncoder::GetSharedDataOffset() const {
}
//----------------------------------------------------------------------
-// Set the data with which this object will extract from to data
-// starting at BYTES and set the length of the data to LENGTH bytes
-// long. The data is externally owned must be around at least as
-// long as this object points to the data. No copy of the data is
-// made, this object just refers to this data and can extract from
-// it. If this object refers to any shared data upon entry, the
-// reference to that data will be released. Is SWAP is set to true,
+// Set the data with which this object will extract from to data starting at
+// BYTES and set the length of the data to LENGTH bytes long. The data is
+// externally owned must be around at least as long as this object points to
+// the data. No copy of the data is made, this object just refers to this data
+// and can extract from it. If this object refers to any shared data upon
+// entry, the reference to that data will be released. Is SWAP is set to true,
// any data extracted will be endian swapped.
//----------------------------------------------------------------------
uint32_t DataEncoder::SetData(void *bytes, uint32_t length, ByteOrder endian) {
@@ -113,18 +110,17 @@ uint32_t DataEncoder::SetData(void *bytes, uint32_t length, ByteOrder endian) {
}
//----------------------------------------------------------------------
-// Assign the data for this object to be a subrange of the shared
-// data in "data_sp" starting "data_offset" bytes into "data_sp"
-// and ending "data_length" bytes later. If "data_offset" is not
-// a valid offset into "data_sp", then this object will contain no
-// bytes. If "data_offset" is within "data_sp" yet "data_length" is
-// too large, the length will be capped at the number of bytes
-// remaining in "data_sp". A ref counted pointer to the data in
-// "data_sp" will be made in this object IF the number of bytes this
-// object refers to in greater than zero (if at least one byte was
-// available starting at "data_offset") to ensure the data stays
-// around as long as it is needed. The address size and endian swap
-// settings will remain unchanged from their current settings.
+// Assign the data for this object to be a subrange of the shared data in
+// "data_sp" starting "data_offset" bytes into "data_sp" and ending
+// "data_length" bytes later. If "data_offset" is not a valid offset into
+// "data_sp", then this object will contain no bytes. If "data_offset" is
+// within "data_sp" yet "data_length" is too large, the length will be capped
+// at the number of bytes remaining in "data_sp". A ref counted pointer to the
+// data in "data_sp" will be made in this object IF the number of bytes this
+// object refers to in greater than zero (if at least one byte was available
+// starting at "data_offset") to ensure the data stays around as long as it is
+// needed. The address size and endian swap settings will remain unchanged from
+// their current settings.
//----------------------------------------------------------------------
uint32_t DataEncoder::SetData(const DataBufferSP &data_sp, uint32_t data_offset,
uint32_t data_length) {
@@ -149,8 +145,8 @@ uint32_t DataEncoder::SetData(const DataBufferSP &data_sp, uint32_t data_offset,
uint32_t new_size = GetByteSize();
- // Don't hold a shared pointer to the data buffer if we don't share
- // any valid bytes in the shared buffer.
+ // Don't hold a shared pointer to the data buffer if we don't share any valid
+ // bytes in the shared buffer.
if (new_size == 0)
m_data_sp.reset();
@@ -158,8 +154,8 @@ uint32_t DataEncoder::SetData(const DataBufferSP &data_sp, uint32_t data_offset,
}
//----------------------------------------------------------------------
-// Extract a single unsigned char from the binary data and update
-// the offset pointed to by "offset_ptr".
+// Extract a single unsigned char from the binary data and update the offset
+// pointed to by "offset_ptr".
//
// RETURNS the byte that was extracted, or zero on failure.
//----------------------------------------------------------------------
@@ -208,12 +204,12 @@ uint32_t DataEncoder::PutU64(uint32_t offset, uint64_t value) {
}
//----------------------------------------------------------------------
-// Extract a single integer value from the data and update the offset
-// pointed to by "offset_ptr". The size of the extracted integer
-// is specified by the "byte_size" argument. "byte_size" should have
-// a value >= 1 and <= 8 since the return value is only 64 bits
-// wide. Any "byte_size" values less than 1 or greater than 8 will
-// result in nothing being extracted, and zero being returned.
+// Extract a single integer value from the data and update the offset pointed
+// to by "offset_ptr". The size of the extracted integer is specified by the
+// "byte_size" argument. "byte_size" should have a value >= 1 and <= 8 since
+// the return value is only 64 bits wide. Any "byte_size" values less than 1 or
+// greater than 8 will result in nothing being extracted, and zero being
+// returned.
//
// RETURNS the integer value that was extracted, or zero on failure.
//----------------------------------------------------------------------
diff --git a/source/Utility/DataExtractor.cpp b/source/Utility/DataExtractor.cpp
index 84c5f8191521..947232943aa7 100644
--- a/source/Utility/DataExtractor.cpp
+++ b/source/Utility/DataExtractor.cpp
@@ -126,8 +126,8 @@ DataExtractor::DataExtractor()
m_data_sp(), m_target_byte_size(1) {}
//----------------------------------------------------------------------
-// This constructor allows us to use data that is owned by someone else.
-// The data must stay around as long as this object is valid.
+// This constructor allows us to use data that is owned by someone else. The
+// data must stay around as long as this object is valid.
//----------------------------------------------------------------------
DataExtractor::DataExtractor(const void *data, offset_t length,
ByteOrder endian, uint32_t addr_size,
@@ -143,11 +143,10 @@ DataExtractor::DataExtractor(const void *data, offset_t length,
}
//----------------------------------------------------------------------
-// Make a shared pointer reference to the shared data in "data_sp" and
-// set the endian swapping setting to "swap", and the address size to
-// "addr_size". The shared data reference will ensure the data lives
-// as long as any DataExtractor objects exist that have a reference to
-// this data.
+// Make a shared pointer reference to the shared data in "data_sp" and set the
+// endian swapping setting to "swap", and the address size to "addr_size". The
+// shared data reference will ensure the data lives as long as any
+// DataExtractor objects exist that have a reference to this data.
//----------------------------------------------------------------------
DataExtractor::DataExtractor(const DataBufferSP &data_sp, ByteOrder endian,
uint32_t addr_size,
@@ -162,11 +161,11 @@ DataExtractor::DataExtractor(const DataBufferSP &data_sp, ByteOrder endian,
}
//----------------------------------------------------------------------
-// Initialize this object with a subset of the data bytes in "data".
-// If "data" contains shared data, then a reference to this shared
-// data will added and the shared data will stay around as long
-// as any object contains a reference to that data. The endian
-// swap and address size settings are copied from "data".
+// Initialize this object with a subset of the data bytes in "data". If "data"
+// contains shared data, then a reference to this shared data will added and
+// the shared data will stay around as long as any object contains a reference
+// to that data. The endian swap and address size settings are copied from
+// "data".
//----------------------------------------------------------------------
DataExtractor::DataExtractor(const DataExtractor &data, offset_t offset,
offset_t length, uint32_t target_byte_size /*=1*/)
@@ -210,9 +209,8 @@ const DataExtractor &DataExtractor::operator=(const DataExtractor &rhs) {
DataExtractor::~DataExtractor() = default;
//------------------------------------------------------------------
-// Clears the object contents back to a default invalid state, and
-// release any references to shared data that this object may
-// contain.
+// Clears the object contents back to a default invalid state, and release any
+// references to shared data that this object may contain.
//------------------------------------------------------------------
void DataExtractor::Clear() {
m_start = nullptr;
@@ -223,8 +221,8 @@ void DataExtractor::Clear() {
}
//------------------------------------------------------------------
-// If this object contains shared data, this function returns the
-// offset into that shared data. Else zero is returned.
+// If this object contains shared data, this function returns the offset into
+// that shared data. Else zero is returned.
//------------------------------------------------------------------
size_t DataExtractor::GetSharedDataOffset() const {
if (m_start != nullptr) {
@@ -241,13 +239,12 @@ size_t DataExtractor::GetSharedDataOffset() const {
}
//----------------------------------------------------------------------
-// Set the data with which this object will extract from to data
-// starting at BYTES and set the length of the data to LENGTH bytes
-// long. The data is externally owned must be around at least as
-// long as this object points to the data. No copy of the data is
-// made, this object just refers to this data and can extract from
-// it. If this object refers to any shared data upon entry, the
-// reference to that data will be released. Is SWAP is set to true,
+// Set the data with which this object will extract from to data starting at
+// BYTES and set the length of the data to LENGTH bytes long. The data is
+// externally owned must be around at least as long as this object points to
+// the data. No copy of the data is made, this object just refers to this data
+// and can extract from it. If this object refers to any shared data upon
+// entry, the reference to that data will be released. Is SWAP is set to true,
// any data extracted will be endian swapped.
//----------------------------------------------------------------------
lldb::offset_t DataExtractor::SetData(const void *bytes, offset_t length,
@@ -265,18 +262,16 @@ lldb::offset_t DataExtractor::SetData(const void *bytes, offset_t length,
}
//----------------------------------------------------------------------
-// Assign the data for this object to be a subrange in "data"
-// starting "data_offset" bytes into "data" and ending "data_length"
-// bytes later. If "data_offset" is not a valid offset into "data",
-// then this object will contain no bytes. If "data_offset" is
-// within "data" yet "data_length" is too large, the length will be
-// capped at the number of bytes remaining in "data". If "data"
-// contains a shared pointer to other data, then a ref counted
-// pointer to that data will be made in this object. If "data"
-// doesn't contain a shared pointer to data, then the bytes referred
-// to in "data" will need to exist at least as long as this object
-// refers to those bytes. The address size and endian swap settings
-// are copied from the current values in "data".
+// Assign the data for this object to be a subrange in "data" starting
+// "data_offset" bytes into "data" and ending "data_length" bytes later. If
+// "data_offset" is not a valid offset into "data", then this object will
+// contain no bytes. If "data_offset" is within "data" yet "data_length" is too
+// large, the length will be capped at the number of bytes remaining in "data".
+// If "data" contains a shared pointer to other data, then a ref counted
+// pointer to that data will be made in this object. If "data" doesn't contain
+// a shared pointer to data, then the bytes referred to in "data" will need to
+// exist at least as long as this object refers to those bytes. The address
+// size and endian swap settings are copied from the current values in "data".
//----------------------------------------------------------------------
lldb::offset_t DataExtractor::SetData(const DataExtractor &data,
offset_t data_offset,
@@ -303,18 +298,17 @@ lldb::offset_t DataExtractor::SetData(const DataExtractor &data,
}
//----------------------------------------------------------------------
-// Assign the data for this object to be a subrange of the shared
-// data in "data_sp" starting "data_offset" bytes into "data_sp"
-// and ending "data_length" bytes later. If "data_offset" is not
-// a valid offset into "data_sp", then this object will contain no
-// bytes. If "data_offset" is within "data_sp" yet "data_length" is
-// too large, the length will be capped at the number of bytes
-// remaining in "data_sp". A ref counted pointer to the data in
-// "data_sp" will be made in this object IF the number of bytes this
-// object refers to in greater than zero (if at least one byte was
-// available starting at "data_offset") to ensure the data stays
-// around as long as it is needed. The address size and endian swap
-// settings will remain unchanged from their current settings.
+// Assign the data for this object to be a subrange of the shared data in
+// "data_sp" starting "data_offset" bytes into "data_sp" and ending
+// "data_length" bytes later. If "data_offset" is not a valid offset into
+// "data_sp", then this object will contain no bytes. If "data_offset" is
+// within "data_sp" yet "data_length" is too large, the length will be capped
+// at the number of bytes remaining in "data_sp". A ref counted pointer to the
+// data in "data_sp" will be made in this object IF the number of bytes this
+// object refers to in greater than zero (if at least one byte was available
+// starting at "data_offset") to ensure the data stays around as long as it is
+// needed. The address size and endian swap settings will remain unchanged from
+// their current settings.
//----------------------------------------------------------------------
lldb::offset_t DataExtractor::SetData(const DataBufferSP &data_sp,
offset_t data_offset,
@@ -340,8 +334,8 @@ lldb::offset_t DataExtractor::SetData(const DataBufferSP &data_sp,
size_t new_size = GetByteSize();
- // Don't hold a shared pointer to the data buffer if we don't share
- // any valid bytes in the shared buffer.
+ // Don't hold a shared pointer to the data buffer if we don't share any valid
+ // bytes in the shared buffer.
if (new_size == 0)
m_data_sp.reset();
@@ -349,8 +343,8 @@ lldb::offset_t DataExtractor::SetData(const DataBufferSP &data_sp,
}
//----------------------------------------------------------------------
-// Extract a single unsigned char from the binary data and update
-// the offset pointed to by "offset_ptr".
+// Extract a single unsigned char from the binary data and update the offset
+// pointed to by "offset_ptr".
//
// RETURNS the byte that was extracted, or zero on failure.
//----------------------------------------------------------------------
@@ -362,13 +356,12 @@ uint8_t DataExtractor::GetU8(offset_t *offset_ptr) const {
}
//----------------------------------------------------------------------
-// Extract "count" unsigned chars from the binary data and update the
-// offset pointed to by "offset_ptr". The extracted data is copied into
-// "dst".
+// Extract "count" unsigned chars from the binary data and update the offset
+// pointed to by "offset_ptr". The extracted data is copied into "dst".
//
// RETURNS the non-nullptr buffer pointer upon successful extraction of
-// all the requested bytes, or nullptr when the data is not available in
-// the buffer due to being out of bounds, or insufficient data.
+// all the requested bytes, or nullptr when the data is not available in the
+// buffer due to being out of bounds, or insufficient data.
//----------------------------------------------------------------------
void *DataExtractor::GetU8(offset_t *offset_ptr, void *dst,
uint32_t count) const {
@@ -384,8 +377,8 @@ void *DataExtractor::GetU8(offset_t *offset_ptr, void *dst,
}
//----------------------------------------------------------------------
-// Extract a single uint16_t from the data and update the offset
-// pointed to by "offset_ptr".
+// Extract a single uint16_t from the data and update the offset pointed to by
+// "offset_ptr".
//
// RETURNS the uint16_t that was extracted, or zero on failure.
//----------------------------------------------------------------------
@@ -432,13 +425,12 @@ uint64_t DataExtractor::GetU64_unchecked(offset_t *offset_ptr) const {
}
//----------------------------------------------------------------------
-// Extract "count" uint16_t values from the binary data and update
-// the offset pointed to by "offset_ptr". The extracted data is
-// copied into "dst".
+// Extract "count" uint16_t values from the binary data and update the offset
+// pointed to by "offset_ptr". The extracted data is copied into "dst".
//
// RETURNS the non-nullptr buffer pointer upon successful extraction of
-// all the requested bytes, or nullptr when the data is not available
-// in the buffer due to being out of bounds, or insufficient data.
+// all the requested bytes, or nullptr when the data is not available in the
+// buffer due to being out of bounds, or insufficient data.
//----------------------------------------------------------------------
void *DataExtractor::GetU16(offset_t *offset_ptr, void *void_dst,
uint32_t count) const {
@@ -465,8 +457,8 @@ void *DataExtractor::GetU16(offset_t *offset_ptr, void *void_dst,
}
//----------------------------------------------------------------------
-// Extract a single uint32_t from the data and update the offset
-// pointed to by "offset_ptr".
+// Extract a single uint32_t from the data and update the offset pointed to by
+// "offset_ptr".
//
// RETURNS the uint32_t that was extracted, or zero on failure.
//----------------------------------------------------------------------
@@ -484,13 +476,12 @@ uint32_t DataExtractor::GetU32(offset_t *offset_ptr) const {
}
//----------------------------------------------------------------------
-// Extract "count" uint32_t values from the binary data and update
-// the offset pointed to by "offset_ptr". The extracted data is
-// copied into "dst".
+// Extract "count" uint32_t values from the binary data and update the offset
+// pointed to by "offset_ptr". The extracted data is copied into "dst".
//
// RETURNS the non-nullptr buffer pointer upon successful extraction of
-// all the requested bytes, or nullptr when the data is not available
-// in the buffer due to being out of bounds, or insufficient data.
+// all the requested bytes, or nullptr when the data is not available in the
+// buffer due to being out of bounds, or insufficient data.
//----------------------------------------------------------------------
void *DataExtractor::GetU32(offset_t *offset_ptr, void *void_dst,
uint32_t count) const {
@@ -517,8 +508,8 @@ void *DataExtractor::GetU32(offset_t *offset_ptr, void *void_dst,
}
//----------------------------------------------------------------------
-// Extract a single uint64_t from the data and update the offset
-// pointed to by "offset_ptr".
+// Extract a single uint64_t from the data and update the offset pointed to by
+// "offset_ptr".
//
// RETURNS the uint64_t that was extracted, or zero on failure.
//----------------------------------------------------------------------
@@ -538,9 +529,9 @@ uint64_t DataExtractor::GetU64(offset_t *offset_ptr) const {
//----------------------------------------------------------------------
// GetU64
//
-// Get multiple consecutive 64 bit values. Return true if the entire
-// read succeeds and increment the offset pointed to by offset_ptr, else
-// return false and leave the offset pointed to by offset_ptr unchanged.
+// Get multiple consecutive 64 bit values. Return true if the entire read
+// succeeds and increment the offset pointed to by offset_ptr, else return
+// false and leave the offset pointed to by offset_ptr unchanged.
//----------------------------------------------------------------------
void *DataExtractor::GetU64(offset_t *offset_ptr, void *void_dst,
uint32_t count) const {
@@ -708,10 +699,10 @@ long double DataExtractor::GetLongDouble(offset_t *offset_ptr) const {
}
//------------------------------------------------------------------
-// Extract a single address from the data and update the offset
-// pointed to by "offset_ptr". The size of the extracted address
-// comes from the "this->m_addr_size" member variable and should be
-// set correctly prior to extracting any address values.
+// Extract a single address from the data and update the offset pointed to by
+// "offset_ptr". The size of the extracted address comes from the
+// "this->m_addr_size" member variable and should be set correctly prior to
+// extracting any address values.
//
// RETURNS the address that was extracted, or zero on failure.
//------------------------------------------------------------------
@@ -730,10 +721,10 @@ uint64_t DataExtractor::GetAddress_unchecked(offset_t *offset_ptr) const {
}
//------------------------------------------------------------------
-// Extract a single pointer from the data and update the offset
-// pointed to by "offset_ptr". The size of the extracted pointer
-// comes from the "this->m_addr_size" member variable and should be
-// set correctly prior to extracting any pointer values.
+// Extract a single pointer from the data and update the offset pointed to by
+// "offset_ptr". The size of the extracted pointer comes from the
+// "this->m_addr_size" member variable and should be set correctly prior to
+// extracting any pointer values.
//
// RETURNS the pointer that was extracted, or zero on failure.
//------------------------------------------------------------------
@@ -804,9 +795,9 @@ DataExtractor::CopyByteOrderedData(offset_t src_offset, offset_t src_len,
const uint8_t *src = (const uint8_t *)PeekData(src_offset, src_len);
if (src) {
if (dst_len >= src_len) {
- // We are copying the entire value from src into dst.
- // Calculate how many, if any, zeroes we need for the most
- // significant bytes if "dst_len" is greater than "src_len"...
+ // We are copying the entire value from src into dst. Calculate how many,
+ // if any, zeroes we need for the most significant bytes if "dst_len" is
+ // greater than "src_len"...
const size_t num_zeroes = dst_len - src_len;
if (dst_byte_order == eByteOrderBig) {
// Big endian, so we lead with zeroes...
@@ -863,15 +854,13 @@ DataExtractor::CopyByteOrderedData(offset_t src_offset, offset_t src_len,
}
//----------------------------------------------------------------------
-// Extracts a variable length NULL terminated C string from
-// the data at the offset pointed to by "offset_ptr". The
-// "offset_ptr" will be updated with the offset of the byte that
-// follows the NULL terminator byte.
+// Extracts a variable length NULL terminated C string from the data at the
+// offset pointed to by "offset_ptr". The "offset_ptr" will be updated with
+// the offset of the byte that 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 available
-// bytes, nullptr will be returned and "offset_ptr" will not be
-// updated.
+// If the offset pointed to by "offset_ptr" is out of bounds, or if "length" is
+// non-zero and there aren't enough available bytes, nullptr will be returned
+// and "offset_ptr" will not be updated.
//----------------------------------------------------------------------
const char *DataExtractor::GetCStr(offset_t *offset_ptr) const {
const char *cstr = (const char *)PeekData(*offset_ptr, 1);
@@ -890,23 +879,21 @@ const char *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 nullptr otherwise anyone that
- // would have used the result as a C string can wander into
- // unknown memory...
+ // terminator. Fall through and return nullptr otherwise anyone that would
+ // have used the result as a C string can wander into unknown memory...
}
return nullptr;
}
//----------------------------------------------------------------------
-// Extracts a NULL terminated C string from the fixed length field of
-// length "len" at the offset pointed to by "offset_ptr".
-// The "offset_ptr" will be updated with the offset of the byte that
-// follows the fixed length field.
+// Extracts a NULL terminated C string from the fixed length field of length
+// "len" at the offset pointed to by "offset_ptr". The "offset_ptr" will be
+// updated with the offset of the byte that follows the fixed length field.
//
-// If the offset pointed to by "offset_ptr" is out of bounds, or if
-// the offset plus the length of the field is out of bounds, or if the
-// field does not contain a NULL terminator byte, nullptr will be returned
-// and "offset_ptr" will not be updated.
+// If the offset pointed to by "offset_ptr" is out of bounds, or if the offset
+// plus the length of the field is out of bounds, or if the field does not
+// contain a NULL terminator byte, nullptr will be returned and "offset_ptr"
+// will not be updated.
//----------------------------------------------------------------------
const char *DataExtractor::GetCStr(offset_t *offset_ptr, offset_t len) const {
const char *cstr = (const char *)PeekData(*offset_ptr, len);
@@ -921,22 +908,22 @@ const char *DataExtractor::GetCStr(offset_t *offset_ptr, offset_t len) const {
}
//------------------------------------------------------------------
-// Peeks at a string in the contained data. No verification is done
-// to make sure the entire string lies within the bounds of this
-// object's data, only "offset" is verified to be a valid offset.
+// Peeks at a string in the contained data. No verification is done to make
+// sure the entire string lies within the bounds of this object's data, only
+// "offset" is verified to be a valid offset.
//
-// Returns a valid C string pointer if "offset" is a valid offset in
-// this object's data, else nullptr is returned.
+// Returns a valid C string pointer if "offset" is a valid offset in this
+// object's data, else nullptr is returned.
//------------------------------------------------------------------
const char *DataExtractor::PeekCStr(offset_t offset) const {
return (const char *)PeekData(offset, 1);
}
//----------------------------------------------------------------------
-// Extracts an unsigned LEB128 number from this object's data
-// starting at the offset pointed to by "offset_ptr". The offset
-// pointed to by "offset_ptr" will be updated with the offset of the
-// byte following the last extracted byte.
+// Extracts an unsigned LEB128 number from this object's data starting at the
+// offset pointed to by "offset_ptr". The offset pointed to by "offset_ptr"
+// will be updated with the offset of the byte following the last extracted
+// byte.
//
// Returned the extracted integer value.
//----------------------------------------------------------------------
@@ -968,10 +955,10 @@ uint64_t DataExtractor::GetULEB128(offset_t *offset_ptr) const {
}
//----------------------------------------------------------------------
-// Extracts an signed LEB128 number from this object's data
-// starting at the offset pointed to by "offset_ptr". The offset
-// pointed to by "offset_ptr" will be updated with the offset of the
-// byte following the last extracted byte.
+// Extracts an signed LEB128 number from this object's data starting at the
+// offset pointed to by "offset_ptr". The offset pointed to by "offset_ptr"
+// will be updated with the offset of the byte following the last extracted
+// byte.
//
// Returned the extracted integer value.
//----------------------------------------------------------------------
@@ -1010,10 +997,10 @@ int64_t DataExtractor::GetSLEB128(offset_t *offset_ptr) const {
}
//----------------------------------------------------------------------
-// Skips a ULEB128 number (signed or unsigned) from this object's
-// data starting at the offset pointed to by "offset_ptr". The
-// offset pointed to by "offset_ptr" will be updated with the offset
-// of the byte following the last extracted byte.
+// Skips a ULEB128 number (signed or unsigned) from this object's data starting
+// at the offset pointed to by "offset_ptr". The offset pointed to by
+// "offset_ptr" will be updated with the offset of the byte following the last
+// extracted byte.
//
// Returns the number of bytes consumed during the extraction.
//----------------------------------------------------------------------
@@ -1036,15 +1023,14 @@ uint32_t DataExtractor::Skip_LEB128(offset_t *offset_ptr) const {
//----------------------------------------------------------------------
// Dumps bytes from this object's data to the stream "s" starting
-// "start_offset" bytes into this data, and ending with the byte
-// before "end_offset". "base_addr" will be added to the offset
-// into the dumped data when showing the offset into the data in the
-// output information. "num_per_line" objects of type "type" will
-// be dumped with the option to override the format for each object
-// with "type_format". "type_format" is a printf style formatting
-// string. If "type_format" is nullptr, then an appropriate format
-// string will be used for the supplied "type". If the stream "s"
-// is nullptr, then the output will be send to Log().
+// "start_offset" bytes into this data, and ending with the byte before
+// "end_offset". "base_addr" will be added to the offset into the dumped data
+// when showing the offset into the data in the output information.
+// "num_per_line" objects of type "type" will be dumped with the option to
+// override the format for each object with "type_format". "type_format" is a
+// printf style formatting string. If "type_format" is nullptr, then an
+// appropriate format string will be used for the supplied "type". If the
+// stream "s" is nullptr, then the output will be send to Log().
//----------------------------------------------------------------------
lldb::offset_t DataExtractor::PutToLog(Log *log, offset_t start_offset,
offset_t length, uint64_t base_addr,
@@ -1107,24 +1093,6 @@ lldb::offset_t DataExtractor::PutToLog(Log *log, offset_t start_offset,
return offset; // Return the offset at which we ended up
}
-//----------------------------------------------------------------------
-// DumpUUID
-//
-// Dump out a UUID starting at 'offset' bytes into the buffer
-//----------------------------------------------------------------------
-void DataExtractor::DumpUUID(Stream *s, offset_t offset) const {
- if (s) {
- const uint8_t *uuid_data = PeekData(offset, 16);
- if (uuid_data) {
- lldb_private::UUID uuid(uuid_data, 16);
- uuid.Dump(s);
- } else {
- s->Printf("<not enough data for UUID at offset 0x%8.8" PRIx64 ">",
- offset);
- }
- }
-}
-
size_t DataExtractor::Copy(DataExtractor &dest_data) const {
if (m_data_sp) {
// we can pass along the SP to the data
diff --git a/source/Utility/Environment.cpp b/source/Utility/Environment.cpp
new file mode 100644
index 000000000000..ea20267a2362
--- /dev/null
+++ b/source/Utility/Environment.cpp
@@ -0,0 +1,50 @@
+//===-- Environment.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/Utility/Environment.h"
+
+using namespace lldb_private;
+
+char *Environment::Envp::make_entry(llvm::StringRef Key,
+ llvm::StringRef Value) {
+ const size_t size = Key.size() + 1 /*=*/ + Value.size() + 1 /*\0*/;
+ char *Result = reinterpret_cast<char *>(
+ Allocator.Allocate(sizeof(char) * size, alignof(char)));
+ char *Next = Result;
+
+ Next = std::copy(Key.begin(), Key.end(), Next);
+ *Next++ = '=';
+ Next = std::copy(Value.begin(), Value.end(), Next);
+ *Next++ = '\0';
+
+ return Result;
+}
+
+Environment::Envp::Envp(const Environment &Env) {
+ Data = reinterpret_cast<char **>(
+ Allocator.Allocate(sizeof(char *) * (Env.size() + 1), alignof(char *)));
+ char **Next = Data;
+ for (const auto &KV : Env)
+ *Next++ = make_entry(KV.first(), KV.second);
+ *Next++ = nullptr;
+}
+
+Environment::Environment(const char *const *Env) {
+ if (!Env)
+ return;
+ while (*Env)
+ insert(*Env++);
+}
+
+void Environment::insert(const_iterator first, const_iterator last) {
+ while (first != last) {
+ try_emplace(first->first(), first->second);
+ ++first;
+ }
+}
diff --git a/source/Utility/FastDemangle.cpp b/source/Utility/FastDemangle.cpp
index 90326c5f15c3..d92670a9199b 100644
--- a/source/Utility/FastDemangle.cpp
+++ b/source/Utility/FastDemangle.cpp
@@ -25,7 +25,7 @@
namespace {
-/// @brief Represents the collection of qualifiers on a type
+/// Represents the collection of qualifiers on a type
enum Qualifiers {
QualifierNone = 0,
@@ -37,7 +37,7 @@ enum Qualifiers {
QualifierPointer = 32
};
-/// @brief Categorizes the recognized operators
+/// Categorizes the recognized operators
enum class OperatorKind {
Unary,
@@ -50,23 +50,23 @@ enum class OperatorKind {
NoMatch
};
-/// @brief Represents one of the recognized two-character operator
-/// abbreviations used when parsing operators as names and expressions
+/// 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()
+/// 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
+/// Transient state required while parsing a name
struct NameState {
bool parse_function_params;
@@ -75,12 +75,13 @@ struct NameState {
BufferRange last_name_range;
};
-/// @brief LLDB's fast C++ demangler
+/// 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.
+/// 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.
@@ -91,7 +92,7 @@ public:
// Public API
//----------------------------------------------------
- /// @brief Create a SymbolDemangler
+ /// Create a SymbolDemangler
///
/// The newly created demangler allocates and owns scratch memory sufficient
/// for demangling typical symbols. Additional memory will be allocated if
@@ -107,18 +108,18 @@ public:
m_owns_m_rewrite_ranges = true;
}
- /// @brief Create a SymbolDemangler that uses provided scratch memory
+ /// 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.
+ /// 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_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
@@ -138,8 +139,8 @@ public:
m_owns_buffer = false;
}
- /// @brief Destroys the SymbolDemangler and deallocates any scratch
- /// memory that it owns
+ /// Destroys the SymbolDemangler and deallocates any scratch memory that it
+ /// owns
~SymbolDemangler() {
if (m_owns_buffer)
@@ -153,11 +154,11 @@ public:
int highwater_buffer = 0;
#endif
- /// @brief Parses the provided mangled name and returns a newly allocated
+ /// 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
+ /// @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 successful, and nullptr when demangling fails. The caller is
@@ -200,8 +201,7 @@ private:
if (growth > 1 << 20)
growth = 1 << 20;
- // ... but never grow by less than requested,
- // or 1K, whichever is greater
+ // ... but never grow by less than requested, or 1K, whichever is greater
if (min_growth < 1024)
min_growth = 1024;
if (growth < min_growth)
@@ -282,9 +282,8 @@ private:
if (index == m_rewrite_ranges_size)
break;
- // Affected ranges are either shuffled forward when after the
- // insertion but before the source, or backward when inside the
- // source
+ // Affected ranges are either shuffled forward when after the insertion
+ // but before the source, or backward when inside the source
int candidate_offset = m_rewrite_ranges[index].offset;
if (candidate_offset >= insertion_point_cookie) {
if (candidate_offset < source_range.offset) {
@@ -402,8 +401,7 @@ private:
//----------------------------------------------------
// Rewrite methods
//
- // Write another copy of content already present
- // earlier in the output buffer
+ // Write another copy of content already present earlier in the output buffer
//----------------------------------------------------
void RewriteRange(BufferRange range) {
@@ -436,11 +434,11 @@ private:
//----------------------------------------------------
// TryParse methods
//
- // Provide information with return values instead of
- // writing to the output buffer
+ // Provide information with return values instead of writing to the output
+ // buffer
//
- // Values indicating failure guarantee that the pre-
- // call m_read_ptr is unchanged
+ // Values indicating failure guarantee that the pre- call m_read_ptr is
+ // unchanged
//----------------------------------------------------
int TryParseNumber() {
@@ -820,8 +818,8 @@ private:
}
// <CV-qualifiers> ::= [r] [V] [K]
- // <ref-qualifier> ::= R # & ref-qualifier
- // <ref-qualifier> ::= O # && ref-qualifier
+ // <ref-qualifier> ::= R # & ref-qualifier <ref-qualifier>
+ // ::= O # && ref-qualifier
int TryParseQualifiers(bool allow_cv, bool allow_ro) {
int qualifiers = QualifierNone;
@@ -890,11 +888,10 @@ private:
//----------------------------------------------------
// Parse methods
//
- // Consume input starting from m_read_ptr and produce
- // buffered output at m_write_ptr
+ // Consume input starting from m_read_ptr and produce buffered output at
+ // m_write_ptr
//
- // Failures return false and may leave m_read_ptr in an
- // indeterminate state
+ // Failures return false and may leave m_read_ptr in an indeterminate state
//----------------------------------------------------
bool Parse(char character) {
@@ -932,17 +929,14 @@ private:
// <substitution> ::= S <seq-id> _
// ::= S_
- // <substitution> ::= Sa # ::std::allocator
- // <substitution> ::= Sb # ::std::basic_string
- // <substitution> ::= Ss # ::std::basic_string < char,
+ // <substitution> ::= Sa # ::std::allocator <substitution> ::= Sb #
+ // ::std::basic_string <substitution> ::= Ss # ::std::basic_string < char,
// ::std::char_traits<char>,
// ::std::allocator<char> >
// <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char>
- // >
- // <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char>
- // >
- // <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char>
- // >
+ // > <substitution> ::= So # ::std::basic_ostream<char,
+ // std::char_traits<char> > <substitution> ::= Sd #
+ // ::std::basic_iostream<char, std::char_traits<char> >
bool ParseSubstitution() {
const char *substitution;
@@ -967,7 +961,8 @@ private:
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
+ // perfect here as S_ is the first substitution, S0_ the next and so
+ // forth
int substitution_index = TryParseBase36Number();
if (*m_read_ptr++ != '_') {
#ifdef DEBUG_FAILURES
@@ -984,17 +979,17 @@ private:
// <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E
//
- // <bare-function-type> ::= <signature type>+ # types are possible return
- // type, then parameter types
+ // <bare-function-type> ::= <signature type>+ # 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.
+ // 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 0 // TODO
@@ -1154,8 +1149,8 @@ private:
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
+ // 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);
}
@@ -1193,13 +1188,13 @@ private:
// ::= G <type> # imaginary (C 2000)
// ::= Dp <type> # pack expansion (C++0x)
// ::= U <source-name> <type> # vendor extended type qualifier
- // extension := U <objc-name> <objc-type> # objc-type<identifier>
- // extension := <vector-type> # <vector-type> starts with Dv
+ // extension := U <objc-name> <objc-type> # objc-type<identifier> extension
+ // := <vector-type> # <vector-type> starts with Dv
// <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 +
- // <number of digits in k1> + k1
- // <objc-type> := <source-name> # PU<11+>objcproto 11objc_object<source-name>
- // 11objc_object -> id<source-name>
+ // <number of digits in k1> + k1 <objc-type> := <source-name> #
+ // PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-
+ // name>
bool ParseType() {
#ifdef DEBUG_FAILURES
@@ -1476,8 +1471,8 @@ private:
// ::= <unnamed-type-name>
bool ParseUnqualifiedName(NameState &name_state) {
- // Note that these are detected directly in ParseNestedName for
- // performance rather than switching on the same options twice
+ // Note that these are detected directly in ParseNestedName for performance
+ // rather than switching on the same options twice
char next = *m_read_ptr;
switch (next) {
case 'C':
@@ -1943,7 +1938,8 @@ private:
break;
}
- // Record a substitution candidate for all prefixes, but not the full name
+ // Record a substitution candidate for all prefixes, but not the full
+ // name
if (suppress_substitution)
suppress_substitution = false;
else
@@ -2247,9 +2243,9 @@ private:
if (next == 'E' || next == '\0' || next == '.')
return true;
- // Clang has a bad habit of making unique manglings by just sticking numbers
- // on the end of a symbol,
- // which is ambiguous with malformed source name manglings
+ // Clang has a bad habit of making unique manglings by just sticking
+ // numbers on the end of a symbol, which is ambiguous with malformed source
+ // name manglings
const char *before_clang_uniquing_test = m_read_ptr;
if (TryParseNumber()) {
if (*m_read_ptr == '\0')
diff --git a/source/Utility/FileSpec.cpp b/source/Utility/FileSpec.cpp
index 72f86917b813..b6952f7e3eb0 100644
--- a/source/Utility/FileSpec.cpp
+++ b/source/Utility/FileSpec.cpp
@@ -12,17 +12,15 @@
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/TildeExpressionResolver.h"
-#include "llvm/ADT/SmallString.h" // for SmallString
-#include "llvm/ADT/SmallVector.h" // for SmallVectorTemplat...
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h" // for Triple
-#include "llvm/ADT/Twine.h" // for Twine
-#include "llvm/Config/llvm-config.h" // for LLVM_ON_WIN32
-#include "llvm/Support/ErrorOr.h" // for ErrorOr
+#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
-#include "llvm/Support/raw_ostream.h" // for raw_ostream, fs
+#include "llvm/Support/raw_ostream.h"
#include <algorithm> // for replace, min, unique
#include <system_error> // for error_code
@@ -37,113 +35,35 @@ using namespace lldb_private;
namespace {
-static constexpr FileSpec::PathSyntax GetNativeSyntax() {
-#if defined(LLVM_ON_WIN32)
- return FileSpec::ePathSyntaxWindows;
+static constexpr FileSpec::Style GetNativeStyle() {
+#if defined(_WIN32)
+ return FileSpec::Style::windows;
#else
- return FileSpec::ePathSyntaxPosix;
+ return FileSpec::Style::posix;
#endif
}
-bool PathSyntaxIsPosix(FileSpec::PathSyntax syntax) {
- return (syntax == FileSpec::ePathSyntaxPosix ||
- (syntax == FileSpec::ePathSyntaxHostNative &&
- GetNativeSyntax() == FileSpec::ePathSyntaxPosix));
+bool PathStyleIsPosix(FileSpec::Style style) {
+ return (style == FileSpec::Style::posix ||
+ (style == FileSpec::Style::native &&
+ GetNativeStyle() == FileSpec::Style::posix));
}
-const char *GetPathSeparators(FileSpec::PathSyntax syntax) {
- return PathSyntaxIsPosix(syntax) ? "/" : "\\/";
+const char *GetPathSeparators(FileSpec::Style style) {
+ return llvm::sys::path::get_separator(style).data();
}
-char GetPreferredPathSeparator(FileSpec::PathSyntax syntax) {
- return GetPathSeparators(syntax)[0];
+char GetPreferredPathSeparator(FileSpec::Style style) {
+ return GetPathSeparators(style)[0];
}
-bool IsPathSeparator(char value, FileSpec::PathSyntax syntax) {
- return value == '/' || (!PathSyntaxIsPosix(syntax) && value == '\\');
-}
-
-void Normalize(llvm::SmallVectorImpl<char> &path, FileSpec::PathSyntax syntax) {
- if (PathSyntaxIsPosix(syntax))
- return;
-
- std::replace(path.begin(), path.end(), '\\', '/');
- // Windows path can have \\ slashes which can be changed by replace
- // call above to //. Here we remove the duplicate.
- auto iter = std::unique(path.begin(), path.end(), [](char &c1, char &c2) {
- return (c1 == '/' && c2 == '/');
- });
- path.erase(iter, path.end());
-}
-
-void Denormalize(llvm::SmallVectorImpl<char> &path,
- FileSpec::PathSyntax syntax) {
- if (PathSyntaxIsPosix(syntax))
+void Denormalize(llvm::SmallVectorImpl<char> &path, FileSpec::Style style) {
+ if (PathStyleIsPosix(style))
return;
std::replace(path.begin(), path.end(), '/', '\\');
}
-size_t FilenamePos(llvm::StringRef str, FileSpec::PathSyntax syntax) {
- if (str.size() == 2 && IsPathSeparator(str[0], syntax) && str[0] == str[1])
- return 0;
-
- if (str.size() > 0 && IsPathSeparator(str.back(), syntax))
- return str.size() - 1;
-
- size_t pos = str.find_last_of(GetPathSeparators(syntax), str.size() - 1);
-
- if (!PathSyntaxIsPosix(syntax) && pos == llvm::StringRef::npos)
- pos = str.find_last_of(':', str.size() - 2);
-
- if (pos == llvm::StringRef::npos ||
- (pos == 1 && IsPathSeparator(str[0], syntax)))
- return 0;
-
- return pos + 1;
-}
-
-size_t RootDirStart(llvm::StringRef str, FileSpec::PathSyntax syntax) {
- // case "c:/"
- if (!PathSyntaxIsPosix(syntax) &&
- (str.size() > 2 && str[1] == ':' && IsPathSeparator(str[2], syntax)))
- return 2;
-
- // case "//"
- if (str.size() == 2 && IsPathSeparator(str[0], syntax) && str[0] == str[1])
- return llvm::StringRef::npos;
-
- // case "//net"
- if (str.size() > 3 && IsPathSeparator(str[0], syntax) && str[0] == str[1] &&
- !IsPathSeparator(str[2], syntax))
- return str.find_first_of(GetPathSeparators(syntax), 2);
-
- // case "/"
- if (str.size() > 0 && IsPathSeparator(str[0], syntax))
- return 0;
-
- return llvm::StringRef::npos;
-}
-
-size_t ParentPathEnd(llvm::StringRef path, FileSpec::PathSyntax syntax) {
- size_t end_pos = FilenamePos(path, syntax);
-
- bool filename_was_sep =
- path.size() > 0 && IsPathSeparator(path[end_pos], syntax);
-
- // Skip separators except for root dir.
- size_t root_dir_pos = RootDirStart(path.substr(0, end_pos), syntax);
-
- while (end_pos > 0 && (end_pos - 1) != root_dir_pos &&
- IsPathSeparator(path[end_pos - 1], syntax))
- --end_pos;
-
- if (end_pos == 1 && root_dir_pos == 0 && filename_was_sep)
- return llvm::StringRef::npos;
-
- return end_pos;
-}
-
} // end anonymous namespace
void FileSpec::Resolve(llvm::SmallVectorImpl<char> &path) {
@@ -164,28 +84,27 @@ void FileSpec::Resolve(llvm::SmallVectorImpl<char> &path) {
}
}
-FileSpec::FileSpec() : m_syntax(GetNativeSyntax()) {}
+FileSpec::FileSpec() : m_style(GetNativeStyle()) {}
//------------------------------------------------------------------
-// Default constructor that can take an optional full path to a
-// file on disk.
+// Default constructor that can take an optional full path to a file on disk.
//------------------------------------------------------------------
-FileSpec::FileSpec(llvm::StringRef path, bool resolve_path, PathSyntax syntax)
- : m_syntax(syntax) {
- SetFile(path, resolve_path, syntax);
+FileSpec::FileSpec(llvm::StringRef path, bool resolve_path, Style style)
+ : m_style(style) {
+ SetFile(path, resolve_path, style);
}
FileSpec::FileSpec(llvm::StringRef path, bool resolve_path,
const llvm::Triple &Triple)
: FileSpec{path, resolve_path,
- Triple.isOSWindows() ? ePathSyntaxWindows : ePathSyntaxPosix} {}
+ Triple.isOSWindows() ? Style::windows : Style::posix} {}
//------------------------------------------------------------------
// Copy constructor
//------------------------------------------------------------------
FileSpec::FileSpec(const FileSpec &rhs)
: m_directory(rhs.m_directory), m_filename(rhs.m_filename),
- m_is_resolved(rhs.m_is_resolved), m_syntax(rhs.m_syntax) {}
+ m_is_resolved(rhs.m_is_resolved), m_style(rhs.m_style) {}
//------------------------------------------------------------------
// Copy constructor
@@ -200,6 +119,100 @@ FileSpec::FileSpec(const FileSpec *rhs) : m_directory(), m_filename() {
//------------------------------------------------------------------
FileSpec::~FileSpec() {}
+namespace {
+//------------------------------------------------------------------
+/// Safely get a character at the specified index.
+///
+/// @param[in] path
+/// A full, partial, or relative path to a file.
+///
+/// @param[in] i
+/// An index into path which may or may not be valid.
+///
+/// @return
+/// The character at index \a i if the index is valid, or 0 if
+/// the index is not valid.
+//------------------------------------------------------------------
+inline char safeCharAtIndex(const llvm::StringRef &path, size_t i) {
+ if (i < path.size())
+ return path[i];
+ return 0;
+}
+
+//------------------------------------------------------------------
+/// Check if a path needs to be normalized.
+///
+/// Check if a path needs to be normalized. We currently consider a
+/// path to need normalization if any of the following are true
+/// - path contains "/./"
+/// - path contains "/../"
+/// - path contains "//"
+/// - path ends with "/"
+/// Paths that start with "./" or with "../" are not considered to
+/// need normalization since we aren't trying to resolve the path,
+/// we are just trying to remove redundant things from the path.
+///
+/// @param[in] path
+/// A full, partial, or relative path to a file.
+///
+/// @return
+/// Returns \b true if the path needs to be normalized.
+//------------------------------------------------------------------
+bool needsNormalization(const llvm::StringRef &path) {
+ if (path.empty())
+ return false;
+ // We strip off leading "." values so these paths need to be normalized
+ if (path[0] == '.')
+ return true;
+ for (auto i = path.find_first_of("\\/"); i != llvm::StringRef::npos;
+ i = path.find_first_of("\\/", i + 1)) {
+ const auto next = safeCharAtIndex(path, i+1);
+ switch (next) {
+ case 0:
+ // path separator char at the end of the string which should be
+ // stripped unless it is the one and only character
+ return i > 0;
+ case '/':
+ case '\\':
+ // two path separator chars in the middle of a path needs to be
+ // normalized
+ if (i > 0)
+ return true;
+ ++i;
+ break;
+
+ case '.': {
+ const auto next_next = safeCharAtIndex(path, i+2);
+ switch (next_next) {
+ default: break;
+ case 0: return true; // ends with "/."
+ case '/':
+ case '\\':
+ return true; // contains "/./"
+ case '.': {
+ const auto next_next_next = safeCharAtIndex(path, i+3);
+ switch (next_next_next) {
+ default: break;
+ case 0: return true; // ends with "/.."
+ case '/':
+ case '\\':
+ return true; // contains "/../"
+ }
+ break;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return false;
+}
+
+
+}
//------------------------------------------------------------------
// Assignment operator.
//------------------------------------------------------------------
@@ -208,26 +221,25 @@ const FileSpec &FileSpec::operator=(const FileSpec &rhs) {
m_directory = rhs.m_directory;
m_filename = rhs.m_filename;
m_is_resolved = rhs.m_is_resolved;
- m_syntax = rhs.m_syntax;
+ m_style = rhs.m_style;
}
return *this;
}
+void FileSpec::SetFile(llvm::StringRef pathname, bool resolve) {
+ SetFile(pathname, resolve, m_style);
+}
+
//------------------------------------------------------------------
-// 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
-// string values for quick comparison and efficient memory usage.
+// 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 string values for
+// quick comparison and efficient memory usage.
//------------------------------------------------------------------
-void FileSpec::SetFile(llvm::StringRef pathname, bool resolve,
- PathSyntax syntax) {
- // CLEANUP: Use StringRef for string handling. This function is kind of a
- // mess and the unclear semantics of RootDirStart and ParentPathEnd make
- // it very difficult to understand this function. There's no reason this
- // function should be particularly complicated or difficult to understand.
+void FileSpec::SetFile(llvm::StringRef pathname, bool resolve, Style style) {
m_filename.Clear();
m_directory.Clear();
m_is_resolved = false;
- m_syntax = (syntax == ePathSyntaxHostNative) ? GetNativeSyntax() : syntax;
+ m_style = (style == Style::native) ? GetNativeStyle() : style;
if (pathname.empty())
return;
@@ -239,39 +251,41 @@ void FileSpec::SetFile(llvm::StringRef pathname, bool resolve,
m_is_resolved = true;
}
- Normalize(resolved, m_syntax);
+ // Normalize the path by removing ".", ".." and other redundant components.
+ if (needsNormalization(resolved))
+ llvm::sys::path::remove_dots(resolved, true, m_style);
+
+ // Normalize back slashes to forward slashes
+ if (m_style == Style::windows)
+ std::replace(resolved.begin(), resolved.end(), '\\', '/');
- llvm::StringRef resolve_path_ref(resolved.c_str());
- size_t dir_end = ParentPathEnd(resolve_path_ref, m_syntax);
- if (dir_end == 0) {
- m_filename.SetString(resolve_path_ref);
+ if (resolved.empty()) {
+ // If we have no path after normalization set the path to the current
+ // directory. This matches what python does and also a few other path
+ // utilities.
+ m_filename.SetString(".");
return;
}
- m_directory.SetString(resolve_path_ref.substr(0, dir_end));
-
- size_t filename_begin = dir_end;
- size_t root_dir_start = RootDirStart(resolve_path_ref, m_syntax);
- while (filename_begin != llvm::StringRef::npos &&
- filename_begin < resolve_path_ref.size() &&
- filename_begin != root_dir_start &&
- IsPathSeparator(resolve_path_ref[filename_begin], m_syntax))
- ++filename_begin;
- m_filename.SetString((filename_begin == llvm::StringRef::npos ||
- filename_begin >= resolve_path_ref.size())
- ? "."
- : resolve_path_ref.substr(filename_begin));
+ // Split path into filename and directory. We rely on the underlying char
+ // pointer to be nullptr when the components are empty.
+ llvm::StringRef filename = llvm::sys::path::filename(resolved, m_style);
+ if(!filename.empty())
+ m_filename.SetString(filename);
+ llvm::StringRef directory = llvm::sys::path::parent_path(resolved, m_style);
+ if(!directory.empty())
+ m_directory.SetString(directory);
}
void FileSpec::SetFile(llvm::StringRef path, bool resolve,
const llvm::Triple &Triple) {
return SetFile(path, resolve,
- Triple.isOSWindows() ? ePathSyntaxWindows : ePathSyntaxPosix);
+ Triple.isOSWindows() ? Style::windows : Style::posix);
}
//----------------------------------------------------------------------
-// Convert to pointer operator. This allows code to check any FileSpec
-// objects to see if they contain anything valid using code such as:
+// Convert to pointer operator. This allows code to check any FileSpec objects
+// to see if they contain anything valid using code such as:
//
// if (file_spec)
// {}
@@ -279,8 +293,8 @@ void FileSpec::SetFile(llvm::StringRef path, bool resolve,
FileSpec::operator bool() const { return m_filename || m_directory; }
//----------------------------------------------------------------------
-// Logical NOT operator. This allows code to check any FileSpec
-// objects to see if they are invalid using code such as:
+// Logical NOT operator. This allows code to check any FileSpec objects to see
+// if they are invalid using code such as:
//
// if (!file_spec)
// {}
@@ -307,12 +321,10 @@ bool FileSpec::operator==(const FileSpec &rhs) const {
return true;
// TODO: determine if we want to keep this code in here.
- // The code below was added to handle a case where we were
- // trying to set a file and line breakpoint and one path
- // was resolved, and the other not and the directory was
- // in a mount point that resolved to a more complete path:
- // "/tmp/a.c" == "/private/tmp/a.c". I might end up pulling
- // this out...
+ // The code below was added to handle a case where we were trying to set a
+ // file and line breakpoint and one path was resolved, and the other not and
+ // the directory was in a mount point that resolved to a more complete path:
+ // "/tmp/a.c" == "/private/tmp/a.c". I might end up pulling this out...
if (IsResolved() && rhs.IsResolved()) {
// Both paths are resolved, no need to look further...
return false;
@@ -324,8 +336,8 @@ bool FileSpec::operator==(const FileSpec &rhs) const {
if (!IsResolved()) {
if (resolved_lhs.ResolvePath()) {
// This path wasn't resolved but now it is. Check if the resolved
- // directory is the same as our unresolved directory, and if so,
- // we can mark this object as resolved to avoid more future resolves
+ // directory is the same as our unresolved directory, and if so, we can
+ // mark this object as resolved to avoid more future resolves
m_is_resolved = (m_directory == resolved_lhs.m_directory);
} else
return false;
@@ -335,16 +347,16 @@ bool FileSpec::operator==(const FileSpec &rhs) const {
if (!rhs.IsResolved()) {
if (resolved_rhs.ResolvePath()) {
// rhs's path wasn't resolved but now it is. Check if the resolved
- // directory is the same as rhs's unresolved directory, and if so,
- // we can mark this object as resolved to avoid more future resolves
+ // directory is the same as rhs's unresolved directory, and if so, we can
+ // mark this object as resolved to avoid more future resolves
rhs.m_is_resolved = (rhs.m_directory == resolved_rhs.m_directory);
} else
return false;
}
- // If we reach this point in the code we were able to resolve both paths
- // and since we only resolve the paths if the basenames are equal, then
- // we can just check if both directories are equal...
+ // If we reach this point in the code we were able to resolve both paths and
+ // since we only resolve the paths if the basenames are equal, then we can
+ // just check if both directories are equal...
return DirectoryEquals(rhs);
}
@@ -369,8 +381,8 @@ Stream &lldb_private::operator<<(Stream &s, const FileSpec &f) {
}
//------------------------------------------------------------------
-// Clear this object by releasing both the directory and filename
-// string values and making them both the empty string.
+// Clear this object by releasing both the directory and filename string values
+// and making them both the empty string.
//------------------------------------------------------------------
void FileSpec::Clear() {
m_directory.Clear();
@@ -378,15 +390,14 @@ void FileSpec::Clear() {
}
//------------------------------------------------------------------
-// Compare two FileSpec objects. If "full" is true, then both
-// the directory and the filename must match. If "full" is false,
-// then the directory names for "a" and "b" are only compared if
-// they are both non-empty. This allows a FileSpec object to only
-// contain a filename and it can match FileSpec objects that have
-// matching filenames with different paths.
+// Compare two FileSpec objects. If "full" is true, then both the directory and
+// the filename must match. If "full" is false, then the directory names for
+// "a" and "b" are only compared if they are both non-empty. This allows a
+// FileSpec object to only contain a filename and it can match FileSpec objects
+// that have matching filenames with different paths.
//
-// Return -1 if the "a" is less than "b", 0 if "a" is equal to "b"
-// and "1" if "a" is greater than "b".
+// Return -1 if the "a" is less than "b", 0 if "a" is equal to "b" and "1" if
+// "a" is greater than "b".
//------------------------------------------------------------------
int FileSpec::Compare(const FileSpec &a, const FileSpec &b, bool full) {
int result = 0;
@@ -396,10 +407,10 @@ int FileSpec::Compare(const FileSpec &a, const FileSpec &b, bool full) {
// If full is true, then we must compare both the directory and filename.
- // If full is false, then if either directory is empty, then we match on
- // the basename only, and if both directories have valid values, we still
- // do a full compare. This allows for matching when we just have a filename
- // in one of the FileSpec objects.
+ // If full is false, then if either directory is empty, then we match on the
+ // basename only, and if both directories have valid values, we still do a
+ // full compare. This allows for matching when we just have a filename in one
+ // of the FileSpec objects.
if (full || (a.m_directory && b.m_directory)) {
result = ConstString::Compare(a.m_directory, b.m_directory, case_sensitive);
@@ -409,118 +420,33 @@ int FileSpec::Compare(const FileSpec &a, const FileSpec &b, bool full) {
return ConstString::Compare(a.m_filename, b.m_filename, case_sensitive);
}
-bool FileSpec::Equal(const FileSpec &a, const FileSpec &b, bool full,
- bool remove_backups) {
- static ConstString g_dot_string(".");
- static ConstString g_dot_dot_string("..");
-
+bool FileSpec::Equal(const FileSpec &a, const FileSpec &b, bool full) {
// case sensitivity of equality test
const bool case_sensitive = a.IsCaseSensitive() || b.IsCaseSensitive();
-
- bool filenames_equal = ConstString::Equals(a.m_filename,
- b.m_filename,
- case_sensitive);
-
- // The only way two FileSpecs can be equal if their filenames are
- // unequal is if we are removing backups and one or the other filename
- // is a backup string:
-
- if (!filenames_equal && !remove_backups)
- return false;
- bool last_component_is_dot = ConstString::Equals(a.m_filename, g_dot_string)
- || ConstString::Equals(a.m_filename,
- g_dot_dot_string)
- || ConstString::Equals(b.m_filename,
- g_dot_string)
- || ConstString::Equals(b.m_filename,
- g_dot_dot_string);
+ const bool filenames_equal = ConstString::Equals(a.m_filename,
+ b.m_filename,
+ case_sensitive);
- if (!filenames_equal && !last_component_is_dot)
+ if (!filenames_equal)
return false;
if (!full && (a.GetDirectory().IsEmpty() || b.GetDirectory().IsEmpty()))
return filenames_equal;
- if (remove_backups == false)
- return a == b;
-
- if (a == b)
- return true;
-
- return Equal(a.GetNormalizedPath(), b.GetNormalizedPath(), full, false);
-}
-
-FileSpec FileSpec::GetNormalizedPath() const {
- // Fast path. Do nothing if the path is not interesting.
- if (!m_directory.GetStringRef().contains(".") &&
- !m_directory.GetStringRef().contains("//") &&
- m_filename.GetStringRef() != ".." && m_filename.GetStringRef() != ".")
- return *this;
-
- llvm::SmallString<64> path, result;
- const bool normalize = false;
- GetPath(path, normalize);
- llvm::StringRef rest(path);
-
- // We will not go below root dir.
- size_t root_dir_start = RootDirStart(path, m_syntax);
- const bool absolute = root_dir_start != llvm::StringRef::npos;
- if (absolute) {
- result += rest.take_front(root_dir_start + 1);
- rest = rest.drop_front(root_dir_start + 1);
- } else {
- if (m_syntax == ePathSyntaxWindows && path.size() > 2 && path[1] == ':') {
- result += rest.take_front(2);
- rest = rest.drop_front(2);
- }
- }
-
- bool anything_added = false;
- llvm::SmallVector<llvm::StringRef, 0> components, processed;
- rest.split(components, '/', -1, false);
- processed.reserve(components.size());
- for (auto component : components) {
- if (component == ".")
- continue; // Skip these.
- if (component != "..") {
- processed.push_back(component);
- continue; // Regular file name.
- }
- if (!processed.empty()) {
- processed.pop_back();
- continue; // Dots. Go one level up if we can.
- }
- if (absolute)
- continue; // We're at the top level. Cannot go higher than that. Skip.
-
- result += component; // We're a relative path. We need to keep these.
- result += '/';
- anything_added = true;
- }
- for (auto component : processed) {
- result += component;
- result += '/';
- anything_added = true;
- }
- if (anything_added)
- result.pop_back(); // Pop last '/'.
- else if (result.empty())
- result = ".";
-
- return FileSpec(result, false, m_syntax);
+ return a == b;
}
//------------------------------------------------------------------
-// Dump the object to the supplied stream. If the object contains
-// a valid directory name, it will be displayed followed by a
-// directory delimiter, and the filename.
+// Dump the object to the supplied stream. If the object contains a valid
+// directory name, it will be displayed followed by a directory delimiter, and
+// the filename.
//------------------------------------------------------------------
void FileSpec::Dump(Stream *s) const {
if (s) {
std::string path{GetPath(true)};
s->PutCString(path);
- char path_separator = GetPreferredPathSeparator(m_syntax);
+ char path_separator = GetPreferredPathSeparator(m_style);
if (!m_filename && !path.empty() && path.back() != path_separator)
s->PutChar(path_separator);
}
@@ -557,8 +483,7 @@ bool FileSpec::ResolveExecutableLocation() {
return true;
else {
// If FindProgramByName found the file, it returns the directory +
- // filename in its return results.
- // We need to separate them.
+ // filename in its return results. We need to separate them.
FileSpec tmp_file(dir_ref.data(), false);
if (tmp_file.Exists()) {
m_directory = tmp_file.m_directory;
@@ -588,7 +513,7 @@ uint64_t FileSpec::GetByteSize() const {
return Size;
}
-FileSpec::PathSyntax FileSpec::GetPathSyntax() const { return m_syntax; }
+FileSpec::Style FileSpec::GetPathStyle() const { return m_style; }
uint32_t FileSpec::GetPermissions() const {
namespace fs = llvm::sys::fs;
@@ -620,9 +545,8 @@ ConstString &FileSpec::GetFilename() { return m_filename; }
const ConstString &FileSpec::GetFilename() const { return m_filename; }
//------------------------------------------------------------------
-// Extract the directory and path into a fixed buffer. This is
-// needed as the directory and path are stored in separate string
-// values.
+// Extract the directory and path into a fixed buffer. This is needed as the
+// directory and path are stored in separate string values.
//------------------------------------------------------------------
size_t FileSpec::GetPath(char *path, size_t path_max_len,
bool denormalize) const {
@@ -648,42 +572,30 @@ void FileSpec::GetPath(llvm::SmallVectorImpl<char> &path,
bool denormalize) const {
path.append(m_directory.GetStringRef().begin(),
m_directory.GetStringRef().end());
- if (m_directory && m_filename &&
- !IsPathSeparator(m_directory.GetStringRef().back(), m_syntax))
- path.insert(path.end(), GetPreferredPathSeparator(m_syntax));
+ // Since the path was normalized and all paths use '/' when stored in these
+ // objects, we don't need to look for the actual syntax specific path
+ // separator, we just look for and insert '/'.
+ if (m_directory && m_filename && m_directory.GetStringRef().back() != '/' &&
+ m_filename.GetStringRef().back() != '/')
+ path.insert(path.end(), '/');
path.append(m_filename.GetStringRef().begin(),
m_filename.GetStringRef().end());
- Normalize(path, m_syntax);
if (denormalize && !path.empty())
- Denormalize(path, m_syntax);
+ Denormalize(path, m_style);
}
ConstString FileSpec::GetFileNameExtension() const {
- if (m_filename) {
- const char *filename = m_filename.GetCString();
- const char *dot_pos = strrchr(filename, '.');
- if (dot_pos && dot_pos[1] != '\0')
- return ConstString(dot_pos + 1);
- }
- return ConstString();
+ return ConstString(
+ llvm::sys::path::extension(m_filename.GetStringRef(), m_style));
}
ConstString FileSpec::GetFileNameStrippingExtension() const {
- const char *filename = m_filename.GetCString();
- if (filename == NULL)
- return ConstString();
-
- const char *dot_pos = strrchr(filename, '.');
- if (dot_pos == NULL)
- return m_filename;
-
- return ConstString(filename, dot_pos - filename);
+ return ConstString(llvm::sys::path::stem(m_filename.GetStringRef(), m_style));
}
//------------------------------------------------------------------
-// Return the size in bytes that this object takes in memory. This
-// returns the size in bytes of this object, not any shared string
-// values it may refer to.
+// Return the size in bytes that this object takes in memory. This returns the
+// size in bytes of this object, not any shared string values it may refer to.
//------------------------------------------------------------------
size_t FileSpec::MemorySize() const {
return m_filename.MemorySize() + m_directory.MemorySize();
@@ -730,91 +642,28 @@ FileSpec::CopyByAppendingPathComponent(llvm::StringRef component) const {
}
FileSpec FileSpec::CopyByRemovingLastPathComponent() const {
- // CLEANUP: Use StringRef for string handling.
- const bool resolve = false;
- if (m_filename.IsEmpty() && m_directory.IsEmpty())
- return FileSpec("", resolve);
- if (m_directory.IsEmpty())
- return FileSpec("", resolve);
- if (m_filename.IsEmpty()) {
- const char *dir_cstr = m_directory.GetCString();
- const char *last_slash_ptr = ::strrchr(dir_cstr, '/');
-
- // check for obvious cases before doing the full thing
- if (!last_slash_ptr)
- return FileSpec("", resolve);
- if (last_slash_ptr == dir_cstr)
- return FileSpec("/", resolve);
-
- size_t last_slash_pos = last_slash_ptr - dir_cstr + 1;
- ConstString new_path(dir_cstr, last_slash_pos);
- return FileSpec(new_path.GetCString(), resolve);
- } else
- return FileSpec(m_directory.GetCString(), resolve);
+ llvm::SmallString<64> current_path;
+ GetPath(current_path, false);
+ if (llvm::sys::path::has_parent_path(current_path, m_style))
+ return FileSpec(llvm::sys::path::parent_path(current_path, m_style), false,
+ m_style);
+ return *this;
}
ConstString FileSpec::GetLastPathComponent() const {
- // CLEANUP: Use StringRef for string handling.
- if (m_filename)
- return m_filename;
- if (m_directory) {
- const char *dir_cstr = m_directory.GetCString();
- const char *last_slash_ptr = ::strrchr(dir_cstr, '/');
- if (last_slash_ptr == NULL)
- return m_directory;
- if (last_slash_ptr == dir_cstr) {
- if (last_slash_ptr[1] == 0)
- return ConstString(last_slash_ptr);
- else
- return ConstString(last_slash_ptr + 1);
- }
- if (last_slash_ptr[1] != 0)
- return ConstString(last_slash_ptr + 1);
- const char *penultimate_slash_ptr = last_slash_ptr;
- while (*penultimate_slash_ptr) {
- --penultimate_slash_ptr;
- if (penultimate_slash_ptr == dir_cstr)
- break;
- if (*penultimate_slash_ptr == '/')
- break;
- }
- ConstString result(penultimate_slash_ptr + 1,
- last_slash_ptr - penultimate_slash_ptr);
- return result;
- }
- return ConstString();
-}
-
-static std::string
-join_path_components(FileSpec::PathSyntax syntax,
- const std::vector<llvm::StringRef> components) {
- std::string result;
- for (size_t i = 0; i < components.size(); ++i) {
- if (components[i].empty())
- continue;
- result += components[i];
- if (i != components.size() - 1 &&
- !IsPathSeparator(components[i].back(), syntax))
- result += GetPreferredPathSeparator(syntax);
- }
-
- return result;
+ llvm::SmallString<64> current_path;
+ GetPath(current_path, false);
+ return ConstString(llvm::sys::path::filename(current_path, m_style));
}
void FileSpec::PrependPathComponent(llvm::StringRef component) {
- if (component.empty())
- return;
-
- const bool resolve = false;
- if (m_filename.IsEmpty() && m_directory.IsEmpty()) {
- SetFile(component, resolve);
- return;
- }
-
- std::string result =
- join_path_components(m_syntax, {component, m_directory.GetStringRef(),
- m_filename.GetStringRef()});
- SetFile(result, resolve, m_syntax);
+ llvm::SmallString<64> new_path(component);
+ llvm::SmallString<64> current_path;
+ GetPath(current_path, false);
+ llvm::sys::path::append(new_path,
+ llvm::sys::path::begin(current_path, m_style),
+ llvm::sys::path::end(current_path), m_style);
+ SetFile(new_path, false, m_style);
}
void FileSpec::PrependPathComponent(const FileSpec &new_path) {
@@ -822,53 +671,24 @@ void FileSpec::PrependPathComponent(const FileSpec &new_path) {
}
void FileSpec::AppendPathComponent(llvm::StringRef component) {
- if (component.empty())
- return;
-
- component = component.drop_while(
- [this](char c) { return IsPathSeparator(c, m_syntax); });
-
- std::string result =
- join_path_components(m_syntax, {m_directory.GetStringRef(),
- m_filename.GetStringRef(), component});
-
- SetFile(result, false, m_syntax);
+ llvm::SmallString<64> current_path;
+ GetPath(current_path, false);
+ llvm::sys::path::append(current_path, m_style, component);
+ SetFile(current_path, false, m_style);
}
void FileSpec::AppendPathComponent(const FileSpec &new_path) {
return AppendPathComponent(new_path.GetPath(false));
}
-void FileSpec::RemoveLastPathComponent() {
- // CLEANUP: Use StringRef for string handling.
-
- const bool resolve = false;
- if (m_filename.IsEmpty() && m_directory.IsEmpty()) {
- SetFile("", resolve);
- return;
- }
- if (m_directory.IsEmpty()) {
- SetFile("", resolve);
- return;
+bool FileSpec::RemoveLastPathComponent() {
+ llvm::SmallString<64> current_path;
+ GetPath(current_path, false);
+ if (llvm::sys::path::has_parent_path(current_path, m_style)) {
+ SetFile(llvm::sys::path::parent_path(current_path, m_style), false);
+ return true;
}
- if (m_filename.IsEmpty()) {
- const char *dir_cstr = m_directory.GetCString();
- const char *last_slash_ptr = ::strrchr(dir_cstr, '/');
-
- // check for obvious cases before doing the full thing
- if (!last_slash_ptr) {
- SetFile("", resolve);
- return;
- }
- if (last_slash_ptr == dir_cstr) {
- SetFile("/", resolve);
- return;
- }
- size_t last_slash_pos = last_slash_ptr - dir_cstr + 1;
- ConstString new_path(dir_cstr, last_slash_pos);
- SetFile(new_path.GetCString(), resolve);
- } else
- SetFile(m_directory.GetCString(), resolve);
+ return false;
}
//------------------------------------------------------------------
/// Returns true if the filespec represents an implementation source
@@ -885,7 +705,7 @@ bool FileSpec::IsSourceImplementationFile() const {
return false;
static RegularExpression g_source_file_regex(llvm::StringRef(
- "^([cC]|[mM]|[mM][mM]|[cC][pP][pP]|[cC]\\+\\+|[cC][xX][xX]|[cC][cC]|["
+ "^.([cC]|[mM]|[mM][mM]|[cC][pP][pP]|[cC]\\+\\+|[cC][xX][xX]|[cC][cC]|["
"cC][pP]|[sS]|[aA][sS][mM]|[fF]|[fF]77|[fF]90|[fF]95|[fF]03|[fF][oO]["
"rR]|[fF][tT][nN]|[fF][pP][pP]|[aA][dD][aA]|[aA][dD][bB]|[aA][dD][sS])"
"$"));
@@ -893,34 +713,23 @@ bool FileSpec::IsSourceImplementationFile() const {
}
bool FileSpec::IsRelative() const {
- const char *dir = m_directory.GetCString();
- llvm::StringRef directory(dir ? dir : "");
+ return !IsAbsolute();
+}
- if (directory.size() > 0) {
- if (PathSyntaxIsPosix(m_syntax)) {
- // If the path doesn't start with '/' or '~', return true
- switch (directory[0]) {
- case '/':
- case '~':
- return false;
- default:
- return true;
- }
- } else {
- if (directory.size() >= 2 && directory[1] == ':')
- return false;
- if (directory[0] == '/')
- return false;
- return true;
- }
- } else if (m_filename) {
- // No directory, just a basename, return true
+bool FileSpec::IsAbsolute() const {
+ llvm::SmallString<64> current_path;
+ GetPath(current_path, false);
+
+ // Early return if the path is empty.
+ if (current_path.empty())
+ return false;
+
+ // We consider paths starting with ~ to be absolute.
+ if (current_path[0] == '~')
return true;
- }
- return false;
-}
-bool FileSpec::IsAbsolute() const { return !FileSpec::IsRelative(); }
+ return llvm::sys::path::is_absolute(current_path, m_style);
+}
void llvm::format_provider<FileSpec>::format(const FileSpec &F,
raw_ostream &Stream,
@@ -944,14 +753,13 @@ void llvm::format_provider<FileSpec>::format(const FileSpec &F,
// Style is either D or empty, either way we need to print the directory.
if (!dir.empty()) {
- // Directory is stored in normalized form, which might be different
- // than preferred form. In order to handle this, we need to cut off
- // the filename, then denormalize, then write the entire denorm'ed
- // directory.
+ // Directory is stored in normalized form, which might be different than
+ // preferred form. In order to handle this, we need to cut off the
+ // filename, then denormalize, then write the entire denorm'ed directory.
llvm::SmallString<64> denormalized_dir = dir;
- Denormalize(denormalized_dir, F.GetPathSyntax());
+ Denormalize(denormalized_dir, F.GetPathStyle());
Stream << denormalized_dir;
- Stream << GetPreferredPathSeparator(F.GetPathSyntax());
+ Stream << GetPreferredPathSeparator(F.GetPathStyle());
}
if (Style.equals_lower("D")) {
diff --git a/source/Utility/History.cpp b/source/Utility/History.cpp
deleted file mode 100644
index 10344b67c635..000000000000
--- a/source/Utility/History.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-//===-- History.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/Utility/History.h"
-
-// C Includes
-#include <inttypes.h>
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Utility/Stream.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-void HistorySourceUInt::DumpHistoryEvent(Stream &strm, HistoryEvent event) {
- strm.Printf("%s %" PRIu64, m_name.c_str(), (uint64_t)((uintptr_t)event));
-}
diff --git a/source/Utility/JSON.cpp b/source/Utility/JSON.cpp
index 9049f596ab9a..7d70034ccabd 100644
--- a/source/Utility/JSON.cpp
+++ b/source/Utility/JSON.cpp
@@ -449,8 +449,7 @@ int JSONParser::GetEscapedChar(bool &was_escaped) {
JSONValue::SP JSONParser::ParseJSONObject() {
// The "JSONParser::Token::ObjectStart" token should have already been
- // consumed
- // by the time this function is called
+ // consumed by the time this function is called
std::unique_ptr<JSONObject> dict_up(new JSONObject());
std::string value;
@@ -481,8 +480,7 @@ JSONValue::SP JSONParser::ParseJSONObject() {
JSONValue::SP JSONParser::ParseJSONArray() {
// The "JSONParser::Token::ObjectStart" token should have already been
- // consumed
- // by the time this function is called
+ // consumed by the time this function is called
std::unique_ptr<JSONArray> array_up(new JSONArray());
std::string value;
diff --git a/source/Utility/Log.cpp b/source/Utility/Log.cpp
index f247124f8d63..eb026fb04752 100644
--- a/source/Utility/Log.cpp
+++ b/source/Utility/Log.cpp
@@ -28,7 +28,7 @@
#include <utility> // for pair
#include <assert.h> // for assert
-#if defined(LLVM_ON_WIN32)
+#if defined(_WIN32)
#include <process.h> // for getpid
#else
#include <unistd.h>
@@ -121,9 +121,9 @@ void Log::Printf(const char *format, ...) {
}
//----------------------------------------------------------------------
-// All logging eventually boils down to this function call. If we have
-// a callback registered, then we call the logging callback. If we have
-// a valid file handle, we also log to the file.
+// All logging eventually boils down to this function call. If we have a
+// callback registered, then we call the logging callback. If we have a valid
+// file handle, we also log to the file.
//----------------------------------------------------------------------
void Log::VAPrintf(const char *format, va_list args) {
llvm::SmallString<64> FinalMessage;
@@ -156,8 +156,7 @@ void Log::VAError(const char *format, va_list args) {
}
//----------------------------------------------------------------------
-// Printing of warnings that are not fatal only if verbose mode is
-// enabled.
+// Printing of warnings that are not fatal only if verbose mode is enabled.
//----------------------------------------------------------------------
void Log::Verbose(const char *format, ...) {
if (!GetVerbose())
@@ -287,7 +286,11 @@ void Log::WriteHeader(llvm::raw_ostream &OS, llvm::StringRef file,
if (options.Test(LLDB_LOG_OPTION_PREPEND_THREAD_NAME)) {
llvm::SmallString<32> thread_name;
llvm::get_thread_name(thread_name);
- OS << llvm::formatv("{0,-16} ", thread_name);
+
+ llvm::SmallString<12> format_str;
+ llvm::raw_svector_ostream format_os(format_str);
+ format_os << "{0,-" << llvm::alignTo<16>(thread_name.size()) << "} ";
+ OS << llvm::formatv(format_str.c_str(), thread_name);
}
if (options.Test(LLDB_LOG_OPTION_BACKTRACE))
@@ -302,8 +305,8 @@ void Log::WriteHeader(llvm::raw_ostream &OS, llvm::StringRef file,
}
void Log::WriteMessage(const std::string &message) {
- // Make a copy of our stream shared pointer in case someone disables our
- // log while we are logging and releases the stream
+ // Make a copy of our stream shared pointer in case someone disables our log
+ // while we are logging and releases the stream
auto stream_sp = GetStream();
if (!stream_sp)
return;
diff --git a/source/Utility/PPC64_DWARF_Registers.h b/source/Utility/PPC64_DWARF_Registers.h
new file mode 100644
index 000000000000..7e3619e0da4d
--- /dev/null
+++ b/source/Utility/PPC64_DWARF_Registers.h
@@ -0,0 +1,127 @@
+//===-- PPC64_DWARF_Registers.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_PPC64_DWARF_Registers_h_
+#define utility_PPC64_DWARF_Registers_h_
+
+#include "lldb/lldb-private.h"
+
+namespace ppc64_dwarf {
+
+enum {
+ dwarf_r0_ppc64 = 0,
+ dwarf_r1_ppc64,
+ dwarf_r2_ppc64,
+ dwarf_r3_ppc64,
+ dwarf_r4_ppc64,
+ dwarf_r5_ppc64,
+ dwarf_r6_ppc64,
+ dwarf_r7_ppc64,
+ dwarf_r8_ppc64,
+ dwarf_r9_ppc64,
+ dwarf_r10_ppc64,
+ dwarf_r11_ppc64,
+ dwarf_r12_ppc64,
+ dwarf_r13_ppc64,
+ dwarf_r14_ppc64,
+ dwarf_r15_ppc64,
+ dwarf_r16_ppc64,
+ dwarf_r17_ppc64,
+ dwarf_r18_ppc64,
+ dwarf_r19_ppc64,
+ dwarf_r20_ppc64,
+ dwarf_r21_ppc64,
+ dwarf_r22_ppc64,
+ dwarf_r23_ppc64,
+ dwarf_r24_ppc64,
+ dwarf_r25_ppc64,
+ dwarf_r26_ppc64,
+ dwarf_r27_ppc64,
+ dwarf_r28_ppc64,
+ dwarf_r29_ppc64,
+ dwarf_r30_ppc64,
+ dwarf_r31_ppc64,
+ dwarf_f0_ppc64,
+ dwarf_f1_ppc64,
+ dwarf_f2_ppc64,
+ dwarf_f3_ppc64,
+ dwarf_f4_ppc64,
+ dwarf_f5_ppc64,
+ dwarf_f6_ppc64,
+ dwarf_f7_ppc64,
+ dwarf_f8_ppc64,
+ dwarf_f9_ppc64,
+ dwarf_f10_ppc64,
+ dwarf_f11_ppc64,
+ dwarf_f12_ppc64,
+ dwarf_f13_ppc64,
+ dwarf_f14_ppc64,
+ dwarf_f15_ppc64,
+ dwarf_f16_ppc64,
+ dwarf_f17_ppc64,
+ dwarf_f18_ppc64,
+ dwarf_f19_ppc64,
+ dwarf_f20_ppc64,
+ dwarf_f21_ppc64,
+ dwarf_f22_ppc64,
+ dwarf_f23_ppc64,
+ dwarf_f24_ppc64,
+ dwarf_f25_ppc64,
+ dwarf_f26_ppc64,
+ dwarf_f27_ppc64,
+ dwarf_f28_ppc64,
+ dwarf_f29_ppc64,
+ dwarf_f30_ppc64,
+ dwarf_f31_ppc64,
+ dwarf_cr_ppc64 = 64,
+ dwarf_fpscr_ppc64,
+ dwarf_msr_ppc64,
+ dwarf_xer_ppc64 = 100,
+ dwarf_lr_ppc64 = 108,
+ dwarf_ctr_ppc64,
+ dwarf_vscr_ppc64,
+ dwarf_vrsave_ppc64 = 356,
+ dwarf_pc_ppc64,
+ dwarf_vr0_ppc64 = 1124,
+ dwarf_vr1_ppc64,
+ dwarf_vr2_ppc64,
+ dwarf_vr3_ppc64,
+ dwarf_vr4_ppc64,
+ dwarf_vr5_ppc64,
+ dwarf_vr6_ppc64,
+ dwarf_vr7_ppc64,
+ dwarf_vr8_ppc64,
+ dwarf_vr9_ppc64,
+ dwarf_vr10_ppc64,
+ dwarf_vr11_ppc64,
+ dwarf_vr12_ppc64,
+ dwarf_vr13_ppc64,
+ dwarf_vr14_ppc64,
+ dwarf_vr15_ppc64,
+ dwarf_vr16_ppc64,
+ dwarf_vr17_ppc64,
+ dwarf_vr18_ppc64,
+ dwarf_vr19_ppc64,
+ dwarf_vr20_ppc64,
+ dwarf_vr21_ppc64,
+ dwarf_vr22_ppc64,
+ dwarf_vr23_ppc64,
+ dwarf_vr24_ppc64,
+ dwarf_vr25_ppc64,
+ dwarf_vr26_ppc64,
+ dwarf_vr27_ppc64,
+ dwarf_vr28_ppc64,
+ dwarf_vr29_ppc64,
+ dwarf_vr30_ppc64,
+ dwarf_vr31_ppc64,
+};
+
+} // namespace ppc64_dwarf
+
+#endif // utility_PPC64_DWARF_Registers_h_
diff --git a/source/Utility/RegularExpression.cpp b/source/Utility/RegularExpression.cpp
index d58b315d0d1d..54f773365d99 100644
--- a/source/Utility/RegularExpression.cpp
+++ b/source/Utility/RegularExpression.cpp
@@ -14,9 +14,8 @@
#include <string>
//----------------------------------------------------------------------
-// Enable enhanced mode if it is available. This allows for things like
-// \d for digit, \s for space, and many more, but it isn't available
-// everywhere.
+// Enable enhanced mode if it is available. This allows for things like \d for
+// digit, \s for space, and many more, but it isn't available everywhere.
//----------------------------------------------------------------------
#if defined(REG_ENHANCED)
#define DEFAULT_COMPILE_FLAGS (REG_ENHANCED | REG_EXTENDED)
@@ -31,8 +30,8 @@ RegularExpression::RegularExpression() : m_re(), m_comp_err(1), m_preg() {
}
//----------------------------------------------------------------------
-// Constructor that compiles "re" using "flags" and stores the
-// resulting compiled regular expression into this object.
+// Constructor that compiles "re" using "flags" and stores the resulting
+// compiled regular expression into this object.
//----------------------------------------------------------------------
RegularExpression::RegularExpression(llvm::StringRef str)
: m_re(), m_comp_err(1), m_preg() {
@@ -55,17 +54,16 @@ operator=(const RegularExpression &rhs) {
//----------------------------------------------------------------------
// Destructor
//
-// Any previously compiled regular expression contained in this
-// object will be freed.
+// Any previously compiled regular expression contained in this object will be
+// freed.
//----------------------------------------------------------------------
RegularExpression::~RegularExpression() { Free(); }
//----------------------------------------------------------------------
-// Compile a regular expression using the supplied regular
-// 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 previously compiled regular
+// Compile a regular expression using the supplied regular 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 previously compiled regular
// expression contained in this object will be freed.
//
// RETURNS
@@ -75,20 +73,19 @@ RegularExpression::~RegularExpression() { Free(); }
bool RegularExpression::Compile(llvm::StringRef str) {
Free();
- // regcomp() on darwin does not recognize "" as a valid regular expression, so
- // we substitute it with an equivalent non-empty one.
+ // regcomp() on darwin does not recognize "" as a valid regular expression,
+ // so we substitute it with an equivalent non-empty one.
m_re = str.empty() ? "()" : str;
m_comp_err = ::regcomp(&m_preg, m_re.c_str(), DEFAULT_COMPILE_FLAGS);
return m_comp_err == 0;
}
//----------------------------------------------------------------------
-// Execute a regular expression match using the compiled regular
-// expression that is already in this object against the match
-// string "s". If any parens are used for regular expression
-// matches "match_count" should indicate the number of regmatch_t
-// values that are present in "match_ptr". The regular expression
-// will be executed using the "execute_flags".
+// Execute a regular expression match using the compiled regular expression
+// that is already in this object against the match string "s". If any parens
+// are used for regular expression matches "match_count" should indicate the
+// number of regmatch_t values that are present in "match_ptr". The regular
+// expression will be executed using the "execute_flags".
//---------------------------------------------------------------------
bool RegularExpression::Execute(llvm::StringRef str, Match *match) const {
int err = 1;
@@ -159,14 +156,12 @@ bool RegularExpression::Match::GetMatchSpanningIndices(
}
//----------------------------------------------------------------------
-// Returns true if the regular expression compiled and is ready
-// for execution.
+// Returns true if the regular expression compiled and is ready for execution.
//----------------------------------------------------------------------
bool RegularExpression::IsValid() const { return m_comp_err == 0; }
//----------------------------------------------------------------------
-// Returns the text that was used to compile the current regular
-// expression.
+// Returns the text that was used to compile the current regular expression.
//----------------------------------------------------------------------
llvm::StringRef RegularExpression::GetText() const { return m_re; }
diff --git a/source/Utility/SelectHelper.cpp b/source/Utility/SelectHelper.cpp
index 200b2ae42759..0f6a96309504 100644
--- a/source/Utility/SelectHelper.cpp
+++ b/source/Utility/SelectHelper.cpp
@@ -109,8 +109,8 @@ lldb_private::Status SelectHelper::Select() {
pair.second.PrepareForSelect();
const lldb::socket_t fd = pair.first;
#if !defined(__APPLE__) && !defined(_MSC_VER)
- lldbassert(fd < FD_SETSIZE);
- if (fd >= FD_SETSIZE) {
+ lldbassert(fd < static_cast<int>(FD_SETSIZE));
+ if (fd >= static_cast<int>(FD_SETSIZE)) {
error.SetErrorStringWithFormat("%i is too large for select()", fd);
return error;
}
@@ -236,8 +236,9 @@ lldb_private::Status SelectHelper::Select() {
error.SetErrorString("timed out");
return error;
} else {
- // One or more descriptors were set, update the FDInfo::select_is_set mask
- // so users can ask the SelectHelper class so clients can call one of:
+ // One or more descriptors were set, update the FDInfo::select_is_set
+ // mask so users can ask the SelectHelper class so clients can call one
+ // of:
for (auto &pair : m_fd_map) {
const int fd = pair.first;
diff --git a/source/Utility/SharingPtr.cpp b/source/Utility/SharingPtr.cpp
index cf32b21f24a6..bdaedfb9b049 100644
--- a/source/Utility/SharingPtr.cpp
+++ b/source/Utility/SharingPtr.cpp
@@ -11,8 +11,8 @@
#if defined(ENABLE_SP_LOGGING)
-// If ENABLE_SP_LOGGING is defined, then log all shared pointer assignments
-// and allow them to be queried using a pointer by a call to:
+// If ENABLE_SP_LOGGING is defined, then log all shared pointer assignments and
+// allow them to be queried using a pointer by a call to:
#include <assert.h>
#include <execinfo.h>
@@ -96,8 +96,8 @@ extern "C" void track_sp(void *sp_this, void *ptr, long use_count) {
namespace lldb {
void dump_sp_refs(void *ptr) {
- // Use a specially crafted call to "track_sp" which will
- // dump info on all live shared pointers that reference "ptr"
+ // Use a specially crafted call to "track_sp" which will dump info on all
+ // live shared pointers that reference "ptr"
track_sp(NULL, ptr, 0);
}
}
diff --git a/source/Utility/Status.cpp b/source/Utility/Status.cpp
index a6a889a71e54..f6dc228391b3 100644
--- a/source/Utility/Status.cpp
+++ b/source/Utility/Status.cpp
@@ -107,9 +107,9 @@ const Status &Status::operator=(const Status &rhs) {
Status::~Status() = default;
//----------------------------------------------------------------------
-// Get the error value as a NULL C string. The error string will be
-// fetched and cached on demand. The cached error string value will
-// remain until the error value is changed or cleared.
+// Get the error value as a NULL C string. The error string will be fetched and
+// cached on demand. The cached error string value will remain until the error
+// value is changed or cleared.
//----------------------------------------------------------------------
const char *Status::AsCString(const char *default_error_str) const {
if (Success())
@@ -161,13 +161,13 @@ Status::ValueType Status::GetError() const { return m_code; }
ErrorType Status::GetType() const { return m_type; }
//----------------------------------------------------------------------
-// Returns true if this object contains a value that describes an
-// error or otherwise non-success result.
+// Returns true if this object contains a value that describes an error or
+// otherwise non-success result.
//----------------------------------------------------------------------
bool Status::Fail() const { return m_code != 0; }
//----------------------------------------------------------------------
-// Set accesssor for the error value to "err" and the type to
+// Set accessor for the error value to "err" and the type to
// "eErrorTypeMachKernel"
//----------------------------------------------------------------------
void Status::SetMachError(uint32_t err) {
@@ -201,7 +201,7 @@ int Status::SetExpressionErrorWithFormat(lldb::ExpressionResults result,
}
//----------------------------------------------------------------------
-// Set accesssor for the error value and type.
+// Set accessor for the error value and type.
//----------------------------------------------------------------------
void Status::SetError(ValueType err, ErrorType type) {
m_code = err;
@@ -210,8 +210,7 @@ void Status::SetError(ValueType err, ErrorType type) {
}
//----------------------------------------------------------------------
-// Update the error value to be "errno" and update the type to
-// be "POSIX".
+// Update the error value to be "errno" and update the type to be "POSIX".
//----------------------------------------------------------------------
void Status::SetErrorToErrno() {
m_code = errno;
@@ -220,8 +219,8 @@ void Status::SetErrorToErrno() {
}
//----------------------------------------------------------------------
-// Update the error value to be LLDB_GENERIC_ERROR and update the type
-// to be "Generic".
+// Update the error value to be LLDB_GENERIC_ERROR and update the type to be
+// "Generic".
//----------------------------------------------------------------------
void Status::SetErrorToGenericError() {
m_code = LLDB_GENERIC_ERROR;
@@ -230,15 +229,15 @@ void Status::SetErrorToGenericError() {
}
//----------------------------------------------------------------------
-// Set accessor for the error string value for a specific error.
-// This allows any string to be supplied as an error explanation.
-// The error string value will remain until the error value is
-// cleared or a new error value/type is assigned.
+// Set accessor for the error string value for a specific error. This allows
+// any string to be supplied as an error explanation. The error string value
+// will remain until the error value is cleared or a new error value/type is
+// assigned.
//----------------------------------------------------------------------
void Status::SetErrorString(llvm::StringRef err_str) {
if (!err_str.empty()) {
- // If we have an error string, we should always at least have an error
- // set to a generic value.
+ // If we have an error string, we should always at least have an error set
+ // to a generic value.
if (Success())
SetErrorToGenericError();
}
@@ -266,8 +265,8 @@ int Status::SetErrorStringWithFormat(const char *format, ...) {
int Status::SetErrorStringWithVarArg(const char *format, va_list args) {
if (format != nullptr && format[0]) {
- // If we have an error string, we should always at least have
- // an error set to a generic value.
+ // If we have an error string, we should always at least have an error set
+ // to a generic value.
if (Success())
SetErrorToGenericError();
@@ -282,8 +281,8 @@ int Status::SetErrorStringWithVarArg(const char *format, va_list args) {
}
//----------------------------------------------------------------------
-// Returns true if the error code in this object is considered a
-// successful return value.
+// Returns true if the error code in this object is considered a successful
+// return value.
//----------------------------------------------------------------------
bool Status::Success() const { return m_code == 0; }
diff --git a/source/Utility/Stream.cpp b/source/Utility/Stream.cpp
index 04edc25b2b09..647a0c0beb5c 100644
--- a/source/Utility/Stream.cpp
+++ b/source/Utility/Stream.cpp
@@ -41,14 +41,12 @@ ByteOrder Stream::SetByteOrder(ByteOrder byte_order) {
}
//------------------------------------------------------------------
-// Put an offset "uval" out to the stream using the printf format
-// in "format".
+// Put an offset "uval" out to the stream using the printf format in "format".
//------------------------------------------------------------------
void Stream::Offset(uint32_t uval, const char *format) { Printf(format, uval); }
//------------------------------------------------------------------
-// Put an SLEB128 "uval" out to the stream using the printf format
-// in "format".
+// Put an SLEB128 "uval" out to the stream using the printf format in "format".
//------------------------------------------------------------------
size_t Stream::PutSLEB128(int64_t sval) {
size_t bytes_written = 0;
@@ -73,8 +71,7 @@ size_t Stream::PutSLEB128(int64_t sval) {
}
//------------------------------------------------------------------
-// Put an ULEB128 "uval" out to the stream using the printf format
-// in "format".
+// Put an ULEB128 "uval" out to the stream using the printf format in "format".
//------------------------------------------------------------------
size_t Stream::PutULEB128(uint64_t uval) {
size_t bytes_written = 0;
@@ -109,16 +106,16 @@ size_t Stream::PutCString(llvm::StringRef str) {
}
//------------------------------------------------------------------
-// Print a double quoted NULL terminated C string to the stream
-// using the printf format in "format".
+// Print a double quoted NULL terminated C string to the stream using the
+// printf format in "format".
//------------------------------------------------------------------
void Stream::QuotedCString(const char *cstr, const char *format) {
Printf(format, cstr);
}
//------------------------------------------------------------------
-// Put an address "addr" out to the stream with optional prefix
-// and suffix strings.
+// Put an address "addr" out to the stream with optional prefix and suffix
+// strings.
//------------------------------------------------------------------
void Stream::Address(uint64_t addr, uint32_t addr_size, const char *prefix,
const char *suffix) {
@@ -132,8 +129,8 @@ void Stream::Address(uint64_t addr, uint32_t addr_size, const char *prefix,
}
//------------------------------------------------------------------
-// Put an address range out to the stream with optional prefix
-// and suffix strings.
+// Put an address range out to the stream with optional prefix and suffix
+// strings.
//------------------------------------------------------------------
void Stream::AddressRange(uint64_t lo_addr, uint64_t hi_addr,
uint32_t addr_size, const char *prefix,
@@ -179,8 +176,8 @@ size_t Stream::PrintfVarArg(const char *format, va_list args) {
size_t Stream::EOL() { return PutChar('\n'); }
//------------------------------------------------------------------
-// Indent the current line using the current indentation level and
-// print an optional string following the indentation spaces.
+// Indent the current line using the current indentation level and print an
+// optional string following the indentation spaces.
//------------------------------------------------------------------
size_t Stream::Indent(const char *s) {
return Printf("%*.*s%s", m_indent_level, m_indent_level, "", s ? s : "");
diff --git a/source/Utility/StringExtractor.cpp b/source/Utility/StringExtractor.cpp
index cf5c7e227448..7528350cf759 100644
--- a/source/Utility/StringExtractor.cpp
+++ b/source/Utility/StringExtractor.cpp
@@ -74,9 +74,8 @@ char StringExtractor::GetChar(char fail_value) {
}
//----------------------------------------------------------------------
-// If a pair of valid hex digits exist at the head of the
-// StringExtractor they are decoded into an unsigned byte and returned
-// by this function
+// If a pair of valid hex digits exist at the head of the StringExtractor they
+// are decoded into an unsigned byte and returned by this function
//
// If there is not a pair of valid hex digits at the head of the
// StringExtractor, it is left unchanged and -1 is returned
@@ -96,12 +95,12 @@ int StringExtractor::DecodeHexU8() {
}
//----------------------------------------------------------------------
-// Extract an unsigned character from two hex ASCII chars in the packet
-// string, or return fail_value on failure
+// Extract an unsigned character from two hex ASCII chars in the packet string,
+// or return fail_value on failure
//----------------------------------------------------------------------
uint8_t StringExtractor::GetHexU8(uint8_t fail_value, bool set_eof_on_fail) {
- // On success, fail_value will be overwritten with the next
- // character in the stream
+ // On success, fail_value will be overwritten with the next character in the
+ // stream
GetHexU8Ex(fail_value, set_eof_on_fail);
return fail_value;
}
@@ -307,8 +306,8 @@ size_t StringExtractor::GetHexBytes(llvm::MutableArrayRef<uint8_t> dest,
}
//----------------------------------------------------------------------
-// Decodes all valid hex encoded bytes at the head of the
-// StringExtractor, limited by dst_len.
+// Decodes all valid hex encoded bytes at the head of the StringExtractor,
+// limited by dst_len.
//
// Returns the number of bytes successfully decoded
//----------------------------------------------------------------------
@@ -390,9 +389,9 @@ size_t StringExtractor::GetHexByteStringTerminatedBy(std::string &str,
bool StringExtractor::GetNameColonValue(llvm::StringRef &name,
llvm::StringRef &value) {
- // Read something in the form of NNNN:VVVV; where NNNN is any character
- // that is not a colon, followed by a ':' character, then a value (one or
- // more ';' chars), followed by a ';'
+ // Read something in the form of NNNN:VVVV; where NNNN is any character that
+ // is not a colon, followed by a ':' character, then a value (one or more ';'
+ // chars), followed by a ';'
if (m_index >= m_packet.size())
return fail();
diff --git a/source/Utility/StringExtractorGDBRemote.cpp b/source/Utility/StringExtractorGDBRemote.cpp
index 818347a42a2c..3cae06df3b1e 100644
--- a/source/Utility/StringExtractorGDBRemote.cpp
+++ b/source/Utility/StringExtractorGDBRemote.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#include "Utility/StringExtractorGDBRemote.h"
+#include "lldb/Utility/StringExtractorGDBRemote.h"
#include <ctype.h> // for isxdigit
#include <string.h>
@@ -482,10 +482,9 @@ lldb_private::Status StringExtractorGDBRemote::GetStatus() {
size_t StringExtractorGDBRemote::GetEscapedBinaryData(std::string &str) {
// Just get the data bytes in the string as
- // GDBRemoteCommunication::CheckForPacket()
- // already removes any 0x7d escaped characters. If any 0x7d characters are
- // left in
- // the packet, then they are supposed to be there...
+ // GDBRemoteCommunication::CheckForPacket() already removes any 0x7d escaped
+ // characters. If any 0x7d characters are left in the packet, then they are
+ // supposed to be there...
str.clear();
const size_t bytes_left = GetBytesLeft();
if (bytes_left > 0) {
@@ -526,9 +525,9 @@ static bool JSONResponseValidator(void *,
case StringExtractorGDBRemote::eResponse:
// JSON that is returned in from JSON query packets is currently always
- // either a dictionary which starts with a '{', or an array which
- // starts with a '['. This is a quick validator to just make sure the
- // response could be valid JSON without having to validate all of the
+ // either a dictionary which starts with a '{', or an array which starts
+ // with a '['. This is a quick validator to just make sure the response
+ // could be valid JSON without having to validate all of the
// JSON content.
switch (response.GetStringRef()[0]) {
case '{':
diff --git a/source/Utility/StringExtractorGDBRemote.h b/source/Utility/StringExtractorGDBRemote.h
deleted file mode 100644
index f4ed642a706e..000000000000
--- a/source/Utility/StringExtractorGDBRemote.h
+++ /dev/null
@@ -1,204 +0,0 @@
-//===-- StringExtractorGDBRemote.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_StringExtractorGDBRemote_h_
-#define utility_StringExtractorGDBRemote_h_
-
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/StringExtractor.h"
-#include "llvm/ADT/StringRef.h" // for StringRef
-
-#include <string>
-
-#include <stddef.h> // for size_t
-#include <stdint.h> // for uint8_t
-
-class StringExtractorGDBRemote : public StringExtractor {
-public:
- typedef bool (*ResponseValidatorCallback)(
- void *baton, const StringExtractorGDBRemote &response);
-
- StringExtractorGDBRemote() : StringExtractor(), m_validator(nullptr) {}
-
- StringExtractorGDBRemote(llvm::StringRef str)
- : StringExtractor(str), m_validator(nullptr) {}
-
- StringExtractorGDBRemote(const char *cstr)
- : StringExtractor(cstr), m_validator(nullptr) {}
-
- StringExtractorGDBRemote(const StringExtractorGDBRemote &rhs)
- : StringExtractor(rhs), m_validator(rhs.m_validator) {}
-
- virtual ~StringExtractorGDBRemote() {}
-
- bool ValidateResponse() const;
-
- void CopyResponseValidator(const StringExtractorGDBRemote &rhs);
-
- void SetResponseValidator(ResponseValidatorCallback callback, void *baton);
-
- void SetResponseValidatorToOKErrorNotSupported();
-
- void SetResponseValidatorToASCIIHexBytes();
-
- void SetResponseValidatorToJSON();
-
- enum ServerPacketType {
- eServerPacketType_nack = 0,
- eServerPacketType_ack,
- eServerPacketType_invalid,
- eServerPacketType_unimplemented,
- eServerPacketType_interrupt, // CTRL+c packet or "\x03"
- eServerPacketType_A, // Program arguments packet
- eServerPacketType_qfProcessInfo,
- eServerPacketType_qsProcessInfo,
- eServerPacketType_qC,
- eServerPacketType_qEcho,
- eServerPacketType_qGroupName,
- eServerPacketType_qHostInfo,
- eServerPacketType_qLaunchGDBServer,
- eServerPacketType_qQueryGDBServer,
- eServerPacketType_qKillSpawnedProcess,
- eServerPacketType_qLaunchSuccess,
- eServerPacketType_qModuleInfo,
- eServerPacketType_qProcessInfoPID,
- eServerPacketType_qSpeedTest,
- eServerPacketType_qUserName,
- eServerPacketType_qGetWorkingDir,
- eServerPacketType_qFileLoadAddress,
- eServerPacketType_QEnvironment,
- eServerPacketType_QEnableErrorStrings,
- eServerPacketType_QLaunchArch,
- eServerPacketType_QSetDisableASLR,
- eServerPacketType_QSetDetachOnError,
- eServerPacketType_QSetSTDIN,
- eServerPacketType_QSetSTDOUT,
- eServerPacketType_QSetSTDERR,
- eServerPacketType_QSetWorkingDir,
- eServerPacketType_QStartNoAckMode,
- eServerPacketType_qPlatform_shell,
- eServerPacketType_qPlatform_mkdir,
- eServerPacketType_qPlatform_chmod,
- eServerPacketType_vFile_open,
- eServerPacketType_vFile_close,
- eServerPacketType_vFile_pread,
- eServerPacketType_vFile_pwrite,
- eServerPacketType_vFile_size,
- eServerPacketType_vFile_mode,
- eServerPacketType_vFile_exists,
- eServerPacketType_vFile_md5,
- eServerPacketType_vFile_stat,
- eServerPacketType_vFile_symlink,
- eServerPacketType_vFile_unlink,
- // debug server packages
- eServerPacketType_QEnvironmentHexEncoded,
- eServerPacketType_QListThreadsInStopReply,
- eServerPacketType_QPassSignals,
- eServerPacketType_QRestoreRegisterState,
- eServerPacketType_QSaveRegisterState,
- eServerPacketType_QSetLogging,
- eServerPacketType_QSetMaxPacketSize,
- eServerPacketType_QSetMaxPayloadSize,
- eServerPacketType_QSetEnableAsyncProfiling,
- eServerPacketType_QSyncThreadState,
- eServerPacketType_QThreadSuffixSupported,
-
- eServerPacketType_jThreadsInfo,
- eServerPacketType_qsThreadInfo,
- eServerPacketType_qfThreadInfo,
- eServerPacketType_qGetPid,
- eServerPacketType_qGetProfileData,
- eServerPacketType_qGDBServerVersion,
- eServerPacketType_qMemoryRegionInfo,
- eServerPacketType_qMemoryRegionInfoSupported,
- eServerPacketType_qProcessInfo,
- eServerPacketType_qRcmd,
- eServerPacketType_qRegisterInfo,
- eServerPacketType_qShlibInfoAddr,
- eServerPacketType_qStepPacketSupported,
- eServerPacketType_qSupported,
- eServerPacketType_qSyncThreadStateSupported,
- eServerPacketType_qThreadExtraInfo,
- eServerPacketType_qThreadStopInfo,
- eServerPacketType_qVAttachOrWaitSupported,
- eServerPacketType_qWatchpointSupportInfo,
- eServerPacketType_qWatchpointSupportInfoSupported,
- eServerPacketType_qXfer_auxv_read,
-
- eServerPacketType_jSignalsInfo,
- eServerPacketType_jModulesInfo,
-
- eServerPacketType_vAttach,
- eServerPacketType_vAttachWait,
- eServerPacketType_vAttachOrWait,
- eServerPacketType_vAttachName,
- eServerPacketType_vCont,
- eServerPacketType_vCont_actions, // vCont?
-
- eServerPacketType_stop_reason, // '?'
-
- eServerPacketType_c,
- eServerPacketType_C,
- eServerPacketType_D,
- eServerPacketType_g,
- eServerPacketType_G,
- eServerPacketType_H,
- eServerPacketType_I, // stdin notification
- eServerPacketType_k,
- eServerPacketType_m,
- eServerPacketType_M,
- eServerPacketType_p,
- eServerPacketType_P,
- eServerPacketType_s,
- eServerPacketType_S,
- eServerPacketType_T,
- eServerPacketType_x,
- eServerPacketType_X,
- eServerPacketType_Z,
- eServerPacketType_z,
-
- eServerPacketType__M,
- eServerPacketType__m,
- eServerPacketType_notify, // '%' notification
-
- eServerPacketType_jTraceStart,
- eServerPacketType_jTraceBufferRead,
- eServerPacketType_jTraceMetaRead,
- eServerPacketType_jTraceStop,
- eServerPacketType_jTraceConfigRead,
- };
-
- ServerPacketType GetServerPacketType() const;
-
- enum ResponseType { eUnsupported = 0, eAck, eNack, eError, eOK, eResponse };
-
- ResponseType GetResponseType() const;
-
- bool IsOKResponse() const;
-
- bool IsUnsupportedResponse() const;
-
- bool IsNormalResponse() const;
-
- bool IsErrorResponse() const;
-
- // Returns zero if the packet isn't a EXX packet where XX are two hex
- // digits. Otherwise the error encoded in XX is returned.
- uint8_t GetError();
-
- lldb_private::Status GetStatus();
-
- size_t GetEscapedBinaryData(std::string &str);
-
-protected:
- ResponseValidatorCallback m_validator;
- void *m_validator_baton;
-};
-
-#endif // utility_StringExtractorGDBRemote_h_
diff --git a/source/Utility/StructuredData.cpp b/source/Utility/StructuredData.cpp
index 492fc585ad07..55f003f245bf 100644
--- a/source/Utility/StructuredData.cpp
+++ b/source/Utility/StructuredData.cpp
@@ -85,8 +85,7 @@ static StructuredData::ObjectSP ParseJSONObject(JSONParser &json_parser) {
static StructuredData::ObjectSP ParseJSONArray(JSONParser &json_parser) {
// The "JSONParser::Token::ObjectStart" token should have already been
- // consumed
- // by the time this function is called
+ // consumed by the time this function is called
auto array_up = llvm::make_unique<StructuredData::Array>();
std::string value;
@@ -162,8 +161,8 @@ StructuredData::Object::GetObjectForDotSeparatedPath(llvm::StringRef path) {
std::string key = match.first.str();
ObjectSP value = this->GetAsDictionary()->GetValueForKey(key);
if (value.get()) {
- // Do we have additional words to descend? If not, return the
- // value we're at right now.
+ // Do we have additional words to descend? If not, return the value
+ // we're at right now.
if (match.second.empty()) {
return value;
} else {
diff --git a/source/Utility/TildeExpressionResolver.cpp b/source/Utility/TildeExpressionResolver.cpp
index 64a771118d6e..ae947059d8b9 100644
--- a/source/Utility/TildeExpressionResolver.cpp
+++ b/source/Utility/TildeExpressionResolver.cpp
@@ -14,12 +14,11 @@
#include "llvm/ADT/STLExtras.h" // for any_of
#include "llvm/ADT/SmallVector.h" // for SmallVectorImpl
-#include "llvm/Config/llvm-config.h" // for LLVM_ON_WIN32
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h" // for fs
-#if !defined(LLVM_ON_WIN32)
+#if !defined(_WIN32)
#include <pwd.h>
#endif
@@ -49,7 +48,7 @@ bool StandardTildeExpressionResolver::ResolvePartial(StringRef Expr,
assert(Expr.empty() || Expr[0] == '~');
Output.clear();
-#if defined(LLVM_ON_WIN32) || defined(__ANDROID__)
+#if defined(_WIN32) || defined(__ANDROID__)
return false;
#else
if (Expr.empty())
diff --git a/source/Utility/UUID.cpp b/source/Utility/UUID.cpp
index 98d4c30cc7f1..623ad69ddc76 100644
--- a/source/Utility/UUID.cpp
+++ b/source/Utility/UUID.cpp
@@ -13,62 +13,44 @@
// Project includes
#include "lldb/Utility/Stream.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Format.h"
// C Includes
#include <ctype.h>
#include <stdio.h>
#include <string.h>
-namespace lldb_private {
+using namespace lldb_private;
-UUID::UUID() { Clear(); }
+// Whether to put a separator after count uuid bytes.
+// For the first 16 bytes we follow the traditional UUID format. After that, we
+// simply put a dash after every 6 bytes.
+static inline bool separate(size_t count) {
+ if (count >= 10)
+ return (count - 10) % 6 == 0;
-UUID::UUID(const UUID &rhs) {
- SetBytes(rhs.m_uuid, rhs.m_num_uuid_bytes);
-}
-
-UUID::UUID(const void *uuid_bytes, uint32_t num_uuid_bytes) {
- SetBytes(uuid_bytes, num_uuid_bytes);
-}
-
-const UUID &UUID::operator=(const UUID &rhs) {
- if (this != &rhs) {
- m_num_uuid_bytes = rhs.m_num_uuid_bytes;
- ::memcpy(m_uuid, rhs.m_uuid, sizeof(m_uuid));
+ switch (count) {
+ case 4:
+ case 6:
+ case 8:
+ return true;
+ default:
+ return false;
}
- return *this;
}
-UUID::~UUID() {}
-
-void UUID::Clear() {
- m_num_uuid_bytes = 16;
- ::memset(m_uuid, 0, sizeof(m_uuid));
-}
+std::string UUID::GetAsString(llvm::StringRef separator) const {
+ std::string result;
+ llvm::raw_string_ostream os(result);
-const void *UUID::GetBytes() const { return m_uuid; }
+ for (auto B : llvm::enumerate(GetBytes())) {
+ if (separate(B.index()))
+ os << separator;
-std::string UUID::GetAsString(const char *separator) const {
- std::string result;
- char buf[256];
- if (!separator)
- separator = "-";
- const uint8_t *u = (const uint8_t *)GetBytes();
- if (sizeof(buf) >
- (size_t)snprintf(buf, sizeof(buf), "%2.2X%2.2X%2.2X%2.2X%s%2.2X%2.2X%s%2."
- "2X%2.2X%s%2.2X%2.2X%s%2.2X%2.2X%2.2X%"
- "2.2X%2.2X%2.2X",
- u[0], u[1], u[2], u[3], separator, u[4], u[5], separator,
- u[6], u[7], separator, u[8], u[9], separator, u[10],
- u[11], u[12], u[13], u[14], u[15])) {
- result.append(buf);
- if (m_num_uuid_bytes == 20) {
- if (sizeof(buf) > (size_t)snprintf(buf, sizeof(buf),
- "%s%2.2X%2.2X%2.2X%2.2X", separator,
- u[16], u[17], u[18], u[19]))
- result.append(buf);
- }
+ os << llvm::format_hex_no_prefix(B.value(), 2, true);
}
+ os.flush();
+
return result;
}
@@ -76,40 +58,6 @@ void UUID::Dump(Stream *s) const {
s->PutCString(GetAsString().c_str());
}
-bool UUID::SetBytes(const void *uuid_bytes, uint32_t num_uuid_bytes) {
- if (uuid_bytes) {
- switch (num_uuid_bytes) {
- case 20:
- m_num_uuid_bytes = 20;
- break;
- case 16:
- m_num_uuid_bytes = 16;
- m_uuid[16] = m_uuid[17] = m_uuid[18] = m_uuid[19] = 0;
- break;
- default:
- // Unsupported UUID byte size
- m_num_uuid_bytes = 0;
- break;
- }
-
- if (m_num_uuid_bytes > 0) {
- ::memcpy(m_uuid, uuid_bytes, m_num_uuid_bytes);
- return true;
- }
- }
- ::memset(m_uuid, 0, sizeof(m_uuid));
- return false;
-}
-
-size_t UUID::GetByteSize() const { return m_num_uuid_bytes; }
-
-bool UUID::IsValid() const {
- return m_uuid[0] || m_uuid[1] || m_uuid[2] || m_uuid[3] || m_uuid[4] ||
- m_uuid[5] || m_uuid[6] || m_uuid[7] || m_uuid[8] || m_uuid[9] ||
- m_uuid[10] || m_uuid[11] || m_uuid[12] || m_uuid[13] || m_uuid[14] ||
- m_uuid[15] || m_uuid[16] || m_uuid[17] || m_uuid[18] || m_uuid[19];
-}
-
static inline int xdigit_to_int(char ch) {
ch = tolower(ch);
if (ch >= 'a' && ch <= 'f')
@@ -117,25 +65,24 @@ static inline int xdigit_to_int(char ch) {
return ch - '0';
}
-llvm::StringRef UUID::DecodeUUIDBytesFromString(llvm::StringRef p,
- ValueType &uuid_bytes,
- uint32_t &bytes_decoded,
- uint32_t num_uuid_bytes) {
- ::memset(uuid_bytes, 0, sizeof(uuid_bytes));
- size_t uuid_byte_idx = 0;
+llvm::StringRef
+UUID::DecodeUUIDBytesFromString(llvm::StringRef p,
+ llvm::SmallVectorImpl<uint8_t> &uuid_bytes,
+ uint32_t num_uuid_bytes) {
+ uuid_bytes.clear();
while (!p.empty()) {
if (isxdigit(p[0]) && isxdigit(p[1])) {
int hi_nibble = xdigit_to_int(p[0]);
int lo_nibble = xdigit_to_int(p[1]);
// Translate the two hex nibble characters into a byte
- uuid_bytes[uuid_byte_idx] = (hi_nibble << 4) + lo_nibble;
+ uuid_bytes.push_back((hi_nibble << 4) + lo_nibble);
// Skip both hex digits
p = p.drop_front(2);
- // Increment the byte that we are decoding within the UUID value
- // and break out if we are done
- if (++uuid_byte_idx == num_uuid_bytes)
+ // Increment the byte that we are decoding within the UUID value and
+ // break out if we are done
+ if (uuid_bytes.size() == num_uuid_bytes)
break;
} else if (p.front() == '-') {
// Skip dashes
@@ -145,11 +92,6 @@ llvm::StringRef UUID::DecodeUUIDBytesFromString(llvm::StringRef p,
break;
}
}
-
- // Clear trailing bytes to 0.
- for (uint32_t i = uuid_byte_idx; i < sizeof(ValueType); i++)
- uuid_bytes[i] = 0;
- bytes_decoded = uuid_byte_idx;
return p;
}
@@ -159,57 +101,17 @@ size_t UUID::SetFromStringRef(llvm::StringRef str, uint32_t num_uuid_bytes) {
// Skip leading whitespace characters
p = p.ltrim();
- uint32_t bytes_decoded = 0;
+ llvm::SmallVector<uint8_t, 20> bytes;
llvm::StringRef rest =
- UUID::DecodeUUIDBytesFromString(p, m_uuid, bytes_decoded, num_uuid_bytes);
+ UUID::DecodeUUIDBytesFromString(p, bytes, num_uuid_bytes);
// If we successfully decoded a UUID, return the amount of characters that
// were consumed
- if (bytes_decoded == num_uuid_bytes) {
- m_num_uuid_bytes = num_uuid_bytes;
+ if (bytes.size() == num_uuid_bytes) {
+ *this = fromData(bytes);
return str.size() - rest.size();
}
// Else return zero to indicate we were not able to parse a UUID value
return 0;
}
-
-size_t UUID::SetFromCString(const char *cstr, uint32_t num_uuid_bytes) {
- if (cstr == NULL)
- return 0;
-
- return SetFromStringRef(cstr, num_uuid_bytes);
-}
-}
-
-bool lldb_private::operator==(const lldb_private::UUID &lhs,
- const lldb_private::UUID &rhs) {
- return ::memcmp(lhs.GetBytes(), rhs.GetBytes(),
- sizeof(lldb_private::UUID::ValueType)) == 0;
-}
-
-bool lldb_private::operator!=(const lldb_private::UUID &lhs,
- const lldb_private::UUID &rhs) {
- return !(lhs == rhs);
-}
-
-bool lldb_private::operator<(const lldb_private::UUID &lhs,
- const lldb_private::UUID &rhs) {
- return ::memcmp(lhs.GetBytes(), rhs.GetBytes(),
- sizeof(lldb_private::UUID::ValueType)) < 0;
-}
-
-bool lldb_private::operator<=(const lldb_private::UUID &lhs,
- const lldb_private::UUID &rhs) {
- return !(lhs > rhs);
-}
-
-bool lldb_private::operator>(const lldb_private::UUID &lhs,
- const lldb_private::UUID &rhs) {
- return rhs < lhs;
-}
-
-bool lldb_private::operator>=(const lldb_private::UUID &lhs,
- const lldb_private::UUID &rhs) {
- return !(lhs < rhs);
-}
diff --git a/source/Utility/VASprintf.cpp b/source/Utility/VASprintf.cpp
index e950fb75cfa0..900d9754a9b4 100644
--- a/source/Utility/VASprintf.cpp
+++ b/source/Utility/VASprintf.cpp
@@ -36,8 +36,8 @@ bool lldb_private::VASprintf(llvm::SmallVectorImpl<char> &buf, const char *fmt,
}
if (size_t(length) >= buf.size()) {
- // The error formatted string didn't fit into our buffer, resize it
- // to the exact needed size, and retry
+ // The error formatted string didn't fit into our buffer, resize it to the
+ // exact needed size, and retry
buf.resize(length + 1);
length = ::vsnprintf(buf.data(), buf.size(), fmt, copy_args);
if (length < 0) {