summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/API/CMakeLists.txt60
-rw-r--r--source/API/SBBreakpoint.cpp87
-rw-r--r--source/API/SBBreakpointLocation.cpp57
-rw-r--r--source/API/SBBreakpointName.cpp685
-rw-r--r--source/API/SBBreakpointOptionCommon.cpp85
-rw-r--r--source/API/SBBreakpointOptionCommon.h37
-rw-r--r--source/API/SBCommandInterpreter.cpp4
-rw-r--r--source/API/SBDebugger.cpp84
-rw-r--r--source/API/SBInstruction.cpp7
-rw-r--r--source/API/SBPlatform.cpp2
-rw-r--r--source/API/SBProcess.cpp10
-rw-r--r--source/API/SBProcessInfo.cpp145
-rw-r--r--source/API/SBTarget.cpp46
-rw-r--r--source/API/SBType.cpp28
-rw-r--r--source/API/SystemInitializerFull.cpp6
-rw-r--r--source/Breakpoint/Breakpoint.cpp30
-rw-r--r--source/Breakpoint/BreakpointID.cpp11
-rw-r--r--source/Breakpoint/BreakpointIDList.cpp35
-rw-r--r--source/Breakpoint/BreakpointList.cpp33
-rw-r--r--source/Breakpoint/BreakpointLocation.cpp76
-rw-r--r--source/Breakpoint/BreakpointLocationList.cpp2
-rw-r--r--source/Breakpoint/BreakpointName.cpp91
-rw-r--r--source/Breakpoint/BreakpointOptions.cpp231
-rw-r--r--source/Breakpoint/CMakeLists.txt1
-rw-r--r--source/Commands/CommandCompletions.cpp8
-rw-r--r--source/Commands/CommandObjectBreakpoint.cpp982
-rw-r--r--source/Commands/CommandObjectBreakpoint.h19
-rw-r--r--source/Commands/CommandObjectBreakpointCommand.cpp72
-rw-r--r--source/Commands/CommandObjectDisassemble.cpp3
-rw-r--r--source/Commands/CommandObjectDisassemble.h6
-rw-r--r--source/Commands/CommandObjectExpression.cpp11
-rw-r--r--source/Commands/CommandObjectFrame.h5
-rw-r--r--source/Commands/CommandObjectPlatform.cpp6
-rw-r--r--source/Commands/CommandObjectSource.cpp9
-rw-r--r--source/Commands/CommandObjectTarget.cpp52
-rw-r--r--source/Commands/CommandObjectTarget.h5
-rw-r--r--source/Commands/CommandObjectThread.cpp8
-rw-r--r--source/Core/Address.cpp2
-rw-r--r--source/Core/AddressRange.cpp1
-rw-r--r--source/Core/CMakeLists.txt1
-rw-r--r--source/Core/Debugger.cpp2
-rw-r--r--source/Core/DumpDataExtractor.cpp7
-rw-r--r--source/Core/FileSpecList.cpp33
-rw-r--r--source/Core/FormatEntity.cpp2
-rw-r--r--source/Core/IOHandler.cpp2
-rw-r--r--source/Core/Module.cpp37
-rw-r--r--source/Core/ModuleList.cpp3
-rw-r--r--source/Core/PluginManager.cpp48
-rw-r--r--source/Core/RegisterValue.cpp3
-rw-r--r--source/Core/Section.cpp8
-rw-r--r--source/Core/Value.cpp31
-rw-r--r--source/Core/ValueObjectDynamicValue.cpp4
-rw-r--r--source/Core/ValueObjectMemory.cpp4
-rw-r--r--source/Core/ValueObjectVariable.cpp6
-rw-r--r--source/Expression/DWARFExpression.cpp35
-rw-r--r--source/Expression/IRExecutionUnit.cpp6
-rw-r--r--source/Expression/IRInterpreter.cpp5
-rw-r--r--source/Host/CMakeLists.txt1
-rw-r--r--source/Host/common/Host.cpp4
-rw-r--r--source/Host/common/HostInfoBase.cpp31
-rw-r--r--source/Host/common/MainLoop.cpp37
-rw-r--r--source/Host/common/NativeProcessProtocol.cpp121
-rw-r--r--source/Host/common/NativeRegisterContext.cpp22
-rw-r--r--source/Host/common/NativeThreadProtocol.cpp26
-rw-r--r--source/Host/common/PseudoTerminal.cpp2
-rw-r--r--source/Host/common/Socket.cpp2
-rw-r--r--source/Host/common/Symbols.cpp48
-rw-r--r--source/Host/common/TaskPool.cpp (renamed from source/Utility/TaskPool.cpp)38
-rw-r--r--source/Host/common/XML.cpp2
-rw-r--r--source/Host/freebsd/Host.cpp9
-rw-r--r--source/Host/macosx/Host.mm4
-rw-r--r--source/Host/macosx/Symbols.cpp21
-rw-r--r--source/Host/posix/HostThreadPosix.cpp2
-rw-r--r--source/Host/posix/ProcessLauncherPosixFork.cpp6
-rw-r--r--source/Initialization/SystemInitializerCommon.cpp4
-rw-r--r--source/Interpreter/Args.cpp5
-rw-r--r--source/Interpreter/CommandInterpreter.cpp100
-rw-r--r--source/Interpreter/CommandObject.cpp7
-rw-r--r--source/Interpreter/OptionGroupArchitecture.cpp11
-rw-r--r--source/Interpreter/OptionGroupFormat.cpp5
-rw-r--r--source/Interpreter/OptionValueDictionary.cpp3
-rw-r--r--source/Interpreter/ScriptInterpreter.cpp5
-rw-r--r--source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp9
-rw-r--r--source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp2
-rw-r--r--source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp11
-rw-r--r--source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp41
-rw-r--r--source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp41
-rw-r--r--source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp99
-rw-r--r--source/Plugins/Architecture/Arm/ArchitectureArm.cpp131
-rw-r--r--source/Plugins/Architecture/Arm/ArchitectureArm.h35
-rw-r--r--source/Plugins/Architecture/Arm/CMakeLists.txt11
-rw-r--r--source/Plugins/Architecture/CMakeLists.txt1
-rw-r--r--source/Plugins/CMakeLists.txt1
-rw-r--r--source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp12
-rw-r--r--source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp4
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp5
-rw-r--r--source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp44
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp357
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangASTSource.h107
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp268
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h17
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp12
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h2
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h1
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp8
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h1
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp1
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp9
-rw-r--r--source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp2
-rw-r--r--source/Plugins/Instruction/ARM/EmulationStateARM.cpp3
-rw-r--r--source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp7
-rw-r--r--source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp7
-rw-r--r--source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp82
-rw-r--r--source/Plugins/Language/CPlusPlus/CMakeLists.txt3
-rw-r--r--source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp39
-rw-r--r--source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp2
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxx.cpp3
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxx.h14
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp107
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp5
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxList.cpp268
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxMap.cpp9
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp61
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp83
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp5
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxVector.cpp3
-rw-r--r--source/Plugins/Language/CPlusPlus/LibStdcpp.cpp7
-rw-r--r--source/Plugins/Language/ObjC/CMakeLists.txt12
-rw-r--r--source/Plugins/Language/ObjC/NSArray.cpp624
-rw-r--r--source/Plugins/Language/ObjC/NSDictionary.cpp319
-rw-r--r--source/Plugins/Language/ObjC/NSSet.cpp84
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp10
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h2
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h2
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp281
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h21
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp24
-rw-r--r--source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp2
-rw-r--r--source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h3
-rw-r--r--source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp2
-rw-r--r--source/Plugins/ObjectFile/ELF/CMakeLists.txt1
-rw-r--r--source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp167
-rw-r--r--source/Plugins/ObjectFile/ELF/ObjectFileELF.h36
-rw-r--r--source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp11
-rw-r--r--source/Plugins/ObjectFile/JIT/ObjectFileJIT.h8
-rw-r--r--source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp5
-rw-r--r--source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp13
-rw-r--r--source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp1
-rw-r--r--source/Plugins/Platform/Android/AdbClient.cpp2
-rw-r--r--source/Plugins/Platform/Android/PlatformAndroid.cpp20
-rw-r--r--source/Plugins/Platform/Android/PlatformAndroid.h3
-rw-r--r--source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp12
-rw-r--r--source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h6
-rw-r--r--source/Plugins/Platform/Linux/PlatformLinux.cpp12
-rw-r--r--source/Plugins/Platform/Linux/PlatformLinux.h6
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp2
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp2
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp2
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformDarwin.cpp21
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp31
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp2
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp2
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp1
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp2
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp2
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm1
-rw-r--r--source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp12
-rw-r--r--source/Plugins/Platform/NetBSD/PlatformNetBSD.h6
-rw-r--r--source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp12
-rw-r--r--source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h6
-rw-r--r--source/Plugins/Platform/POSIX/PlatformPOSIX.cpp7
-rw-r--r--source/Plugins/Platform/POSIX/PlatformPOSIX.h3
-rw-r--r--source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp2
-rw-r--r--source/Plugins/Process/Darwin/MachException.cpp35
-rw-r--r--source/Plugins/Process/Darwin/NativeProcessDarwin.h30
-rw-r--r--source/Plugins/Process/FreeBSD/FreeBSDThread.cpp29
-rw-r--r--source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp16
-rw-r--r--source/Plugins/Process/FreeBSD/POSIXStopInfo.h13
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp26
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessMonitor.cpp6
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h2
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp46
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h2
-rw-r--r--source/Plugins/Process/Linux/CMakeLists.txt3
-rw-r--r--source/Plugins/Process/Linux/NativeProcessLinux.cpp282
-rw-r--r--source/Plugins/Process/Linux/NativeProcessLinux.h9
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp16
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux.h19
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp22
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h3
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp34
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h3
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp26
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h6
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp801
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h149
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp14
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h3
-rwxr-xr-xsource/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp120
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h8
-rw-r--r--source/Plugins/Process/Linux/NativeThreadLinux.cpp42
-rw-r--r--source/Plugins/Process/Linux/NativeThreadLinux.h11
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h2
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp2
-rw-r--r--source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp117
-rw-r--r--source/Plugins/Process/NetBSD/NativeProcessNetBSD.h10
-rw-r--r--source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp4
-rw-r--r--source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h4
-rw-r--r--source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp11
-rw-r--r--source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h3
-rw-r--r--source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp36
-rw-r--r--source/Plugins/Process/NetBSD/NativeThreadNetBSD.h4
-rw-r--r--source/Plugins/Process/Utility/CMakeLists.txt2
-rw-r--r--source/Plugins/Process/Utility/DynamicRegisterInfo.cpp6
-rw-r--r--source/Plugins/Process/Utility/InferiorCallPOSIX.cpp12
-rw-r--r--source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp4
-rw-r--r--source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h2
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h2
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLLDB.cpp8
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMach_arm.cpp16
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMach_i386.cpp12
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp12
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp216
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h82
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp22
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h6
-rw-r--r--source/Plugins/Process/Utility/RegisterContext_mips.h5
-rw-r--r--source/Plugins/Process/Utility/RegisterContext_x86.h39
-rw-r--r--source/Plugins/Process/Utility/RegisterInfoInterface.h5
-rw-r--r--source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp66
-rw-r--r--source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h32
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_i386.h18
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_ppc64le.h476
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_x86_64.h27
-rw-r--r--source/Plugins/Process/Utility/StopInfoMachException.cpp1
-rw-r--r--source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp10
-rw-r--r--source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h210
-rw-r--r--source/Plugins/Process/elf-core/CMakeLists.txt2
-rw-r--r--source/Plugins/Process/elf-core/ProcessElfCore.cpp496
-rw-r--r--source/Plugins/Process/elf-core/ProcessElfCore.h24
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp2
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h7
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp4
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h7
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp5
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h7
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp8
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h8
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp132
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h49
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp4
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h7
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp4
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h7
-rw-r--r--source/Plugins/Process/elf-core/RegisterUtilities.cpp39
-rw-r--r--source/Plugins/Process/elf-core/RegisterUtilities.h110
-rw-r--r--source/Plugins/Process/elf-core/ThreadElfCore.cpp44
-rw-r--r--source/Plugins/Process/elf-core/ThreadElfCore.h29
-rw-r--r--source/Plugins/Process/gdb-remote/CMakeLists.txt5
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp46
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h10
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp49
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h4
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp7
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp329
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h29
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp5
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp2
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp24
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.h9
-rw-r--r--source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp1
-rw-r--r--source/Plugins/Process/mach-core/ProcessMachCore.cpp2
-rw-r--r--source/Plugins/Process/mach-core/ThreadMachCore.cpp2
-rw-r--r--source/Plugins/Process/minidump/MinidumpParser.h3
-rw-r--r--source/Plugins/Process/minidump/ProcessMinidump.h8
-rw-r--r--source/Plugins/Process/minidump/ThreadMinidump.cpp14
-rw-r--r--source/Plugins/Process/minidump/ThreadMinidump.h2
-rw-r--r--source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp54
-rw-r--r--source/Plugins/SymbolFile/DWARF/CMakeLists.txt3
-rw-r--r--source/Plugins/SymbolFile/DWARF/DIERef.cpp2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp30
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp70
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h53
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp12
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp24
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp102
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h6
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp21
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h14
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp37
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp36
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFFormValue.h1
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp99
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h22
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp25
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h9
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp36
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h34
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp142
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h55
-rw-r--r--source/Plugins/SymbolFile/PDB/PDBASTParser.cpp48
-rw-r--r--source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp15
-rw-r--r--source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp21
-rw-r--r--source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp2
-rw-r--r--source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp2
-rw-r--r--source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h5
-rw-r--r--source/Symbol/ArmUnwindInfo.cpp2
-rw-r--r--source/Symbol/ClangASTContext.cpp286
-rw-r--r--source/Symbol/ClangExternalASTSourceCommon.cpp16
-rw-r--r--source/Symbol/CompactUnwindInfo.cpp10
-rw-r--r--source/Symbol/CompilerType.cpp21
-rw-r--r--source/Symbol/DWARFCallFrameInfo.cpp9
-rw-r--r--source/Symbol/JavaASTContext.cpp25
-rw-r--r--source/Symbol/ObjectFile.cpp33
-rw-r--r--source/Symbol/Symtab.cpp29
-rw-r--r--source/Symbol/Type.cpp2
-rw-r--r--source/Symbol/TypeSystem.cpp40
-rw-r--r--source/Symbol/Variable.cpp8
-rw-r--r--source/Target/PathMappingList.cpp1
-rw-r--r--source/Target/Platform.cpp52
-rw-r--r--source/Target/Process.cpp39
-rw-r--r--source/Target/ProcessLaunchInfo.cpp14
-rw-r--r--source/Target/RegisterContext.cpp136
-rw-r--r--source/Target/StackFrame.cpp4
-rw-r--r--source/Target/StopInfo.cpp54
-rw-r--r--source/Target/Target.cpp257
-rw-r--r--source/Target/Thread.cpp8
-rw-r--r--source/Target/ThreadPlanStepInRange.cpp8
-rw-r--r--source/Target/ThreadPlanTracer.cpp3
-rw-r--r--source/Target/UnixSignals.cpp2
-rw-r--r--source/Utility/ArchSpec.cpp (renamed from source/Core/ArchSpec.cpp)237
-rw-r--r--source/Utility/CMakeLists.txt46
-rw-r--r--source/Utility/DataEncoder.cpp44
-rw-r--r--source/Utility/DataExtractor.cpp111
-rw-r--r--source/Utility/FileSpec.cpp12
-rw-r--r--source/Utility/JSON.cpp5
-rw-r--r--source/Utility/Log.cpp19
-rw-r--r--source/Utility/Logging.cpp2
-rw-r--r--source/Utility/PPC64LE_DWARF_Registers.h194
-rw-r--r--source/Utility/PPC64LE_ehframe_Registers.h194
-rw-r--r--source/Utility/SelectHelper.cpp1
-rw-r--r--source/Utility/Status.cpp10
-rw-r--r--source/Utility/StringExtractorGDBRemote.cpp1
-rw-r--r--source/Utility/StructuredData.cpp1
-rw-r--r--source/Utility/UUID.cpp28
-rw-r--r--source/Utility/UriParser.cpp4
-rw-r--r--source/lldb.cpp12
350 files changed, 10433 insertions, 4881 deletions
diff --git a/source/API/CMakeLists.txt b/source/API/CMakeLists.txt
index 9dd21bcf2aaf6..c96e59be5a44a 100644
--- a/source/API/CMakeLists.txt
+++ b/source/API/CMakeLists.txt
@@ -2,10 +2,6 @@ if ( CMAKE_SYSTEM_NAME MATCHES "Windows" )
add_definitions( -DEXPORT_LIBLLDB )
endif()
-# Include this so that add_lldb_library() has the list of dependencies
-# for liblldb to link against
-include(${LLDB_PROJECT_ROOT}/cmake/LLDBDependencies.cmake)
-
option(LLDB_BUILD_FRAMEWORK "Build the Darwin LLDB.framework" Off)
if(LLDB_BUILD_FRAMEWORK AND CMAKE_VERSION VERSION_LESS 3.7)
@@ -24,6 +20,8 @@ add_lldb_library(liblldb SHARED
SBBlock.cpp
SBBreakpoint.cpp
SBBreakpointLocation.cpp
+ SBBreakpointName.cpp
+ SBBreakpointOptionCommon.cpp
SBBroadcaster.cpp
SBCommandInterpreter.cpp
SBCommandReturnObject.cpp
@@ -53,6 +51,7 @@ add_lldb_library(liblldb SHARED
SBModuleSpec.cpp
SBPlatform.cpp
SBProcess.cpp
+ SBProcessInfo.cpp
SBQueue.cpp
SBQueueItem.cpp
SBSection.cpp
@@ -109,9 +108,17 @@ if (LLVM_ENABLE_WERROR)
set_property(SOURCE ${LLDB_WRAP_PYTHON} APPEND_STRING PROPERTY COMPILE_FLAGS " -w")
endif()
endif()
+set_source_files_properties(${LLDB_WRAP_PYTHON} PROPERTIES GENERATED 1)
+if (CLANG_CL)
+ set_property(SOURCE ${LLDB_WRAP_PYTHON} APPEND_STRING
+ PROPERTY COMPILE_FLAGS " -Wno-unused-function")
+endif()
+if (LLVM_COMPILER_IS_GCC_COMPATIBLE AND
+ NOT "${CMAKE_SYSTEM_NAME}" MATCHES "Darwin")
+ set_property(SOURCE ${LLDB_WRAP_PYTHON} APPEND_STRING
+ PROPERTY COMPILE_FLAGS " -Wno-sequence-point -Wno-cast-qual")
+endif ()
-# This should not be part of LLDBDependencies.cmake, because we don't
-# want every single library taking a dependency on the script interpreters.
target_link_libraries(liblldb PRIVATE
lldbPluginScriptInterpreterNone
lldbPluginScriptInterpreterPython
@@ -153,22 +160,45 @@ endif()
if (LLDB_WRAP_PYTHON)
add_dependencies(liblldb swig_wrapper)
endif()
-target_link_libraries(liblldb PRIVATE ${LLDB_SYSTEM_LIBS})
if(LLDB_BUILD_FRAMEWORK)
- file(GLOB public_headers ${LLDB_SOURCE_DIR}/include/lldb/API/*.h)
+ 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 "${public_headers}")
+ 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()
- add_custom_command(TARGET liblldb POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_FILE_DIR:liblldb>/Versions/${LLDB_FRAMEWORK_VERSION}
- COMMAND ${CMAKE_COMMAND} -E copy_directory ${LLDB_SOURCE_DIR}/include/lldb/API $<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 copy_directory ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/clang/${LLDB_VERSION} $<TARGET_FILE_DIR:liblldb>/Resources/Clang
- )
endif()
diff --git a/source/API/SBBreakpoint.cpp b/source/API/SBBreakpoint.cpp
index bf9603248d71f..6a0ff9536c2c2 100644
--- a/source/API/SBBreakpoint.cpp
+++ b/source/API/SBBreakpoint.cpp
@@ -37,6 +37,8 @@
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Stream.h"
+#include "SBBreakpointOptionCommon.h"
+
#include "lldb/lldb-enumerations.h"
#include "llvm/ADT/STLExtras.h"
@@ -44,21 +46,6 @@
using namespace lldb;
using namespace lldb_private;
-struct CallbackData {
- SBBreakpoint::BreakpointHitCallback callback;
- void *callback_baton;
-};
-
-class SBBreakpointCallbackBaton : public TypedBaton<CallbackData> {
-public:
- SBBreakpointCallbackBaton(SBBreakpoint::BreakpointHitCallback callback,
- void *baton)
- : TypedBaton(llvm::make_unique<CallbackData>()) {
- getItem()->callback = callback;
- getItem()->callback_baton = baton;
- }
-};
-
SBBreakpoint::SBBreakpoint() {}
SBBreakpoint::SBBreakpoint(const SBBreakpoint &rhs)
@@ -264,6 +251,25 @@ const char *SBBreakpoint::GetCondition() {
return nullptr;
}
+void SBBreakpoint::SetAutoContinue(bool auto_continue) {
+ BreakpointSP bkpt_sp = GetSP();
+ if (bkpt_sp) {
+ std::lock_guard<std::recursive_mutex> guard(
+ bkpt_sp->GetTarget().GetAPIMutex());
+ bkpt_sp->SetAutoContinue(auto_continue);
+ }
+}
+
+bool SBBreakpoint::GetAutoContinue() {
+ BreakpointSP bkpt_sp = GetSP();
+ if (bkpt_sp) {
+ std::lock_guard<std::recursive_mutex> guard(
+ bkpt_sp->GetTarget().GetAPIMutex());
+ return bkpt_sp->IsAutoContinue();
+ }
+ return false;
+}
+
uint32_t SBBreakpoint::GetHitCount() const {
uint32_t count = 0;
BreakpointSP bkpt_sp = GetSP();
@@ -481,37 +487,9 @@ bool SBBreakpoint::GetDescription(SBStream &s, bool include_locations) {
return false;
}
-bool SBBreakpoint::PrivateBreakpointHitCallback(void *baton,
- StoppointCallbackContext *ctx,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id) {
- ExecutionContext exe_ctx(ctx->exe_ctx_ref);
- BreakpointSP bp_sp(
- exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id));
- if (baton && bp_sp) {
- CallbackData *data = (CallbackData *)baton;
- lldb_private::Breakpoint *bp = bp_sp.get();
- if (bp && data->callback) {
- Process *process = exe_ctx.GetProcessPtr();
- if (process) {
- SBProcess sb_process(process->shared_from_this());
- SBThread sb_thread;
- SBBreakpointLocation sb_location;
- assert(bp_sp);
- sb_location.SetLocation(bp_sp->FindLocationByID(break_loc_id));
- Thread *thread = exe_ctx.GetThreadPtr();
- if (thread)
- sb_thread.SetThread(thread->shared_from_this());
-
- return data->callback(data->callback_baton, sb_process, sb_thread,
- sb_location);
- }
- }
- }
- return true; // Return true if we should stop at this breakpoint
-}
-
-void SBBreakpoint::SetCallback(BreakpointHitCallback callback, void *baton) {
+void SBBreakpoint
+ ::SetCallback(SBBreakpointHitCallback callback,
+ void *baton) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
BreakpointSP bkpt_sp = GetSP();
LLDB_LOG(log, "breakpoint = {0}, callback = {1}, baton = {2}", bkpt_sp.get(),
@@ -521,7 +499,8 @@ void SBBreakpoint::SetCallback(BreakpointHitCallback callback, void *baton) {
std::lock_guard<std::recursive_mutex> guard(
bkpt_sp->GetTarget().GetAPIMutex());
BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));
- bkpt_sp->SetCallback(SBBreakpoint::PrivateBreakpointHitCallback, baton_sp,
+ bkpt_sp->SetCallback(SBBreakpointCallbackBaton
+ ::PrivateBreakpointHitCallback, baton_sp,
false);
}
}
@@ -580,10 +559,17 @@ bool SBBreakpoint::AddName(const char *new_name) {
bkpt_sp->GetTarget().GetAPIMutex());
Status error; // Think I'm just going to swallow the error here, it's
// probably more annoying to have to provide it.
- return bkpt_sp->AddName(new_name, error);
+ bkpt_sp->GetTarget().AddNameToBreakpoint(bkpt_sp, new_name, error);
+ if (error.Fail())
+ {
+ if (log)
+ log->Printf("Failed to add name: '%s' to breakpoint: %s",
+ new_name, error.AsCString());
+ return false;
+ }
}
- return false;
+ return true;
}
void SBBreakpoint::RemoveName(const char *name_to_remove) {
@@ -594,7 +580,8 @@ void SBBreakpoint::RemoveName(const char *name_to_remove) {
if (bkpt_sp) {
std::lock_guard<std::recursive_mutex> guard(
bkpt_sp->GetTarget().GetAPIMutex());
- bkpt_sp->RemoveName(name_to_remove);
+ bkpt_sp->GetTarget().RemoveNameFromBreakpoint(bkpt_sp,
+ ConstString(name_to_remove));
}
}
diff --git a/source/API/SBBreakpointLocation.cpp b/source/API/SBBreakpointLocation.cpp
index dc9c00d8dd57e..99ac0277e7000 100644
--- a/source/API/SBBreakpointLocation.cpp
+++ b/source/API/SBBreakpointLocation.cpp
@@ -12,6 +12,7 @@
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBDefines.h"
#include "lldb/API/SBStream.h"
+#include "lldb/API/SBStringList.h"
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
@@ -100,6 +101,16 @@ bool SBBreakpointLocation::IsEnabled() {
return false;
}
+uint32_t SBBreakpointLocation::GetHitCount() {
+ BreakpointLocationSP loc_sp = GetSP();
+ if (loc_sp) {
+ std::lock_guard<std::recursive_mutex> guard(
+ loc_sp->GetTarget().GetAPIMutex());
+ return loc_sp->GetHitCount();
+ } else
+ return 0;
+}
+
uint32_t SBBreakpointLocation::GetIgnoreCount() {
BreakpointLocationSP loc_sp = GetSP();
if (loc_sp) {
@@ -138,6 +149,25 @@ const char *SBBreakpointLocation::GetCondition() {
return NULL;
}
+void SBBreakpointLocation::SetAutoContinue(bool auto_continue) {
+ BreakpointLocationSP loc_sp = GetSP();
+ if (loc_sp) {
+ std::lock_guard<std::recursive_mutex> guard(
+ loc_sp->GetTarget().GetAPIMutex());
+ loc_sp->SetAutoContinue(auto_continue);
+ }
+}
+
+bool SBBreakpointLocation::GetAutoContinue() {
+ BreakpointLocationSP loc_sp = GetSP();
+ if (loc_sp) {
+ std::lock_guard<std::recursive_mutex> guard(
+ loc_sp->GetTarget().GetAPIMutex());
+ return loc_sp->IsAutoContinue();
+ }
+ return false;
+}
+
void SBBreakpointLocation::SetScriptCallbackFunction(
const char *callback_function_name) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
@@ -185,6 +215,33 @@ SBBreakpointLocation::SetScriptCallbackBody(const char *callback_body_text) {
return sb_error;
}
+void SBBreakpointLocation::SetCommandLineCommands(SBStringList &commands) {
+ BreakpointLocationSP loc_sp = GetSP();
+ if (!loc_sp)
+ return;
+ if (commands.GetSize() == 0)
+ return;
+
+ std::lock_guard<std::recursive_mutex> guard(
+ loc_sp->GetTarget().GetAPIMutex());
+ std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up(
+ new BreakpointOptions::CommandData(*commands, eScriptLanguageNone));
+
+ loc_sp->GetLocationOptions()->SetCommandDataCallback(cmd_data_up);
+}
+
+bool SBBreakpointLocation::GetCommandLineCommands(SBStringList &commands) {
+ BreakpointLocationSP loc_sp = GetSP();
+ if (!loc_sp)
+ return false;
+ StringList command_list;
+ bool has_commands =
+ loc_sp->GetLocationOptions()->GetCommandLineCallbacks(command_list);
+ if (has_commands)
+ commands.AppendList(command_list);
+ return has_commands;
+}
+
void SBBreakpointLocation::SetThreadID(tid_t thread_id) {
BreakpointLocationSP loc_sp = GetSP();
if (loc_sp) {
diff --git a/source/API/SBBreakpointName.cpp b/source/API/SBBreakpointName.cpp
new file mode 100644
index 0000000000000..2205280b9e5f2
--- /dev/null
+++ b/source/API/SBBreakpointName.cpp
@@ -0,0 +1,685 @@
+//===-- SBBreakpointName.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 "lldb/API/SBBreakpointName.h"
+#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBError.h"
+#include "lldb/API/SBStream.h"
+#include "lldb/API/SBStringList.h"
+#include "lldb/API/SBTarget.h"
+
+#include "lldb/Breakpoint/BreakpointName.h"
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/ThreadSpec.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Stream.h"
+
+#include "SBBreakpointOptionCommon.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace lldb
+{
+class SBBreakpointNameImpl {
+public:
+ SBBreakpointNameImpl(TargetSP target_sp, const char *name) {
+ if (!name || name[0] == '\0')
+ return;
+ m_name.assign(name);
+
+ if (!target_sp)
+ return;
+
+ m_target_wp = target_sp;
+ }
+
+ SBBreakpointNameImpl(SBTarget &sb_target, const char *name);
+ 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.
+
+ TargetSP GetTarget() const {
+ return m_target_wp.lock();
+ }
+
+ const char *GetName() const {
+ return m_name.c_str();
+ }
+
+ bool IsValid() const {
+ return !m_name.empty() && m_target_wp.lock();
+ }
+
+ lldb_private::BreakpointName *GetBreakpointName() const;
+
+private:
+ TargetWP m_target_wp;
+ std::string m_name;
+};
+
+SBBreakpointNameImpl::SBBreakpointNameImpl(SBTarget &sb_target,
+ const char *name) {
+ if (!name || name[0] == '\0')
+ return;
+ m_name.assign(name);
+
+ if (!sb_target.IsValid())
+ return;
+
+ TargetSP target_sp = sb_target.GetSP();
+ if (!target_sp)
+ return;
+
+ m_target_wp = target_sp;
+}
+
+bool SBBreakpointNameImpl::operator==(const SBBreakpointNameImpl &rhs) {
+ return m_name == rhs.m_name && m_target_wp.lock() == rhs.m_target_wp.lock();
+}
+
+bool SBBreakpointNameImpl::operator!=(const SBBreakpointNameImpl &rhs) {
+ return m_name != rhs.m_name || m_target_wp.lock() != rhs.m_target_wp.lock();
+}
+
+lldb_private::BreakpointName *SBBreakpointNameImpl::GetBreakpointName() const {
+ if (!IsValid())
+ return nullptr;
+ TargetSP target_sp = GetTarget();
+ if (!target_sp)
+ return nullptr;
+ Status error;
+ return target_sp->FindBreakpointName(ConstString(m_name), true, error);
+}
+
+} // namespace lldb
+
+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:
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ m_impl_up.reset();
+}
+
+SBBreakpointName::SBBreakpointName(SBBreakpoint &sb_bkpt, const char *name)
+{
+ if (!sb_bkpt.IsValid()) {
+ m_impl_up.reset();
+ return;
+ }
+ BreakpointSP bkpt_sp = sb_bkpt.GetSP();
+ Target &target = bkpt_sp->GetTarget();
+
+ m_impl_up.reset(new SBBreakpointNameImpl(target.shared_from_this(), name));
+
+ // Call FindBreakpointName here to make sure the name is valid, reset if
+ // not:
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name) {
+ m_impl_up.reset();
+ return;
+ }
+
+ // Now copy over the breakpoint's options:
+ target.ConfigureBreakpointName(*bp_name, *bkpt_sp->GetOptions(),
+ BreakpointName::Permissions());
+}
+
+SBBreakpointName::SBBreakpointName(const SBBreakpointName &rhs)
+{
+ if (!rhs.m_impl_up)
+ return;
+ else
+ m_impl_up.reset(new SBBreakpointNameImpl(rhs.m_impl_up->GetTarget(),
+ rhs.m_impl_up->GetName()));
+}
+
+SBBreakpointName::~SBBreakpointName() = default;
+
+const SBBreakpointName &SBBreakpointName::operator=(const SBBreakpointName &rhs)
+{
+ if (!rhs.m_impl_up) {
+ m_impl_up.reset();
+ return *this;
+ }
+
+ m_impl_up.reset(new SBBreakpointNameImpl(rhs.m_impl_up->GetTarget(),
+ rhs.m_impl_up->GetName()));
+ return *this;
+}
+
+bool SBBreakpointName::operator==(const lldb::SBBreakpointName &rhs) {
+ return *m_impl_up.get() == *rhs.m_impl_up.get();
+}
+
+bool SBBreakpointName::operator!=(const lldb::SBBreakpointName &rhs) {
+ return *m_impl_up.get() != *rhs.m_impl_up.get();
+}
+
+bool SBBreakpointName::IsValid() const {
+ if (!m_impl_up)
+ return false;
+ return m_impl_up->IsValid();
+}
+
+const char *SBBreakpointName::GetName() const {
+ if (!m_impl_up)
+ return "<Invalid Breakpoint Name Object>";
+ return m_impl_up->GetName();
+}
+
+void SBBreakpointName::SetEnabled(bool enable) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+
+ LLDB_LOG(log, "Name: {0} enabled: {1}\n", bp_name->GetName(), enable);
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ bp_name->GetOptions().SetEnabled(enable);
+}
+
+void SBBreakpointName::UpdateName(BreakpointName &bp_name) {
+ if (!IsValid())
+ return;
+
+ TargetSP target_sp = m_impl_up->GetTarget();
+ if (!target_sp)
+ return;
+ target_sp->ApplyNameToBreakpoints(bp_name);
+
+}
+
+bool SBBreakpointName::IsEnabled() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return false;
+
+ LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ return bp_name->GetOptions().IsEnabled();
+}
+
+void SBBreakpointName::SetOneShot(bool one_shot) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+
+ LLDB_LOG(log, "Name: {0} one_shot: {1}\n", bp_name->GetName(), one_shot);
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ bp_name->GetOptions().SetOneShot(one_shot);
+ UpdateName(*bp_name);
+}
+
+bool SBBreakpointName::IsOneShot() const {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ const BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return false;
+
+ LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ return bp_name->GetOptions().IsOneShot();
+}
+
+void SBBreakpointName::SetIgnoreCount(uint32_t count) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+
+ LLDB_LOG(log, "Name: {0} one_shot: {1}\n", bp_name->GetName(), count);
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ bp_name->GetOptions().SetIgnoreCount(count);
+ UpdateName(*bp_name);
+}
+
+uint32_t SBBreakpointName::GetIgnoreCount() const {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return false;
+
+ LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ return bp_name->GetOptions().GetIgnoreCount();
+}
+
+void SBBreakpointName::SetCondition(const char *condition) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+
+ LLDB_LOG(log, "Name: {0} one_shot: {1}\n", bp_name->GetName(),
+ condition ? condition : "<NULL>");
+
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ bp_name->GetOptions().SetCondition(condition);
+ UpdateName(*bp_name);
+}
+
+const char *SBBreakpointName::GetCondition() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return nullptr;
+
+ LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ return bp_name->GetOptions().GetConditionText();
+}
+
+void SBBreakpointName::SetAutoContinue(bool auto_continue) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+
+ LLDB_LOG(log, "Name: {0} auto-continue: {1}\n", bp_name->GetName(), auto_continue);
+
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ bp_name->GetOptions().SetAutoContinue(auto_continue);
+ UpdateName(*bp_name);
+}
+
+bool SBBreakpointName::GetAutoContinue() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return false;
+
+ LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ return bp_name->GetOptions().IsAutoContinue();
+}
+
+void SBBreakpointName::SetThreadID(tid_t tid) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+
+ LLDB_LOG(log, "Name: {0} tid: {1:x}\n", bp_name->GetName(), tid);
+
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ bp_name->GetOptions().SetThreadID(tid);
+ UpdateName(*bp_name);
+}
+
+tid_t SBBreakpointName::GetThreadID() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return LLDB_INVALID_THREAD_ID;
+
+ LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ return bp_name->GetOptions().GetThreadSpec()->GetTID();
+}
+
+void SBBreakpointName::SetThreadIndex(uint32_t index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+
+ LLDB_LOG(log, "Name: {0} thread index: {1}\n", bp_name->GetName(), index);
+
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ bp_name->GetOptions().GetThreadSpec()->SetIndex(index);
+ UpdateName(*bp_name);
+}
+
+uint32_t SBBreakpointName::GetThreadIndex() const {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return LLDB_INVALID_THREAD_ID;
+
+ LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ return bp_name->GetOptions().GetThreadSpec()->GetIndex();
+}
+
+void SBBreakpointName::SetThreadName(const char *thread_name) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+
+ LLDB_LOG(log, "Name: {0} thread name: {1}\n", bp_name->GetName(), thread_name);
+
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ bp_name->GetOptions().GetThreadSpec()->SetName(thread_name);
+ UpdateName(*bp_name);
+}
+
+const char *SBBreakpointName::GetThreadName() const {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return nullptr;
+
+ LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ return bp_name->GetOptions().GetThreadSpec()->GetName();
+}
+
+void SBBreakpointName::SetQueueName(const char *queue_name) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+
+ LLDB_LOG(log, "Name: {0} queue name: {1}\n", bp_name->GetName(), queue_name);
+
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ bp_name->GetOptions().GetThreadSpec()->SetQueueName(queue_name);
+ UpdateName(*bp_name);
+}
+
+const char *SBBreakpointName::GetQueueName() const {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return nullptr;
+
+ LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ return bp_name->GetOptions().GetThreadSpec()->GetQueueName();
+}
+
+void SBBreakpointName::SetCommandLineCommands(SBStringList &commands) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+ if (commands.GetSize() == 0)
+ return;
+
+ LLDB_LOG(log, "Name: {0} commands\n", bp_name->GetName());
+
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+ std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up(
+ new BreakpointOptions::CommandData(*commands, eScriptLanguageNone));
+
+ bp_name->GetOptions().SetCommandDataCallback(cmd_data_up);
+ UpdateName(*bp_name);
+}
+
+bool SBBreakpointName::GetCommandLineCommands(SBStringList &commands) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return false;
+
+ LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+ StringList command_list;
+ bool has_commands =
+ bp_name->GetOptions().GetCommandLineCallbacks(command_list);
+ if (has_commands)
+ commands.AppendList(command_list);
+ return has_commands;
+}
+
+const char *SBBreakpointName::GetHelpString() const {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return "";
+
+ LLDB_LOG(log, "Help: {0}\n", bp_name->GetHelp());
+ return bp_name->GetHelp();
+}
+
+void SBBreakpointName::SetHelpString(const char *help_string) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+
+ LLDB_LOG(log, "Name: {0} help: {1}\n", bp_name->GetName(), help_string);
+
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+ bp_name->SetHelp(help_string);
+}
+
+bool SBBreakpointName::GetDescription(SBStream &s) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ {
+ s.Printf("No value");
+ return false;
+ }
+
+ LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+ bp_name->GetDescription(s.get(), eDescriptionLevelFull);
+ return true;
+}
+
+void SBBreakpointName::SetCallback(SBBreakpointHitCallback callback,
+ void *baton) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+ LLDB_LOG(log, "callback = {1}, baton = {2}", callback, baton);
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));
+ bp_name->GetOptions().SetCallback(SBBreakpointCallbackBaton
+ ::PrivateBreakpointHitCallback,
+ baton_sp,
+ false);
+ UpdateName(*bp_name);
+}
+
+void SBBreakpointName::SetScriptCallbackFunction(
+ const char *callback_function_name) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+
+ LLDB_LOG(log, "Name: {0} callback: {1}\n", bp_name->GetName(),
+ callback_function_name);
+
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ BreakpointOptions &bp_options = bp_name->GetOptions();
+ m_impl_up->GetTarget()
+ ->GetDebugger()
+ .GetCommandInterpreter()
+ .GetScriptInterpreter()
+ ->SetBreakpointCommandCallbackFunction(&bp_options,
+ callback_function_name);
+ UpdateName(*bp_name);
+}
+
+SBError SBBreakpointName::SetScriptCallbackBody(const char *callback_body_text)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+ SBError sb_error;
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return sb_error;
+
+ LLDB_LOG(log, "Name: {0} callback: {1}\n", bp_name->GetName(),
+ callback_body_text);
+
+ std::lock_guard<std::recursive_mutex> guard(
+ m_impl_up->GetTarget()->GetAPIMutex());
+
+ BreakpointOptions &bp_options = bp_name->GetOptions();
+ Status error =
+ m_impl_up->GetTarget()
+ ->GetDebugger()
+ .GetCommandInterpreter()
+ .GetScriptInterpreter()
+ ->SetBreakpointCommandCallback(&bp_options, callback_body_text);
+ sb_error.SetError(error);
+ if (!sb_error.Fail())
+ UpdateName(*bp_name);
+
+ return sb_error;
+}
+
+bool SBBreakpointName::GetAllowList() const
+{
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return false;
+ return bp_name->GetPermissions().GetAllowList();
+}
+
+void SBBreakpointName::SetAllowList(bool value)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+ if (log)
+ log->Printf("Setting allow list to %u for %s.", value,
+ bp_name->GetName().AsCString());
+ bp_name->GetPermissions().SetAllowList(value);
+}
+
+bool SBBreakpointName::GetAllowDelete()
+{
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return false;
+ return bp_name->GetPermissions().GetAllowDelete();
+}
+
+void SBBreakpointName::SetAllowDelete(bool value)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+ if (log)
+ log->Printf("Setting allow delete to %u for %s.", value,
+ bp_name->GetName().AsCString());
+ bp_name->GetPermissions().SetAllowDelete(value);
+}
+
+bool SBBreakpointName::GetAllowDisable()
+{
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return false;
+ return bp_name->GetPermissions().GetAllowDisable();
+}
+
+void SBBreakpointName::SetAllowDisable(bool value)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ BreakpointName *bp_name = GetBreakpointName();
+ if (!bp_name)
+ return;
+ if (log)
+ log->Printf("Setting allow disable to %u for %s.", value,
+ bp_name->GetName().AsCString());
+ bp_name->GetPermissions().SetAllowDisable(value);
+}
+
+lldb_private::BreakpointName *SBBreakpointName::GetBreakpointName() const
+{
+ if (!IsValid())
+ return nullptr;
+ return m_impl_up->GetBreakpointName();
+}
+
diff --git a/source/API/SBBreakpointOptionCommon.cpp b/source/API/SBBreakpointOptionCommon.cpp
new file mode 100644
index 0000000000000..569b860a4235a
--- /dev/null
+++ b/source/API/SBBreakpointOptionCommon.cpp
@@ -0,0 +1,85 @@
+//===-- SBBreakpointName.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 "lldb/API/SBBreakpointName.h"
+#include "lldb/API/SBBreakpointLocation.h"
+#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBEvent.h"
+#include "lldb/API/SBProcess.h"
+#include "lldb/API/SBStream.h"
+#include "lldb/API/SBStringList.h"
+#include "lldb/API/SBThread.h"
+
+#include "lldb/Breakpoint/BreakpointName.h"
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadSpec.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Stream.h"
+
+#include "lldb/lldb-enumerations.h"
+
+#include "SBBreakpointOptionCommon.h"
+
+#include "llvm/ADT/STLExtras.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+SBBreakpointCallbackBaton::SBBreakpointCallbackBaton(SBBreakpointHitCallback
+ callback,
+ void *baton)
+ : TypedBaton(llvm::make_unique<CallbackData>()) {
+ getItem()->callback = callback;
+ getItem()->callback_baton = baton;
+ }
+
+ bool SBBreakpointCallbackBaton::PrivateBreakpointHitCallback(void *baton,
+ StoppointCallbackContext *ctx,
+ lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id)
+{
+ ExecutionContext exe_ctx(ctx->exe_ctx_ref);
+ BreakpointSP bp_sp(
+ exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id));
+ if (baton && bp_sp) {
+ CallbackData *data = (CallbackData *)baton;
+ lldb_private::Breakpoint *bp = bp_sp.get();
+ if (bp && data->callback) {
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process) {
+ SBProcess sb_process(process->shared_from_this());
+ SBThread sb_thread;
+ SBBreakpointLocation sb_location;
+ assert(bp_sp);
+ sb_location.SetLocation(bp_sp->FindLocationByID(break_loc_id));
+ Thread *thread = exe_ctx.GetThreadPtr();
+ if (thread)
+ sb_thread.SetThread(thread->shared_from_this());
+
+ return data->callback(data->callback_baton, sb_process, sb_thread,
+ sb_location);
+ }
+ }
+ }
+ return true; // Return true if we should stop at this breakpoint
+}
+
+SBBreakpointCallbackBaton::~SBBreakpointCallbackBaton() = default;
diff --git a/source/API/SBBreakpointOptionCommon.h b/source/API/SBBreakpointOptionCommon.h
new file mode 100644
index 0000000000000..fe276ac636fef
--- /dev/null
+++ b/source/API/SBBreakpointOptionCommon.h
@@ -0,0 +1,37 @@
+//===-- SBBreakpointOptionCommon.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_SBBreakpointOptionCommons_h_
+#define LLDB_SBBreakpointOptionCommons_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/Utility/Baton.h"
+
+namespace lldb
+{
+struct CallbackData {
+ SBBreakpointHitCallback callback;
+ void *callback_baton;
+};
+
+class SBBreakpointCallbackBaton : public lldb_private::TypedBaton<CallbackData> {
+public:
+ SBBreakpointCallbackBaton(SBBreakpointHitCallback callback,
+ void *baton);
+
+ ~SBBreakpointCallbackBaton();
+
+ static bool PrivateBreakpointHitCallback(void *baton,
+ lldb_private::StoppointCallbackContext *ctx,
+ lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id);
+};
+
+} // namespace lldb
+#endif // LLDB_SBBreakpointOptionCommons_h_
diff --git a/source/API/SBCommandInterpreter.cpp b/source/API/SBCommandInterpreter.cpp
index aa4953999b84e..c9bb8f65fa2e9 100644
--- a/source/API/SBCommandInterpreter.cpp
+++ b/source/API/SBCommandInterpreter.cpp
@@ -161,6 +161,10 @@ bool SBCommandInterpreter::IsActive() {
return (IsValid() ? m_opaque_ptr->IsActive() : false);
}
+bool SBCommandInterpreter::WasInterrupted() const {
+ return (IsValid() ? m_opaque_ptr->WasInterrupted() : false);
+}
+
const char *SBCommandInterpreter::GetIOHandlerControlSequence(char ch) {
return (IsValid()
? m_opaque_ptr->GetDebugger()
diff --git a/source/API/SBDebugger.cpp b/source/API/SBDebugger.cpp
index 3cdb6bbfd5f99..d3294dab582de 100644
--- a/source/API/SBDebugger.cpp
+++ b/source/API/SBDebugger.cpp
@@ -26,6 +26,7 @@
#include "lldb/API/SBSourceManager.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBStringList.h"
+#include "lldb/API/SBStructuredData.h"
#include "lldb/API/SBTarget.h"
#include "lldb/API/SBThread.h"
#include "lldb/API/SBTypeCategory.h"
@@ -37,8 +38,10 @@
#include "lldb/API/SystemInitializerFull.h"
#include "lldb/Core/Debugger.h"
+#include "lldb/Core/PluginManager.h"
#include "lldb/Core/State.h"
#include "lldb/Core/StreamFile.h"
+#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/Initialization/SystemLifetimeManager.h"
#include "lldb/Interpreter/Args.h"
@@ -69,7 +72,7 @@ static llvm::sys::DynamicLibrary LoadPlugin(const lldb::DebuggerSP &debugger_sp,
// TODO: mangle this differently for your system - on OSX, the first
// underscore needs to be removed and the second one stays
LLDBCommandPluginInit init_func =
- (LLDBCommandPluginInit)dynlib.getAddressOfSymbol(
+ (LLDBCommandPluginInit)(uintptr_t)dynlib.getAddressOfSymbol(
"_ZN4lldb16PluginInitializeENS_10SBDebuggerE");
if (init_func) {
if (init_func(debugger_sb))
@@ -619,6 +622,20 @@ SBTarget SBDebugger::CreateTarget(const char *filename) {
return sb_target;
}
+SBTarget SBDebugger::GetDummyTarget() {
+ SBTarget sb_target;
+ if (m_opaque_sp) {
+ sb_target.SetSP(m_opaque_sp->GetDummyTarget()->shared_from_this());
+ }
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+ if (log)
+ log->Printf(
+ "SBDebugger(%p)::GetDummyTarget() => SBTarget(%p)",
+ static_cast<void *>(m_opaque_sp.get()),
+ static_cast<void *>(sb_target.GetSP().get()));
+ return sb_target;
+}
+
bool SBDebugger::DeleteTarget(lldb::SBTarget &target) {
bool result = false;
if (m_opaque_sp) {
@@ -677,8 +694,8 @@ SBTarget SBDebugger::FindTargetWithFileAndArch(const char *filename,
SBTarget sb_target;
if (m_opaque_sp && filename && filename[0]) {
// No need to lock, the target list is thread safe
- ArchSpec arch(arch_name,
- m_opaque_sp->GetPlatformList().GetSelectedPlatform().get());
+ ArchSpec arch = Platform::GetAugmentedArchSpec(
+ m_opaque_sp->GetPlatformList().GetSelectedPlatform().get(), arch_name);
TargetSP target_sp(
m_opaque_sp->GetTargetList().FindTargetWithExecutableAndArchitecture(
FileSpec(filename, false), arch_name ? &arch : nullptr));
@@ -774,6 +791,67 @@ void SBDebugger::SetSelectedPlatform(SBPlatform &sb_platform) {
sb_platform.GetName());
}
+uint32_t SBDebugger::GetNumPlatforms() {
+ if (m_opaque_sp) {
+ // No need to lock, the platform list is thread safe
+ return m_opaque_sp->GetPlatformList().GetSize();
+ }
+ return 0;
+}
+
+SBPlatform SBDebugger::GetPlatformAtIndex(uint32_t idx) {
+ SBPlatform sb_platform;
+ if (m_opaque_sp) {
+ // No need to lock, the platform list is thread safe
+ sb_platform.SetSP(m_opaque_sp->GetPlatformList().GetAtIndex(idx));
+ }
+ return sb_platform;
+}
+
+uint32_t SBDebugger::GetNumAvailablePlatforms() {
+ uint32_t idx = 0;
+ while (true) {
+ if (!PluginManager::GetPlatformPluginNameAtIndex(idx)) {
+ break;
+ }
+ ++idx;
+ }
+ // +1 for the host platform, which should always appear first in the list.
+ return idx + 1;
+}
+
+SBStructuredData SBDebugger::GetAvailablePlatformInfoAtIndex(uint32_t idx) {
+ SBStructuredData data;
+ auto platform_dict = llvm::make_unique<StructuredData::Dictionary>();
+ llvm::StringRef name_str("name"), desc_str("description");
+
+ if (idx == 0) {
+ PlatformSP host_platform_sp(Platform::GetHostPlatform());
+ platform_dict->AddStringItem(
+ name_str, host_platform_sp->GetPluginName().GetStringRef());
+ platform_dict->AddStringItem(
+ desc_str, llvm::StringRef(host_platform_sp->GetDescription()));
+ } else if (idx > 0) {
+ const char *plugin_name =
+ PluginManager::GetPlatformPluginNameAtIndex(idx - 1);
+ if (!plugin_name) {
+ return data;
+ }
+ platform_dict->AddStringItem(name_str, llvm::StringRef(plugin_name));
+
+ const char *plugin_desc =
+ PluginManager::GetPlatformPluginDescriptionAtIndex(idx - 1);
+ if (!plugin_desc) {
+ return data;
+ }
+ platform_dict->AddStringItem(desc_str, llvm::StringRef(plugin_desc));
+ }
+
+ data.m_impl_up->SetObjectSP(
+ StructuredData::ObjectSP(platform_dict.release()));
+ return data;
+}
+
void SBDebugger::DispatchInput(void *baton, const void *data, size_t data_len) {
DispatchInput(data, data_len);
}
diff --git a/source/API/SBInstruction.cpp b/source/API/SBInstruction.cpp
index 8b7deb7011be7..1cca8db2afe8d 100644
--- a/source/API/SBInstruction.cpp
+++ b/source/API/SBInstruction.cpp
@@ -14,15 +14,15 @@
#include "lldb/API/SBInstruction.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBTarget.h"
-
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamFile.h"
+#include "lldb/Host/HostInfo.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
@@ -259,8 +259,7 @@ bool SBInstruction::EmulateWithFrame(lldb::SBFrame &frame,
bool SBInstruction::DumpEmulation(const char *triple) {
lldb::InstructionSP inst_sp(GetOpaque());
if (inst_sp && triple) {
- lldb_private::ArchSpec arch(triple, NULL);
- return inst_sp->DumpEmulation(arch);
+ return inst_sp->DumpEmulation(HostInfo::GetAugmentedArchSpec(triple));
}
return false;
}
diff --git a/source/API/SBPlatform.cpp b/source/API/SBPlatform.cpp
index 87cbc4537a3c8..7ec43f13021f3 100644
--- a/source/API/SBPlatform.cpp
+++ b/source/API/SBPlatform.cpp
@@ -12,11 +12,11 @@
#include "lldb/API/SBFileSpec.h"
#include "lldb/API/SBLaunchInfo.h"
#include "lldb/API/SBUnixSignals.h"
-#include "lldb/Core/ArchSpec.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/Status.h"
#include "llvm/Support/FileSystem.h"
diff --git a/source/API/SBProcess.cpp b/source/API/SBProcess.cpp
index caf07dbe3ce88..e08a7f4b08e0b 100644
--- a/source/API/SBProcess.cpp
+++ b/source/API/SBProcess.cpp
@@ -1369,3 +1369,13 @@ lldb::SBMemoryRegionInfoList SBProcess::GetMemoryRegions() {
}
return sb_region_list;
}
+
+lldb::SBProcessInfo SBProcess::GetProcessInfo() {
+ lldb::SBProcessInfo sb_proc_info;
+ ProcessSP process_sp(GetSP());
+ ProcessInstanceInfo proc_info;
+ if (process_sp && process_sp->GetProcessInfo(proc_info)) {
+ sb_proc_info.SetProcessInfo(proc_info);
+ }
+ return sb_proc_info;
+}
diff --git a/source/API/SBProcessInfo.cpp b/source/API/SBProcessInfo.cpp
new file mode 100644
index 0000000000000..38f6c1d1e699d
--- /dev/null
+++ b/source/API/SBProcessInfo.cpp
@@ -0,0 +1,145 @@
+//===-- SBProcessInfo.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/API/SBProcessInfo.h"
+
+#include "lldb/API/SBFileSpec.h"
+#include "lldb/Target/Process.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+SBProcessInfo::SBProcessInfo() : m_opaque_ap() {}
+
+SBProcessInfo::SBProcessInfo(const SBProcessInfo &rhs) : m_opaque_ap() {
+ if (rhs.IsValid()) {
+ ref() = *rhs.m_opaque_ap;
+ }
+}
+
+SBProcessInfo::~SBProcessInfo() {}
+
+SBProcessInfo &SBProcessInfo::operator=(const SBProcessInfo &rhs) {
+ if (this != &rhs) {
+ if (rhs.IsValid())
+ ref() = *rhs.m_opaque_ap;
+ else
+ m_opaque_ap.reset();
+ }
+ return *this;
+}
+
+ProcessInstanceInfo &SBProcessInfo::ref() {
+ if (m_opaque_ap.get() == nullptr) {
+ m_opaque_ap.reset(new ProcessInstanceInfo());
+ }
+ return *m_opaque_ap;
+}
+
+void SBProcessInfo::SetProcessInfo(const ProcessInstanceInfo &proc_info_ref) {
+ ref() = proc_info_ref;
+}
+
+bool SBProcessInfo::IsValid() const { return m_opaque_ap.get() != nullptr; }
+
+const char *SBProcessInfo::GetName() {
+ const char *name = nullptr;
+ if (m_opaque_ap) {
+ name = m_opaque_ap->GetName();
+ }
+ return name;
+}
+
+SBFileSpec SBProcessInfo::GetExecutableFile() {
+ SBFileSpec file_spec;
+ if (m_opaque_ap) {
+ file_spec.SetFileSpec(m_opaque_ap->GetExecutableFile());
+ }
+ return file_spec;
+}
+
+lldb::pid_t SBProcessInfo::GetProcessID() {
+ lldb::pid_t proc_id = LLDB_INVALID_PROCESS_ID;
+ if (m_opaque_ap) {
+ proc_id = m_opaque_ap->GetProcessID();
+ }
+ return proc_id;
+}
+
+uint32_t SBProcessInfo::GetUserID() {
+ uint32_t user_id = UINT32_MAX;
+ if (m_opaque_ap) {
+ user_id = m_opaque_ap->GetUserID();
+ }
+ return user_id;
+}
+
+uint32_t SBProcessInfo::GetGroupID() {
+ uint32_t group_id = UINT32_MAX;
+ if (m_opaque_ap) {
+ group_id = m_opaque_ap->GetGroupID();
+ }
+ return group_id;
+}
+
+bool SBProcessInfo::UserIDIsValid() {
+ bool is_valid = false;
+ if (m_opaque_ap) {
+ is_valid = m_opaque_ap->UserIDIsValid();
+ }
+ return is_valid;
+}
+
+bool SBProcessInfo::GroupIDIsValid() {
+ bool is_valid = false;
+ if (m_opaque_ap) {
+ is_valid = m_opaque_ap->GroupIDIsValid();
+ }
+ return is_valid;
+}
+
+uint32_t SBProcessInfo::GetEffectiveUserID() {
+ uint32_t user_id = UINT32_MAX;
+ if (m_opaque_ap) {
+ user_id = m_opaque_ap->GetEffectiveUserID();
+ }
+ return user_id;
+}
+
+uint32_t SBProcessInfo::GetEffectiveGroupID() {
+ uint32_t group_id = UINT32_MAX;
+ if (m_opaque_ap) {
+ group_id = m_opaque_ap->GetEffectiveGroupID();
+ }
+ return group_id;
+}
+
+bool SBProcessInfo::EffectiveUserIDIsValid() {
+ bool is_valid = false;
+ if (m_opaque_ap) {
+ is_valid = m_opaque_ap->EffectiveUserIDIsValid();
+ }
+ return is_valid;
+}
+
+bool SBProcessInfo::EffectiveGroupIDIsValid() {
+ bool is_valid = false;
+ if (m_opaque_ap) {
+ is_valid = m_opaque_ap->EffectiveGroupIDIsValid();
+ }
+ return is_valid;
+}
+
+lldb::pid_t SBProcessInfo::GetParentProcessID() {
+ lldb::pid_t proc_id = LLDB_INVALID_PROCESS_ID;
+ if (m_opaque_ap) {
+ proc_id = m_opaque_ap->GetParentProcessID();
+ }
+ return proc_id;
+}
diff --git a/source/API/SBTarget.cpp b/source/API/SBTarget.cpp
index c706344ee4a39..2c1c6bcac71b6 100644
--- a/source/API/SBTarget.cpp
+++ b/source/API/SBTarget.cpp
@@ -31,7 +31,6 @@
#include "lldb/Core/Address.h"
#include "lldb/Core/AddressResolver.h"
#include "lldb/Core/AddressResolverName.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Module.h"
@@ -58,6 +57,7 @@
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/TargetList.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"
@@ -414,16 +414,6 @@ lldb::SBProcess SBTarget::Attach(SBAttachInfo &sb_attach_info, SBError &error) {
return sb_process;
}
-#if defined(__APPLE__)
-
-lldb::SBProcess SBTarget::AttachToProcessWithID(SBListener &listener,
- ::pid_t pid,
- lldb::SBError &error) {
- return AttachToProcessWithID(listener, (lldb::pid_t)pid, error);
-}
-
-#endif // #if defined(__APPLE__)
-
lldb::SBProcess SBTarget::AttachToProcessWithID(
SBListener &listener,
lldb::pid_t pid, // The process ID to attach to
@@ -1097,11 +1087,35 @@ bool SBTarget::FindBreakpointsByName(const char *name,
return true;
}
+void SBTarget::GetBreakpointNames(SBStringList &names)
+{
+ names.Clear();
+
+ TargetSP target_sp(GetSP());
+ if (target_sp) {
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
+
+ std::vector<std::string> name_vec;
+ target_sp->GetBreakpointNames(name_vec);
+ for (auto name : name_vec)
+ names.AppendString(name.c_str());
+ }
+}
+
+void SBTarget::DeleteBreakpointName(const char *name)
+{
+ TargetSP target_sp(GetSP());
+ if (target_sp) {
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
+ target_sp->DeleteBreakpointName(ConstString(name));
+ }
+}
+
bool SBTarget::EnableAllBreakpoints() {
TargetSP target_sp(GetSP());
if (target_sp) {
std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
- target_sp->EnableAllBreakpoints();
+ target_sp->EnableAllowedBreakpoints();
return true;
}
return false;
@@ -1111,7 +1125,7 @@ bool SBTarget::DisableAllBreakpoints() {
TargetSP target_sp(GetSP());
if (target_sp) {
std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
- target_sp->DisableAllBreakpoints();
+ target_sp->DisableAllowedBreakpoints();
return true;
}
return false;
@@ -1121,7 +1135,7 @@ bool SBTarget::DeleteAllBreakpoints() {
TargetSP target_sp(GetSP());
if (target_sp) {
std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
- target_sp->RemoveAllBreakpoints();
+ target_sp->RemoveAllowedBreakpoints();
return true;
}
return false;
@@ -1428,8 +1442,8 @@ lldb::SBModule SBTarget::AddModule(const char *path, const char *triple,
module_spec.GetUUID().SetFromCString(uuid_cstr);
if (triple)
- module_spec.GetArchitecture().SetTriple(triple,
- target_sp->GetPlatform().get());
+ module_spec.GetArchitecture() = Platform::GetAugmentedArchSpec(
+ target_sp->GetPlatform().get(), triple);
else
module_spec.GetArchitecture() = target_sp->GetArchitecture();
diff --git a/source/API/SBType.cpp b/source/API/SBType.cpp
index e2ef07cf5c478..80d48754c89b2 100644
--- a/source/API/SBType.cpp
+++ b/source/API/SBType.cpp
@@ -415,21 +415,31 @@ uint32_t SBType::GetNumberOfTemplateArguments() {
}
lldb::SBType SBType::GetTemplateArgumentType(uint32_t idx) {
- if (IsValid()) {
- TemplateArgumentKind kind = eTemplateArgumentKindNull;
- CompilerType template_arg_type =
- m_opaque_sp->GetCompilerType(false).GetTemplateArgument(idx, kind);
- if (template_arg_type.IsValid())
- return SBType(template_arg_type);
+ if (!IsValid())
+ return SBType();
+
+ CompilerType type;
+ switch(GetTemplateArgumentKind(idx)) {
+ case eTemplateArgumentKindType:
+ type = m_opaque_sp->GetCompilerType(false).GetTypeTemplateArgument(idx);
+ break;
+ case eTemplateArgumentKindIntegral:
+ type = m_opaque_sp->GetCompilerType(false)
+ .GetIntegralTemplateArgument(idx)
+ ->type;
+ break;
+ default:
+ break;
}
+ if (type.IsValid())
+ return SBType(type);
return SBType();
}
lldb::TemplateArgumentKind SBType::GetTemplateArgumentKind(uint32_t idx) {
- TemplateArgumentKind kind = eTemplateArgumentKindNull;
if (IsValid())
- m_opaque_sp->GetCompilerType(false).GetTemplateArgument(idx, kind);
- return kind;
+ return m_opaque_sp->GetCompilerType(false).GetTemplateArgumentKind(idx);
+ return eTemplateArgumentKindNull;
}
SBTypeList::SBTypeList() : m_opaque_ap(new TypeListImpl()) {}
diff --git a/source/API/SystemInitializerFull.cpp b/source/API/SystemInitializerFull.cpp
index c505f61e42a68..977ebe62353ec 100644
--- a/source/API/SystemInitializerFull.cpp
+++ b/source/API/SystemInitializerFull.cpp
@@ -42,6 +42,7 @@
#include "Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h"
#include "Plugins/ABI/SysV-s390x/ABISysV_s390x.h"
#include "Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h"
+#include "Plugins/Architecture/Arm/ArchitectureArm.h"
#include "Plugins/Disassembler/llvm/DisassemblerLLVMC.h"
#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h"
#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h"
@@ -50,9 +51,9 @@
#include "Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h"
#include "Plugins/Instruction/ARM64/EmulateInstructionARM64.h"
#include "Plugins/InstrumentationRuntime/ASan/ASanRuntime.h"
+#include "Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.h"
#include "Plugins/InstrumentationRuntime/TSan/TSanRuntime.h"
#include "Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.h"
-#include "Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.h"
#include "Plugins/JITLoader/GDB/JITLoaderGDB.h"
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
#include "Plugins/Language/Go/GoLanguage.h"
@@ -304,6 +305,9 @@ void SystemInitializerFull::Initialize() {
ABISysV_mips::Initialize();
ABISysV_mips64::Initialize();
ABISysV_s390x::Initialize();
+
+ ArchitectureArm::Initialize();
+
DisassemblerLLVMC::Initialize();
JITLoaderGDB::Initialize();
diff --git a/source/Breakpoint/Breakpoint.cpp b/source/Breakpoint/Breakpoint.cpp
index 17c104ba0c600..3f6c63e1e5ba1 100644
--- a/source/Breakpoint/Breakpoint.cpp
+++ b/source/Breakpoint/Breakpoint.cpp
@@ -53,7 +53,7 @@ Breakpoint::Breakpoint(Target &target, SearchFilterSP &filter_sp,
bool resolve_indirect_symbols)
: m_being_created(true), m_hardware(hardware), m_target(target),
m_filter_sp(filter_sp), m_resolver_sp(resolver_sp),
- m_options_up(new BreakpointOptions()), m_locations(*this),
+ m_options_up(new BreakpointOptions(true)), m_locations(*this),
m_resolve_indirect_symbols(resolve_indirect_symbols), m_hit_count(0) {
m_being_created = false;
}
@@ -210,7 +210,7 @@ lldb::BreakpointSP Breakpoint::CreateFromStructuredData(
llvm::StringRef name;
Status error;
success = names_array->GetItemAtIndexAsString(i, name);
- result_sp->AddName(name, error);
+ target.AddNameToBreakpoint(result_sp, name.str().c_str(), error);
}
}
@@ -348,6 +348,14 @@ void Breakpoint::SetOneShot(bool one_shot) {
m_options_up->SetOneShot(one_shot);
}
+bool Breakpoint::IsAutoContinue() const {
+ return m_options_up->IsAutoContinue();
+}
+
+void Breakpoint::SetAutoContinue(bool auto_continue) {
+ m_options_up->SetAutoContinue(auto_continue);
+}
+
void Breakpoint::SetThreadID(lldb::tid_t thread_id) {
if (m_options_up->GetThreadSpec()->GetTID() == thread_id)
return;
@@ -447,6 +455,10 @@ bool Breakpoint::InvokeCallback(StoppointCallbackContext *context,
BreakpointOptions *Breakpoint::GetOptions() { return m_options_up.get(); }
+const BreakpointOptions *Breakpoint::GetOptions() const {
+ return m_options_up.get();
+}
+
void Breakpoint::ResolveBreakpoint() {
if (m_resolver_sp)
m_resolver_sp->ResolveBreakpoint(*m_filter_sp);
@@ -833,18 +845,8 @@ size_t Breakpoint::GetNumResolvedLocations() const {
size_t Breakpoint::GetNumLocations() const { return m_locations.GetSize(); }
-bool Breakpoint::AddName(llvm::StringRef new_name, Status &error) {
- if (new_name.empty())
- return false;
- if (!BreakpointID::StringIsBreakpointName(new_name, error)) {
- error.SetErrorStringWithFormatv("input name \"{0}\" not a breakpoint name.",
- new_name);
- return false;
- }
- if (!error.Success())
- return false;
-
- m_name_list.insert(new_name);
+bool Breakpoint::AddName(llvm::StringRef new_name) {
+ m_name_list.insert(new_name.str().c_str());
return true;
}
diff --git a/source/Breakpoint/BreakpointID.cpp b/source/Breakpoint/BreakpointID.cpp
index 112f7c0b51956..b801065468221 100644
--- a/source/Breakpoint/BreakpointID.cpp
+++ b/source/Breakpoint/BreakpointID.cpp
@@ -101,15 +101,24 @@ BreakpointID::ParseCanonicalReference(llvm::StringRef input) {
bool BreakpointID::StringIsBreakpointName(llvm::StringRef str, Status &error) {
error.Clear();
if (str.empty())
+ {
+ error.SetErrorStringWithFormat("Empty breakpoint names are not allowed");
return false;
+ }
// First character must be a letter or _
if (!isalpha(str[0]) && str[0] != '_')
+ {
+ error.SetErrorStringWithFormat("Breakpoint names must start with a "
+ "character or underscore: %s",
+ str.str().c_str());
return false;
+ }
// Cannot contain ., -, or space.
if (str.find_first_of(".- ") != llvm::StringRef::npos) {
- error.SetErrorStringWithFormat("invalid breakpoint name: \"%s\"",
+ error.SetErrorStringWithFormat("Breakpoint names cannot contain "
+ "'.' or '-': \"%s\"",
str.str().c_str());
return false;
}
diff --git a/source/Breakpoint/BreakpointIDList.cpp b/source/Breakpoint/BreakpointIDList.cpp
index 7b461147a4e93..6d610d512f3b8 100644
--- a/source/Breakpoint/BreakpointIDList.cpp
+++ b/source/Breakpoint/BreakpointIDList.cpp
@@ -11,6 +11,7 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "lldb/lldb-enumerations.h"
#include "lldb/Breakpoint/BreakpointIDList.h"
#include "lldb/Breakpoint/Breakpoint.h"
@@ -117,6 +118,8 @@ void BreakpointIDList::InsertStringArray(const char **string_array,
void BreakpointIDList::FindAndReplaceIDRanges(Args &old_args, Target *target,
bool allow_locations,
+ BreakpointName::Permissions
+ ::PermissionKinds purpose,
CommandReturnObject &result,
Args &new_args) {
llvm::StringRef range_from;
@@ -136,7 +139,6 @@ void BreakpointIDList::FindAndReplaceIDRanges(Args &old_args, Target *target,
return;
}
- llvm::StringRef range_expr;
Status error;
std::tie(range_from, range_to) =
@@ -302,14 +304,29 @@ void BreakpointIDList::FindAndReplaceIDRanges(Args &old_args, Target *target,
}
// Okay, now see if we found any names, and if we did, add them:
- if (target && names_found.size()) {
- for (BreakpointSP bkpt_sp : target->GetBreakpointList().Breakpoints()) {
- for (std::string name : names_found) {
- if (bkpt_sp->MatchesName(name.c_str())) {
- StreamString canonical_id_str;
- BreakpointID::GetCanonicalReference(
- &canonical_id_str, bkpt_sp->GetID(), LLDB_INVALID_BREAK_ID);
- new_args.AppendArgument(canonical_id_str.GetString());
+ if (target && !names_found.empty()) {
+ Status error;
+ // Remove any names that aren't visible for this purpose:
+ auto iter = names_found.begin();
+ while (iter != names_found.end()) {
+ BreakpointName *bp_name = target->FindBreakpointName(ConstString(*iter),
+ true,
+ error);
+ if (bp_name && !bp_name->GetPermission(purpose))
+ iter = names_found.erase(iter);
+ else
+ iter++;
+ }
+
+ if (!names_found.empty()) {
+ for (BreakpointSP bkpt_sp : target->GetBreakpointList().Breakpoints()) {
+ for (std::string name : names_found) {
+ if (bkpt_sp->MatchesName(name.c_str())) {
+ StreamString canonical_id_str;
+ BreakpointID::GetCanonicalReference(
+ &canonical_id_str, bkpt_sp->GetID(), LLDB_INVALID_BREAK_ID);
+ new_args.AppendArgument(canonical_id_str.GetString());
+ }
}
}
}
diff --git a/source/Breakpoint/BreakpointList.cpp b/source/Breakpoint/BreakpointList.cpp
index 15bcb34a3d85f..01ac59f0a903e 100644
--- a/source/Breakpoint/BreakpointList.cpp
+++ b/source/Breakpoint/BreakpointList.cpp
@@ -71,6 +71,13 @@ void BreakpointList::SetEnabledAll(bool enabled) {
bp_sp->SetEnabled(enabled);
}
+void BreakpointList::SetEnabledAllowed(bool enabled) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ for (const auto &bp_sp : m_breakpoints)
+ if (bp_sp->AllowDisable())
+ bp_sp->SetEnabled(enabled);
+}
+
void BreakpointList::RemoveAll(bool notify) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
ClearAllBreakpointSites();
@@ -90,6 +97,32 @@ void BreakpointList::RemoveAll(bool notify) {
m_breakpoints.erase(m_breakpoints.begin(), m_breakpoints.end());
}
+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) {
+ if(!(*pos)->AllowDelete())
+ continue;
+ if ((*pos)->GetTarget().EventTypeHasListeners(
+ Target::eBroadcastBitBreakpointChanged)) {
+ (*pos)->GetTarget().BroadcastEvent(
+ Target::eBroadcastBitBreakpointChanged,
+ new Breakpoint::BreakpointEventData(eBreakpointEventTypeRemoved,
+ *pos));
+ }
+ }
+ }
+ pos = m_breakpoints.begin();
+ while ( pos != end) {
+ if((*pos)->AllowDelete())
+ pos = m_breakpoints.erase(pos);
+ else
+ pos++;
+ }
+}
+
class BreakpointIDMatches {
public:
BreakpointIDMatches(break_id_t break_id) : m_break_id(break_id) {}
diff --git a/source/Breakpoint/BreakpointLocation.cpp b/source/Breakpoint/BreakpointLocation.cpp
index ec8f141e8d38a..f59c334fe5c8a 100644
--- a/source/Breakpoint/BreakpointLocation.cpp
+++ b/source/Breakpoint/BreakpointLocation.cpp
@@ -58,6 +58,15 @@ lldb::addr_t BreakpointLocation::GetLoadAddress() const {
return m_address.GetOpcodeLoadAddress(&m_owner.GetTarget());
}
+const BreakpointOptions *
+BreakpointLocation::GetOptionsSpecifyingKind(BreakpointOptions::OptionKind kind)
+const {
+ if (m_options_ap && m_options_ap->IsOptionSet(kind))
+ return m_options_ap.get();
+ else
+ return m_owner.GetOptions();
+}
+
Address &BreakpointLocation::GetAddress() { return m_address; }
Breakpoint &BreakpointLocation::GetBreakpoint() { return m_owner; }
@@ -84,6 +93,19 @@ void BreakpointLocation::SetEnabled(bool enabled) {
: eBreakpointEventTypeDisabled);
}
+bool BreakpointLocation::IsAutoContinue() const {
+ if (m_options_ap
+ && m_options_ap->IsOptionSet(BreakpointOptions::eAutoContinue))
+ return m_options_ap->IsAutoContinue();
+ else
+ return m_owner.IsAutoContinue();
+}
+
+void BreakpointLocation::SetAutoContinue(bool auto_continue) {
+ GetLocationOptions()->SetAutoContinue(auto_continue);
+ SendBreakpointLocationChangedEvent(eBreakpointEventTypeAutoContinueChanged);
+}
+
void BreakpointLocation::SetThreadID(lldb::tid_t thread_id) {
if (thread_id != LLDB_INVALID_THREAD_ID)
GetLocationOptions()->SetThreadID(thread_id);
@@ -97,8 +119,11 @@ void BreakpointLocation::SetThreadID(lldb::tid_t thread_id) {
}
lldb::tid_t BreakpointLocation::GetThreadID() {
- if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
- return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID();
+ const ThreadSpec *thread_spec =
+ GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
+ ->GetThreadSpecNoCreate();
+ if (thread_spec)
+ return thread_spec->GetTID();
else
return LLDB_INVALID_THREAD_ID;
}
@@ -116,8 +141,11 @@ void BreakpointLocation::SetThreadIndex(uint32_t index) {
}
uint32_t BreakpointLocation::GetThreadIndex() const {
- if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
- return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex();
+ const ThreadSpec *thread_spec =
+ GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
+ ->GetThreadSpecNoCreate();
+ if (thread_spec)
+ return thread_spec->GetIndex();
else
return 0;
}
@@ -135,8 +163,11 @@ void BreakpointLocation::SetThreadName(const char *thread_name) {
}
const char *BreakpointLocation::GetThreadName() const {
- if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
- return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName();
+ const ThreadSpec *thread_spec =
+ GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
+ ->GetThreadSpecNoCreate();
+ if (thread_spec)
+ return thread_spec->GetName();
else
return nullptr;
}
@@ -154,8 +185,11 @@ void BreakpointLocation::SetQueueName(const char *queue_name) {
}
const char *BreakpointLocation::GetQueueName() const {
- if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
- return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName();
+ const ThreadSpec *thread_spec =
+ GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
+ ->GetThreadSpecNoCreate();
+ if (thread_spec)
+ return thread_spec->GetQueueName();
else
return nullptr;
}
@@ -193,7 +227,8 @@ void BreakpointLocation::SetCondition(const char *condition) {
}
const char *BreakpointLocation::GetConditionText(size_t *hash) const {
- return GetOptionsNoCreate()->GetConditionText(hash);
+ return GetOptionsSpecifyingKind(BreakpointOptions::eCondition)
+ ->GetConditionText(hash);
}
bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx,
@@ -305,7 +340,8 @@ bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx,
}
uint32_t BreakpointLocation::GetIgnoreCount() {
- return GetOptionsNoCreate()->GetIgnoreCount();
+ return GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount)
+ ->GetIgnoreCount();
}
void BreakpointLocation::SetIgnoreCount(uint32_t n) {
@@ -335,26 +371,21 @@ bool BreakpointLocation::IgnoreCountShouldStop() {
return true;
}
-const BreakpointOptions *BreakpointLocation::GetOptionsNoCreate() const {
- if (m_options_ap.get() != nullptr)
- return m_options_ap.get();
- else
- return m_owner.GetOptions();
-}
-
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 (m_options_ap.get() == nullptr)
m_options_ap.reset(
- BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions()));
+ new BreakpointOptions(false));
return m_options_ap.get();
}
bool BreakpointLocation::ValidForThisThread(Thread *thread) {
- return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate());
+ return thread
+ ->MatchesSpec(GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
+ ->GetThreadSpecNoCreate());
}
// RETURNS - true if we should stop at this breakpoint, false if we
@@ -600,17 +631,20 @@ void BreakpointLocation::Dump(Stream *s) const {
if (s == nullptr)
return;
+ lldb::tid_t tid = GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
+ ->GetThreadSpecNoCreate()->GetTID();
s->Printf(
"BreakpointLocation %u: tid = %4.4" PRIx64 " load addr = 0x%8.8" PRIx64
" state = %s type = %s breakpoint "
"hw_index = %i hit_count = %-4u ignore_count = %-4u",
- GetID(), GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(),
+ GetID(), tid,
(uint64_t)m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()),
(m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled())
? "enabled "
: "disabled",
IsHardware() ? "hardware" : "software", GetHardwareIndex(), GetHitCount(),
- GetOptionsNoCreate()->GetIgnoreCount());
+ GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount)
+ ->GetIgnoreCount());
}
void BreakpointLocation::SendBreakpointLocationChangedEvent(
diff --git a/source/Breakpoint/BreakpointLocationList.cpp b/source/Breakpoint/BreakpointLocationList.cpp
index b4cf0c38e9c28..1e4b4412a427b 100644
--- a/source/Breakpoint/BreakpointLocationList.cpp
+++ b/source/Breakpoint/BreakpointLocationList.cpp
@@ -15,11 +15,11 @@
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
using namespace lldb;
using namespace lldb_private;
diff --git a/source/Breakpoint/BreakpointName.cpp b/source/Breakpoint/BreakpointName.cpp
new file mode 100644
index 0000000000000..be4710d7849c8
--- /dev/null
+++ b/source/Breakpoint/BreakpointName.cpp
@@ -0,0 +1,91 @@
+//===-- Breakpoint.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
+#include "llvm/Support/Casting.h"
+
+// Project includes
+#include "lldb/Breakpoint/Breakpoint.h"
+#include "lldb/Breakpoint/BreakpointOptions.h"
+#include "lldb/Breakpoint/BreakpointLocationCollection.h"
+#include "lldb/Breakpoint/BreakpointResolver.h"
+#include "lldb/Breakpoint/BreakpointResolverFileLine.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Stream.h"
+#include "lldb/Utility/StreamString.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+const Flags::ValueType BreakpointName::Permissions::permissions_mask
+ [BreakpointName::Permissions::PermissionKinds::allPerms + 1] = {
+ (1u << 0),
+ (1u << 1),
+ (1u << 2),
+ (0x5u)
+};
+
+BreakpointName::BreakpointName(const ConstString &name, const Breakpoint &bkpt,
+ const char *help) :
+ m_name(name), m_options(bkpt.GetOptions())
+{
+ SetHelp(help);
+}
+
+bool BreakpointName::Permissions::GetDescription(Stream *s,
+ lldb::DescriptionLevel level) {
+ if (!AnySet())
+ return false;
+ s->IndentMore();
+ s->Indent();
+ if (IsSet(listPerm))
+ s->Printf("list: %s", GetAllowList() ? "allowed" : "disallowed");
+
+ if (IsSet(disablePerm))
+ s->Printf("disable: %s", GetAllowDisable() ? "allowed" : "disallowed");
+
+ if (IsSet(deletePerm))
+ s->Printf("delete: %s", GetAllowDelete() ? "allowed" : "disallowed");
+ s->IndentLess();
+ return true;
+}
+
+bool BreakpointName::GetDescription(Stream *s, lldb::DescriptionLevel level) {
+ bool printed_any = false;
+ if (!m_help.empty())
+ s->Printf("Help: %s\n", m_help.c_str());
+
+ if (GetOptions().AnySet())
+ {
+ s->PutCString("Options: \n");
+ s->IndentMore();
+ s->Indent();
+ GetOptions().GetDescription(s, level);
+ printed_any = true;
+ s->IndentLess();
+ }
+ if (GetPermissions().AnySet())
+ {
+ s->PutCString("Permissions: \n");
+ s->IndentMore();
+ s->Indent();
+ GetPermissions().GetDescription(s, level);
+ printed_any = true;
+ s->IndentLess();
+ }
+ return printed_any;
+}
+
+void BreakpointName::ConfigureBreakpoint(lldb::BreakpointSP bp_sp)
+{
+ bp_sp->GetOptions()->CopyOverSetOptions(GetOptions());
+ bp_sp->GetPermissions().MergeInto(GetPermissions());
+}
diff --git a/source/Breakpoint/BreakpointOptions.cpp b/source/Breakpoint/BreakpointOptions.cpp
index bef63cc0f222e..662b288794d3a 100644
--- a/source/Breakpoint/BreakpointOptions.cpp
+++ b/source/Breakpoint/BreakpointOptions.cpp
@@ -114,7 +114,8 @@ BreakpointOptions::CommandData::CreateFromStructuredData(
const char *BreakpointOptions::g_option_names[(
size_t)BreakpointOptions::OptionNames::LastOptionName]{
- "ConditionText", "IgnoreCount", "EnabledState", "OneShotState"};
+ "ConditionText", "IgnoreCount",
+ "EnabledState", "OneShotState", "AutoContinue"};
bool BreakpointOptions::NullCallback(void *baton,
StoppointCallbackContext *context,
@@ -126,20 +127,30 @@ bool BreakpointOptions::NullCallback(void *baton,
//----------------------------------------------------------------------
// BreakpointOptions constructor
//----------------------------------------------------------------------
-BreakpointOptions::BreakpointOptions()
+BreakpointOptions::BreakpointOptions(bool all_flags_set)
: m_callback(BreakpointOptions::NullCallback), m_callback_baton_sp(),
m_baton_is_command_baton(false), m_callback_is_synchronous(false),
m_enabled(true), m_one_shot(false), m_ignore_count(0), m_thread_spec_ap(),
- m_condition_text(), m_condition_text_hash(0) {}
+ m_condition_text(), m_condition_text_hash(0), m_auto_continue(false),
+ m_set_flags(0) {
+ if (all_flags_set)
+ m_set_flags.Set(~((Flags::ValueType) 0));
+ }
BreakpointOptions::BreakpointOptions(const char *condition, bool enabled,
- int32_t ignore, bool one_shot)
+ int32_t ignore, bool one_shot,
+ bool auto_continue)
: m_callback(nullptr), m_baton_is_command_baton(false),
m_callback_is_synchronous(false), m_enabled(enabled),
- m_one_shot(one_shot), m_ignore_count(ignore), m_condition_text(condition),
- m_condition_text_hash(0)
-
-{}
+ m_one_shot(one_shot), m_ignore_count(ignore),
+ m_condition_text_hash(0), m_auto_continue(auto_continue)
+{
+ m_set_flags.Set(eEnabled | eIgnoreCount | eOneShot
+ | eAutoContinue);
+ if (condition && *condition != '\0') {
+ SetCondition(condition);
+ }
+}
//----------------------------------------------------------------------
// BreakpointOptions copy constructor
@@ -149,7 +160,9 @@ BreakpointOptions::BreakpointOptions(const BreakpointOptions &rhs)
m_baton_is_command_baton(rhs.m_baton_is_command_baton),
m_callback_is_synchronous(rhs.m_callback_is_synchronous),
m_enabled(rhs.m_enabled), m_one_shot(rhs.m_one_shot),
- m_ignore_count(rhs.m_ignore_count), m_thread_spec_ap() {
+ m_ignore_count(rhs.m_ignore_count), m_thread_spec_ap(),
+ m_auto_continue(rhs.m_auto_continue),
+ m_set_flags(rhs.m_set_flags) {
if (rhs.m_thread_spec_ap.get() != nullptr)
m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get()));
m_condition_text = rhs.m_condition_text;
@@ -172,21 +185,62 @@ operator=(const BreakpointOptions &rhs) {
m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get()));
m_condition_text = rhs.m_condition_text;
m_condition_text_hash = rhs.m_condition_text_hash;
+ m_auto_continue = rhs.m_auto_continue;
+ m_set_flags = rhs.m_set_flags;
return *this;
}
-BreakpointOptions *
-BreakpointOptions::CopyOptionsNoCallback(BreakpointOptions &orig) {
- BreakpointHitCallback orig_callback = orig.m_callback;
- lldb::BatonSP orig_callback_baton_sp = orig.m_callback_baton_sp;
- bool orig_is_sync = orig.m_callback_is_synchronous;
-
- orig.ClearCallback();
- BreakpointOptions *ret_val = new BreakpointOptions(orig);
-
- orig.SetCallback(orig_callback, orig_callback_baton_sp, orig_is_sync);
-
- return ret_val;
+void BreakpointOptions::CopyOverSetOptions(const BreakpointOptions &incoming)
+{
+ if (incoming.m_set_flags.Test(eEnabled))
+ {
+ m_enabled = incoming.m_enabled;
+ m_set_flags.Set(eEnabled);
+ }
+ if (incoming.m_set_flags.Test(eOneShot))
+ {
+ m_one_shot = incoming.m_one_shot;
+ m_set_flags.Set(eOneShot);
+ }
+ if (incoming.m_set_flags.Test(eCallback))
+ {
+ m_callback = incoming.m_callback;
+ m_callback_baton_sp = incoming.m_callback_baton_sp;
+ m_callback_is_synchronous = incoming.m_callback_is_synchronous;
+ m_baton_is_command_baton = incoming.m_baton_is_command_baton;
+ m_set_flags.Set(eCallback);
+ }
+ if (incoming.m_set_flags.Test(eIgnoreCount))
+ {
+ m_ignore_count = incoming.m_ignore_count;
+ m_set_flags.Set(eIgnoreCount);
+ }
+ if (incoming.m_set_flags.Test(eCondition))
+ {
+ // If we're copying over an empty condition, mark it as unset.
+ if (incoming.m_condition_text.empty()) {
+ m_condition_text.clear();
+ m_condition_text_hash = 0;
+ m_set_flags.Clear(eCondition);
+ } else {
+ m_condition_text = incoming.m_condition_text;
+ m_condition_text_hash = incoming.m_condition_text_hash;
+ m_set_flags.Set(eCondition);
+ }
+ }
+ if (incoming.m_set_flags.Test(eAutoContinue))
+ {
+ m_auto_continue = incoming.m_auto_continue;
+ m_set_flags.Set(eAutoContinue);
+ }
+ if (incoming.m_set_flags.Test(eThreadSpec) && incoming.m_thread_spec_ap)
+ {
+ if (!m_thread_spec_ap)
+ m_thread_spec_ap.reset(new ThreadSpec(*incoming.m_thread_spec_ap.get()));
+ else
+ *m_thread_spec_ap.get() = *incoming.m_thread_spec_ap.get();
+ m_set_flags.Set(eThreadSpec);
+ }
}
//----------------------------------------------------------------------
@@ -199,30 +253,65 @@ std::unique_ptr<BreakpointOptions> BreakpointOptions::CreateFromStructuredData(
Status &error) {
bool enabled = true;
bool one_shot = false;
+ bool auto_continue = false;
int32_t ignore_count = 0;
- std::string condition_text;
-
- bool success = options_dict.GetValueForKeyAsBoolean(
- GetKey(OptionNames::EnabledState), enabled);
- if (!success) {
- error.SetErrorStringWithFormat("%s key is not a boolean.",
+ llvm::StringRef condition_ref("");
+ Flags set_options;
+
+ const char *key = GetKey(OptionNames::EnabledState);
+ bool success;
+ if (key) {
+ success = options_dict.GetValueForKeyAsBoolean(key, enabled);
+ if (!success) {
+ error.SetErrorStringWithFormat("%s key is not a boolean.",
GetKey(OptionNames::EnabledState));
- return nullptr;
+ return nullptr;
+ }
+ set_options.Set(eEnabled);
}
- success = options_dict.GetValueForKeyAsBoolean(
- GetKey(OptionNames::OneShotState), one_shot);
- if (!success) {
- error.SetErrorStringWithFormat("%s key is not a boolean.",
- GetKey(OptionNames::OneShotState));
- return nullptr;
+ key = GetKey(OptionNames::OneShotState);
+ if (key) {
+ success = options_dict.GetValueForKeyAsBoolean(key, one_shot);
+ if (!success) {
+ error.SetErrorStringWithFormat("%s key is not a boolean.",
+ GetKey(OptionNames::OneShotState));
+ return nullptr;
+ }
+ set_options.Set(eOneShot);
}
- success = options_dict.GetValueForKeyAsInteger(
- GetKey(OptionNames::IgnoreCount), ignore_count);
- if (!success) {
- error.SetErrorStringWithFormat("%s key is not an integer.",
- GetKey(OptionNames::IgnoreCount));
- return nullptr;
+
+ key = GetKey(OptionNames::AutoContinue);
+ if (key) {
+ success = options_dict.GetValueForKeyAsBoolean(key, auto_continue);
+ if (!success) {
+ error.SetErrorStringWithFormat("%s key is not a boolean.",
+ GetKey(OptionNames::AutoContinue));
+ return nullptr;
+ }
+ set_options.Set(eAutoContinue);
+ }
+
+ key = GetKey(OptionNames::IgnoreCount);
+ if (key) {
+ success = options_dict.GetValueForKeyAsInteger(key, ignore_count);
+ if (!success) {
+ error.SetErrorStringWithFormat("%s key is not an integer.",
+ GetKey(OptionNames::IgnoreCount));
+ return nullptr;
+ }
+ set_options.Set(eIgnoreCount);
+ }
+
+ key = GetKey(OptionNames::ConditionText);
+ if (key) {
+ success = options_dict.GetValueForKeyAsString(key, condition_ref);
+ if (!success) {
+ error.SetErrorStringWithFormat("%s key is not an string.",
+ GetKey(OptionNames::ConditionText));
+ return nullptr;
+ }
+ set_options.Set(eCondition);
}
std::unique_ptr<CommandData> cmd_data_up;
@@ -241,7 +330,8 @@ std::unique_ptr<BreakpointOptions> BreakpointOptions::CreateFromStructuredData(
}
auto bp_options = llvm::make_unique<BreakpointOptions>(
- condition_text.c_str(), enabled, ignore_count, one_shot);
+ condition_ref.str().c_str(), enabled,
+ ignore_count, one_shot, auto_continue);
if (cmd_data_up.get()) {
if (cmd_data_up->interpreter == eScriptLanguageNone)
bp_options->SetCommandDataCallback(cmd_data_up);
@@ -293,14 +383,23 @@ std::unique_ptr<BreakpointOptions> BreakpointOptions::CreateFromStructuredData(
StructuredData::ObjectSP BreakpointOptions::SerializeToStructuredData() {
StructuredData::DictionarySP options_dict_sp(
new StructuredData::Dictionary());
- options_dict_sp->AddBooleanItem(GetKey(OptionNames::EnabledState), m_enabled);
- options_dict_sp->AddBooleanItem(GetKey(OptionNames::OneShotState),
- m_one_shot);
- options_dict_sp->AddIntegerItem(GetKey(OptionNames::IgnoreCount),
- m_ignore_count);
- options_dict_sp->AddStringItem(GetKey(OptionNames::ConditionText),
- m_condition_text);
- if (m_baton_is_command_baton) {
+ if (m_set_flags.Test(eEnabled))
+ options_dict_sp->AddBooleanItem(GetKey(OptionNames::EnabledState),
+ m_enabled);
+ if (m_set_flags.Test(eOneShot))
+ options_dict_sp->AddBooleanItem(GetKey(OptionNames::OneShotState),
+ m_one_shot);
+ if (m_set_flags.Test(eAutoContinue))
+ options_dict_sp->AddBooleanItem(GetKey(OptionNames::AutoContinue),
+ m_auto_continue);
+ if (m_set_flags.Test(eIgnoreCount))
+ options_dict_sp->AddIntegerItem(GetKey(OptionNames::IgnoreCount),
+ m_ignore_count);
+ if (m_set_flags.Test(eCondition))
+ options_dict_sp->AddStringItem(GetKey(OptionNames::ConditionText),
+ m_condition_text);
+
+ if (m_set_flags.Test(eCallback) && m_baton_is_command_baton) {
auto cmd_baton =
std::static_pointer_cast<CommandBaton>(m_callback_baton_sp);
StructuredData::ObjectSP commands_sp =
@@ -310,7 +409,7 @@ StructuredData::ObjectSP BreakpointOptions::SerializeToStructuredData() {
BreakpointOptions::CommandData::GetSerializationKey(), commands_sp);
}
}
- if (m_thread_spec_ap) {
+ if (m_set_flags.Test(eThreadSpec) && m_thread_spec_ap) {
StructuredData::ObjectSP thread_spec_sp =
m_thread_spec_ap->SerializeToStructuredData();
options_dict_sp->AddItem(ThreadSpec::GetSerializationKey(), thread_spec_sp);
@@ -340,6 +439,7 @@ void BreakpointOptions::SetCallback(BreakpointHitCallback callback,
m_callback = callback;
m_callback_baton_sp = callback_baton_sp;
m_baton_is_command_baton = false;
+ m_set_flags.Set(eCallback);
}
void BreakpointOptions::SetCallback(
@@ -350,6 +450,7 @@ void BreakpointOptions::SetCallback(
m_callback = callback;
m_callback_baton_sp = callback_baton_sp;
m_baton_is_command_baton = true;
+ m_set_flags.Set(eCallback);
}
void BreakpointOptions::ClearCallback() {
@@ -357,6 +458,7 @@ void BreakpointOptions::ClearCallback() {
m_callback_is_synchronous = false;
m_callback_baton_sp.reset();
m_baton_is_command_baton = false;
+ m_set_flags.Clear(eCallback);
}
Baton *BreakpointOptions::GetBaton() { return m_callback_baton_sp.get(); }
@@ -395,8 +497,12 @@ bool BreakpointOptions::GetCommandLineCallbacks(StringList &command_list) {
}
void BreakpointOptions::SetCondition(const char *condition) {
- if (!condition)
+ if (!condition || condition[0] == '\0') {
condition = "";
+ m_set_flags.Clear(eCondition);
+ }
+ else
+ m_set_flags.Set(eCondition);
m_condition_text.assign(condition);
std::hash<std::string> hasher;
@@ -427,11 +533,13 @@ ThreadSpec *BreakpointOptions::GetThreadSpec() {
void BreakpointOptions::SetThreadID(lldb::tid_t thread_id) {
GetThreadSpec()->SetTID(thread_id);
+ m_set_flags.Set(eThreadSpec);
}
void BreakpointOptions::SetThreadSpec(
std::unique_ptr<ThreadSpec> &thread_spec_up) {
m_thread_spec_ap = std::move(thread_spec_up);
+ m_set_flags.Set(eThreadSpec);
}
void BreakpointOptions::GetDescription(Stream *s,
@@ -440,7 +548,7 @@ void BreakpointOptions::GetDescription(Stream *s,
// print
// anything if there are:
- if (m_ignore_count != 0 || !m_enabled || m_one_shot ||
+ if (m_ignore_count != 0 || !m_enabled || m_one_shot || m_auto_continue ||
(GetThreadSpecNoCreate() != nullptr &&
GetThreadSpecNoCreate()->HasSpecification())) {
if (level == lldb::eDescriptionLevelVerbose) {
@@ -460,6 +568,9 @@ void BreakpointOptions::GetDescription(Stream *s,
if (m_one_shot)
s->Printf("one-shot ");
+ if (m_auto_continue)
+ s->Printf("auto-continue ");
+
if (m_thread_spec_ap.get())
m_thread_spec_ap->GetDescription(s, level);
@@ -520,6 +631,7 @@ void BreakpointOptions::SetCommandDataCallback(
cmd_data->interpreter = eScriptLanguageNone;
auto baton_sp = std::make_shared<CommandBaton>(std::move(cmd_data));
SetCallback(BreakpointOptions::BreakpointOptionsCallbackFunction, baton_sp);
+ m_set_flags.Set(eCallback);
}
bool BreakpointOptions::BreakpointOptionsCallbackFunction(
@@ -562,3 +674,18 @@ bool BreakpointOptions::BreakpointOptionsCallbackFunction(
}
return ret_value;
}
+
+void BreakpointOptions::Clear()
+{
+ m_set_flags.Clear();
+ m_thread_spec_ap.release();
+ m_one_shot = false;
+ m_ignore_count = 0;
+ m_auto_continue = false;
+ m_callback = nullptr;
+ m_callback_baton_sp.reset();
+ m_baton_is_command_baton = false;
+ m_callback_is_synchronous = false;
+ m_enabled = false;
+ m_condition_text.clear();
+}
diff --git a/source/Breakpoint/CMakeLists.txt b/source/Breakpoint/CMakeLists.txt
index f6278528eab8a..f93d48579ad7d 100644
--- a/source/Breakpoint/CMakeLists.txt
+++ b/source/Breakpoint/CMakeLists.txt
@@ -6,6 +6,7 @@ add_lldb_library(lldbBreakpoint
BreakpointLocation.cpp
BreakpointLocationCollection.cpp
BreakpointLocationList.cpp
+ BreakpointName.cpp
BreakpointOptions.cpp
BreakpointResolver.cpp
BreakpointResolverAddress.cpp
diff --git a/source/Commands/CommandCompletions.cpp b/source/Commands/CommandCompletions.cpp
index fd84e1c4f8573..34cad970ff6ed 100644
--- a/source/Commands/CommandCompletions.cpp
+++ b/source/Commands/CommandCompletions.cpp
@@ -199,14 +199,14 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name,
// We have a match.
- fs::file_status st;
- if ((EC = Entry.status(st)))
+ llvm::ErrorOr<fs::basic_file_status> st = Entry.status();
+ if (!st)
continue;
// If it's a symlink, then we treat it as a directory as long as the target
// is a directory.
- bool is_dir = fs::is_directory(st);
- if (fs::is_symlink_file(st)) {
+ bool is_dir = fs::is_directory(*st);
+ if (fs::is_symlink_file(*st)) {
fs::file_status target_st;
if (!fs::status(Entry.path(), target_st))
is_dir = fs::is_directory(target_st);
diff --git a/source/Commands/CommandObjectBreakpoint.cpp b/source/Commands/CommandObjectBreakpoint.cpp
index 266864d1a1f0d..5a175d61060e3 100644
--- a/source/Commands/CommandObjectBreakpoint.cpp
+++ b/source/Commands/CommandObjectBreakpoint.cpp
@@ -45,6 +45,203 @@ static void AddBreakpointDescription(Stream *s, Breakpoint *bp,
s->EOL();
}
+//-------------------------------------------------------------------------
+// Modifiable Breakpoint Options
+//-------------------------------------------------------------------------
+#pragma mark Modify::CommandOptions
+static OptionDefinition g_breakpoint_modify_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
+ { LLDB_OPT_SET_1, false, "one-shot", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." },
+ { LLDB_OPT_SET_1, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument." },
+ { LLDB_OPT_SET_1, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument." },
+ { LLDB_OPT_SET_1, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument." },
+ { LLDB_OPT_SET_1, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument." },
+ { LLDB_OPT_SET_1, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true." },
+ { LLDB_OPT_SET_1, false, "auto-continue",'G', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "The breakpoint will auto-continue after running its commands." },
+ { LLDB_OPT_SET_2, false, "enable", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable the breakpoint." },
+ { LLDB_OPT_SET_3, false, "disable", 'd', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Disable the breakpoint." },
+ { LLDB_OPT_SET_4, false, "command", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCommand, "A command to run when the breakpoint is hit, can be provided more than once, the commands will get run in order left to right." },
+ // clang-format on
+};
+class lldb_private::BreakpointOptionGroup : public OptionGroup
+{
+public:
+ BreakpointOptionGroup() :
+ OptionGroup(),
+ m_bp_opts(false) {}
+
+ ~BreakpointOptionGroup() override = default;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_breakpoint_modify_options);
+ }
+
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Status error;
+ const int short_option = g_breakpoint_modify_options[option_idx].short_option;
+
+ switch (short_option) {
+ case 'c':
+ // 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;
+ case 'C':
+ m_commands.push_back(option_arg);
+ break;
+ case 'd':
+ m_bp_opts.SetEnabled(false);
+ break;
+ case 'e':
+ m_bp_opts.SetEnabled(true);
+ break;
+ case 'G': {
+ bool value, success;
+ value = Args::StringToBoolean(option_arg, false, &success);
+ if (success) {
+ m_bp_opts.SetAutoContinue(value);
+ } else
+ error.SetErrorStringWithFormat(
+ "invalid boolean value '%s' passed for -G option",
+ option_arg.str().c_str());
+ }
+ break;
+ case 'i':
+ {
+ uint32_t ignore_count;
+ if (option_arg.getAsInteger(0, ignore_count))
+ error.SetErrorStringWithFormat("invalid ignore count '%s'",
+ option_arg.str().c_str());
+ else
+ m_bp_opts.SetIgnoreCount(ignore_count);
+ }
+ break;
+ case 'o': {
+ bool value, success;
+ value = Args::StringToBoolean(option_arg, false, &success);
+ if (success) {
+ m_bp_opts.SetOneShot(value);
+ } else
+ error.SetErrorStringWithFormat(
+ "invalid boolean value '%s' passed for -o option",
+ option_arg.str().c_str());
+ } break;
+ case 't':
+ {
+ lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID;
+ if (option_arg[0] != '\0') {
+ if (option_arg.getAsInteger(0, thread_id))
+ error.SetErrorStringWithFormat("invalid thread id string '%s'",
+ option_arg.str().c_str());
+ }
+ m_bp_opts.SetThreadID(thread_id);
+ }
+ break;
+ case 'T':
+ m_bp_opts.GetThreadSpec()->SetName(option_arg.str().c_str());
+ break;
+ case 'q':
+ m_bp_opts.GetThreadSpec()->SetQueueName(option_arg.str().c_str());
+ break;
+ case 'x':
+ {
+ uint32_t thread_index = UINT32_MAX;
+ if (option_arg[0] != '\n') {
+ if (option_arg.getAsInteger(0, thread_index))
+ error.SetErrorStringWithFormat("invalid thread index string '%s'",
+ option_arg.str().c_str());
+ }
+ m_bp_opts.GetThreadSpec()->SetIndex(thread_index);
+ }
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_bp_opts.Clear();
+ m_commands.clear();
+ }
+
+ Status OptionParsingFinished(ExecutionContext *execution_context) override {
+ if (!m_commands.empty())
+ {
+ if (!m_commands.empty())
+ {
+ auto cmd_data = llvm::make_unique<BreakpointOptions::CommandData>();
+
+ for (std::string &str : m_commands)
+ cmd_data->user_source.AppendString(str);
+
+ cmd_data->stop_on_error = true;
+ m_bp_opts.SetCommandDataCallback(cmd_data);
+ }
+ }
+ return Status();
+ }
+
+ const BreakpointOptions &GetBreakpointOptions()
+ {
+ return m_bp_opts;
+ }
+
+ std::vector<std::string> m_commands;
+ BreakpointOptions m_bp_opts;
+
+};
+static OptionDefinition g_breakpoint_dummy_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Act on Dummy breakpoints - i.e. breakpoints set before a file is provided, "
+ "which prime new targets." },
+ // clang-format on
+};
+
+class BreakpointDummyOptionGroup : public OptionGroup
+{
+public:
+ BreakpointDummyOptionGroup() :
+ OptionGroup() {}
+
+ ~BreakpointDummyOptionGroup() override = default;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_breakpoint_dummy_options);
+ }
+
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Status error;
+ const int short_option = g_breakpoint_modify_options[option_idx].short_option;
+
+ switch (short_option) {
+ case 'D':
+ m_use_dummy = true;
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_use_dummy = false;
+ }
+
+ bool m_use_dummy;
+
+};
+
// If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
// update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
#define LLDB_OPT_FILE (LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2)
@@ -58,16 +255,7 @@ static OptionDefinition g_breakpoint_set_options[] = {
// clang-format off
{ LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the breakpoint only in this shared library. Can repeat this option "
"multiple times to specify multiple shared libraries." },
- { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
- { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "The breakpoint is deleted the first time it causes a stop." },
- { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true." },
- { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose indeX matches this argument." },
- { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument." },
- { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this "
- "argument." },
{ LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Require the breakpoint to use hardware breakpoints." },
- { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by "
- "this argument." },
{ LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specifies the source file in which to set this breakpoint. Note, by default "
"lldb only looks for files that are #included if they use the standard include "
"file extensions. To set breakpoints on .c/.cpp/.m/.mm files that are "
@@ -125,8 +313,6 @@ static OptionDefinition g_breakpoint_set_options[] = {
"If not set the target.language setting is used." },
{ LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "sKip the prologue if the breakpoint is at the beginning of a function. "
"If not set the target.skip-prologue setting is used." },
- { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, "
- "which prime new targets." },
{ LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Adds this to the list of names for this breakpoint." },
{ LLDB_OPT_OFFSET_APPLIES, false, "address-slide", 'R', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddress, "Add the specified offset to whatever address(es) the breakpoint resolves to. "
"At present this applies the offset directly as given, and doesn't try to align it to instruction boundaries." },
@@ -156,24 +342,30 @@ public:
interpreter, "breakpoint set",
"Sets a breakpoint or set of breakpoints in the executable.",
"breakpoint set <cmd-options>"),
- m_options() {}
+ m_bp_opts(), m_options() {
+ // We're picking up all the normal options, commands and disable.
+ m_all_options.Append(&m_bp_opts,
+ LLDB_OPT_SET_1 | LLDB_OPT_SET_3 | LLDB_OPT_SET_4,
+ LLDB_OPT_SET_ALL);
+ m_all_options.Append(&m_dummy_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
+ m_all_options.Append(&m_options);
+ m_all_options.Finalize();
+ }
~CommandObjectBreakpointSet() override = default;
- Options *GetOptions() override { return &m_options; }
+ Options *GetOptions() override { return &m_all_options; }
- class CommandOptions : public Options {
+ class CommandOptions : public OptionGroup {
public:
CommandOptions()
- : Options(), m_condition(), m_filenames(), m_line_num(0), m_column(0),
+ : OptionGroup(), m_condition(), m_filenames(), m_line_num(0), m_column(0),
m_func_names(), m_func_name_type_mask(eFunctionNameTypeNone),
m_func_regexp(), m_source_text_regexp(), m_modules(), m_load_addr(),
- m_ignore_count(0), m_thread_id(LLDB_INVALID_THREAD_ID),
- m_thread_index(UINT32_MAX), m_thread_name(), m_queue_name(),
m_catch_bp(false), m_throw_bp(true), m_hardware(false),
m_exception_language(eLanguageTypeUnknown),
m_language(lldb::eLanguageTypeUnknown),
- m_skip_prologue(eLazyBoolCalculate), m_one_shot(false),
+ m_skip_prologue(eLazyBoolCalculate),
m_all_files(false), m_move_to_nearest_code(eLazyBoolCalculate) {}
~CommandOptions() override = default;
@@ -181,7 +373,7 @@ public:
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
ExecutionContext *execution_context) override {
Status error;
- const int short_option = m_getopt_table[option_idx].val;
+ const int short_option = g_breakpoint_set_options[option_idx].short_option;
switch (short_option) {
case 'a': {
@@ -204,14 +396,6 @@ public:
option_arg.str().c_str());
break;
- case 'c':
- m_condition.assign(option_arg);
- break;
-
- case 'D':
- m_use_dummy = true;
- break;
-
case 'E': {
LanguageType language = Language::GetLanguageTypeFromString(option_arg);
@@ -255,7 +439,7 @@ public:
m_func_names.push_back(option_arg);
m_func_name_type_mask |= eFunctionNameTypeFull;
break;
-
+
case 'h': {
bool success;
m_catch_bp = Args::StringToBoolean(option_arg, true, &success);
@@ -269,12 +453,6 @@ public:
m_hardware = true;
break;
- case 'i':
- if (option_arg.getAsInteger(0, m_ignore_count))
- error.SetErrorStringWithFormat("invalid ignore count '%s'",
- option_arg.str().c_str());
- break;
-
case 'K': {
bool success;
bool value;
@@ -347,10 +525,6 @@ public:
m_offset_addr = tmp_offset_addr;
} break;
- case 'o':
- m_one_shot = true;
- break;
-
case 'O':
m_exception_extra_args.AppendArgument("-O");
m_exception_extra_args.AppendArgument(option_arg);
@@ -360,10 +534,6 @@ public:
m_source_text_regexp.assign(option_arg);
break;
- case 'q':
- m_queue_name.assign(option_arg);
- break;
-
case 'r':
m_func_regexp.assign(option_arg);
break;
@@ -377,16 +547,6 @@ public:
m_func_name_type_mask |= eFunctionNameTypeSelector;
break;
- case 't':
- if (option_arg.getAsInteger(0, m_thread_id))
- error.SetErrorStringWithFormat("invalid thread id string '%s'",
- option_arg.str().c_str());
- break;
-
- case 'T':
- m_thread_name.assign(option_arg);
- break;
-
case 'w': {
bool success;
m_throw_bp = Args::StringToBoolean(option_arg, true, &success);
@@ -396,12 +556,6 @@ public:
option_arg.str().c_str());
} break;
- case 'x':
- if (option_arg.getAsInteger(0, m_thread_index))
- error.SetErrorStringWithFormat("invalid thread index string '%s'",
- option_arg.str().c_str());
- break;
-
case 'X':
m_source_regex_func_names.insert(option_arg);
break;
@@ -416,7 +570,6 @@ public:
}
void OptionParsingStarting(ExecutionContext *execution_context) override {
- m_condition.clear();
m_filenames.Clear();
m_line_num = 0;
m_column = 0;
@@ -427,19 +580,12 @@ public:
m_modules.Clear();
m_load_addr = LLDB_INVALID_ADDRESS;
m_offset_addr = 0;
- m_ignore_count = 0;
- m_thread_id = LLDB_INVALID_THREAD_ID;
- m_thread_index = UINT32_MAX;
- m_thread_name.clear();
- m_queue_name.clear();
m_catch_bp = false;
m_throw_bp = true;
m_hardware = false;
m_exception_language = eLanguageTypeUnknown;
m_language = lldb::eLanguageTypeUnknown;
m_skip_prologue = eLazyBoolCalculate;
- m_one_shot = false;
- m_use_dummy = false;
m_breakpoint_names.clear();
m_all_files = false;
m_exception_extra_args.Clear();
@@ -465,19 +611,12 @@ public:
FileSpecList m_modules;
lldb::addr_t m_load_addr;
lldb::addr_t m_offset_addr;
- uint32_t m_ignore_count;
- lldb::tid_t m_thread_id;
- uint32_t m_thread_index;
- std::string m_thread_name;
- std::string m_queue_name;
bool m_catch_bp;
bool m_throw_bp;
bool m_hardware; // Request to use hardware breakpoints
lldb::LanguageType m_exception_language;
lldb::LanguageType m_language;
LazyBool m_skip_prologue;
- bool m_one_shot;
- bool m_use_dummy;
bool m_all_files;
Args m_exception_extra_args;
LazyBool m_move_to_nearest_code;
@@ -486,7 +625,7 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
+ Target *target = GetSelectedOrDummyTarget(m_dummy_options.m_use_dummy);
if (target == nullptr) {
result.AppendError("Invalid target. Must set target before setting "
@@ -521,7 +660,7 @@ protected:
else if (m_options.m_exception_language != eLanguageTypeUnknown)
break_type = eSetTypeException;
- Breakpoint *bp = nullptr;
+ BreakpointSP bp_sp = nullptr;
FileSpec module_spec;
const bool internal = false;
@@ -553,35 +692,32 @@ protected:
// Only check for inline functions if
LazyBool check_inlines = eLazyBoolCalculate;
- bp = target
- ->CreateBreakpoint(&(m_options.m_modules), file,
- m_options.m_line_num, m_options.m_offset_addr,
- check_inlines, m_options.m_skip_prologue,
- internal, m_options.m_hardware,
- m_options.m_move_to_nearest_code)
- .get();
+ bp_sp = target->CreateBreakpoint(&(m_options.m_modules),
+ file,
+ m_options.m_line_num,
+ m_options.m_offset_addr,
+ check_inlines,
+ m_options.m_skip_prologue,
+ internal,
+ m_options.m_hardware,
+ m_options.m_move_to_nearest_code);
} break;
case eSetTypeAddress: // Breakpoint by address
{
// If a shared library has been specified, make an lldb_private::Address
- // with the library, and
- // use that. That way the address breakpoint will track the load location
- // of the library.
+ // with the library, and use that. That way the address breakpoint
+ // will track the load location of the library.
size_t num_modules_specified = m_options.m_modules.GetSize();
if (num_modules_specified == 1) {
const FileSpec *file_spec =
m_options.m_modules.GetFileSpecPointerAtIndex(0);
- bp = target
- ->CreateAddressInModuleBreakpoint(m_options.m_load_addr,
- internal, file_spec,
- m_options.m_hardware)
- .get();
+ bp_sp = target->CreateAddressInModuleBreakpoint(m_options.m_load_addr,
+ internal, file_spec,
+ m_options.m_hardware);
} else if (num_modules_specified == 0) {
- bp = target
- ->CreateBreakpoint(m_options.m_load_addr, internal,
- m_options.m_hardware)
- .get();
+ bp_sp = target->CreateBreakpoint(m_options.m_load_addr, internal,
+ m_options.m_hardware);
} else {
result.AppendError("Only one shared library can be specified for "
"address breakpoints.");
@@ -597,13 +733,15 @@ protected:
if (name_type_mask == 0)
name_type_mask = eFunctionNameTypeAuto;
- bp = target
- ->CreateBreakpoint(
- &(m_options.m_modules), &(m_options.m_filenames),
- m_options.m_func_names, name_type_mask, m_options.m_language,
- m_options.m_offset_addr, m_options.m_skip_prologue, internal,
- m_options.m_hardware)
- .get();
+ bp_sp = target->CreateBreakpoint(&(m_options.m_modules),
+ &(m_options.m_filenames),
+ m_options.m_func_names,
+ name_type_mask,
+ m_options.m_language,
+ m_options.m_offset_addr,
+ m_options.m_skip_prologue,
+ internal,
+ m_options.m_hardware);
} break;
case eSetTypeFunctionRegexp: // Breakpoint by regular expression function
@@ -620,12 +758,13 @@ protected:
return false;
}
- bp = target
- ->CreateFuncRegexBreakpoint(
- &(m_options.m_modules), &(m_options.m_filenames), regexp,
- m_options.m_language, m_options.m_skip_prologue, internal,
- m_options.m_hardware)
- .get();
+ bp_sp = target->CreateFuncRegexBreakpoint(&(m_options.m_modules),
+ &(m_options.m_filenames),
+ regexp,
+ m_options.m_language,
+ m_options.m_skip_prologue,
+ internal,
+ m_options.m_hardware);
}
break;
case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
@@ -654,26 +793,30 @@ protected:
result.SetStatus(eReturnStatusFailed);
return false;
}
- bp = target
- ->CreateSourceRegexBreakpoint(
- &(m_options.m_modules), &(m_options.m_filenames),
- m_options.m_source_regex_func_names, regexp, internal,
- m_options.m_hardware, m_options.m_move_to_nearest_code)
- .get();
+ bp_sp =
+ target->CreateSourceRegexBreakpoint(&(m_options.m_modules),
+ &(m_options.m_filenames),
+ m_options
+ .m_source_regex_func_names,
+ regexp,
+ internal,
+ m_options.m_hardware,
+ m_options.m_move_to_nearest_code);
} break;
case eSetTypeException: {
Status precond_error;
- bp = target
- ->CreateExceptionBreakpoint(
- m_options.m_exception_language, m_options.m_catch_bp,
- m_options.m_throw_bp, internal,
- &m_options.m_exception_extra_args, &precond_error)
- .get();
+ bp_sp = target->CreateExceptionBreakpoint(m_options.m_exception_language,
+ m_options.m_catch_bp,
+ m_options.m_throw_bp,
+ internal,
+ &m_options
+ .m_exception_extra_args,
+ &precond_error);
if (precond_error.Fail()) {
result.AppendErrorWithFormat(
"Error setting extra exception arguments: %s",
precond_error.AsCString());
- target->RemoveBreakpointByID(bp->GetID());
+ target->RemoveBreakpointByID(bp_sp->GetID());
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -683,64 +826,43 @@ protected:
}
// Now set the various options that were passed in:
- if (bp) {
- if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
- bp->SetThreadID(m_options.m_thread_id);
-
- if (m_options.m_thread_index != UINT32_MAX)
- bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
-
- if (!m_options.m_thread_name.empty())
- bp->GetOptions()->GetThreadSpec()->SetName(
- m_options.m_thread_name.c_str());
-
- if (!m_options.m_queue_name.empty())
- bp->GetOptions()->GetThreadSpec()->SetQueueName(
- m_options.m_queue_name.c_str());
-
- if (m_options.m_ignore_count != 0)
- bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
-
- if (!m_options.m_condition.empty())
- bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
+ if (bp_sp) {
+ bp_sp->GetOptions()->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions());
if (!m_options.m_breakpoint_names.empty()) {
Status name_error;
for (auto name : m_options.m_breakpoint_names) {
- bp->AddName(name.c_str(), name_error);
+ target->AddNameToBreakpoint(bp_sp, name.c_str(), name_error);
if (name_error.Fail()) {
result.AppendErrorWithFormat("Invalid breakpoint name: %s",
name.c_str());
- target->RemoveBreakpointByID(bp->GetID());
+ target->RemoveBreakpointByID(bp_sp->GetID());
result.SetStatus(eReturnStatusFailed);
return false;
}
}
}
-
- bp->SetOneShot(m_options.m_one_shot);
}
-
- if (bp) {
+
+ if (bp_sp) {
Stream &output_stream = result.GetOutputStream();
const bool show_locations = false;
- bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
+ bp_sp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
show_locations);
if (target == m_interpreter.GetDebugger().GetDummyTarget())
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.
- if (bp->GetNumLocations() == 0 && break_type != eSetTypeException) {
+ // 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");
}
}
result.SetStatus(eReturnStatusSuccessFinishResult);
- } else if (!bp) {
+ } else if (!bp_sp) {
result.AppendError("Breakpoint creation failed: No breakpoint created.");
result.SetStatus(eReturnStatusFailed);
}
@@ -782,29 +904,15 @@ private:
return true;
}
+ BreakpointOptionGroup m_bp_opts;
+ BreakpointDummyOptionGroup m_dummy_options;
CommandOptions m_options;
+ OptionGroupOptions m_all_options;
};
//-------------------------------------------------------------------------
// CommandObjectBreakpointModify
//-------------------------------------------------------------------------
-
-#pragma mark Modify::CommandOptions
-static OptionDefinition g_breakpoint_modify_options[] = {
- // clang-format off
- { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
- { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." },
- { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument." },
- { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument." },
- { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument." },
- { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument." },
- { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true." },
- { LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable the breakpoint." },
- { LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Disable the breakpoint." },
- { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." },
- // clang-format on
-};
-
#pragma mark Modify
class CommandObjectBreakpointModify : public CommandObjectParsed {
@@ -825,148 +933,21 @@ public:
// Add the entry for the first argument for this command to the object's
// arguments vector.
m_arguments.push_back(arg);
+
+ m_options.Append(&m_bp_opts,
+ LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3,
+ LLDB_OPT_SET_ALL);
+ m_options.Append(&m_dummy_opts, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
+ m_options.Finalize();
}
~CommandObjectBreakpointModify() override = default;
Options *GetOptions() override { return &m_options; }
- class CommandOptions : public Options {
- public:
- CommandOptions()
- : Options(), m_ignore_count(0), m_thread_id(LLDB_INVALID_THREAD_ID),
- m_thread_id_passed(false), m_thread_index(UINT32_MAX),
- m_thread_index_passed(false), m_thread_name(), m_queue_name(),
- m_condition(), m_one_shot(false), m_enable_passed(false),
- m_enable_value(false), m_name_passed(false), m_queue_passed(false),
- m_condition_passed(false), m_one_shot_passed(false),
- m_use_dummy(false) {}
-
- ~CommandOptions() override = default;
-
- Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
- ExecutionContext *execution_context) override {
- Status error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option) {
- case 'c':
- m_condition = option_arg;
- m_condition_passed = true;
- break;
- case 'd':
- m_enable_passed = true;
- m_enable_value = false;
- break;
- case 'D':
- m_use_dummy = true;
- break;
- case 'e':
- m_enable_passed = true;
- m_enable_value = true;
- break;
- case 'i':
- if (option_arg.getAsInteger(0, m_ignore_count))
- error.SetErrorStringWithFormat("invalid ignore count '%s'",
- option_arg.str().c_str());
- break;
- case 'o': {
- bool value, success;
- value = Args::StringToBoolean(option_arg, false, &success);
- if (success) {
- m_one_shot_passed = true;
- m_one_shot = value;
- } else
- error.SetErrorStringWithFormat(
- "invalid boolean value '%s' passed for -o option",
- option_arg.str().c_str());
- } break;
- case 't':
- if (option_arg[0] == '\0') {
- m_thread_id = LLDB_INVALID_THREAD_ID;
- m_thread_id_passed = true;
- } else {
- if (option_arg.getAsInteger(0, m_thread_id))
- error.SetErrorStringWithFormat("invalid thread id string '%s'",
- option_arg.str().c_str());
- else
- m_thread_id_passed = true;
- }
- break;
- case 'T':
- m_thread_name = option_arg;
- m_name_passed = true;
- break;
- case 'q':
- m_queue_name = option_arg;
- m_queue_passed = true;
- break;
- case 'x':
- if (option_arg[0] == '\n') {
- m_thread_index = UINT32_MAX;
- m_thread_index_passed = true;
- } else {
- if (option_arg.getAsInteger(0, m_thread_index))
- error.SetErrorStringWithFormat("invalid thread index string '%s'",
- option_arg.str().c_str());
- else
- m_thread_index_passed = true;
- }
- break;
- default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
- }
-
- return error;
- }
-
- void OptionParsingStarting(ExecutionContext *execution_context) override {
- m_ignore_count = 0;
- m_thread_id = LLDB_INVALID_THREAD_ID;
- m_thread_id_passed = false;
- m_thread_index = UINT32_MAX;
- m_thread_index_passed = false;
- m_thread_name.clear();
- m_queue_name.clear();
- m_condition.clear();
- m_one_shot = false;
- m_enable_passed = false;
- m_queue_passed = false;
- m_name_passed = false;
- m_condition_passed = false;
- m_one_shot_passed = false;
- m_use_dummy = false;
- }
-
- llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
- return llvm::makeArrayRef(g_breakpoint_modify_options);
- }
-
- // Instance variables to hold the values for command options.
-
- uint32_t m_ignore_count;
- lldb::tid_t m_thread_id;
- bool m_thread_id_passed;
- uint32_t m_thread_index;
- bool m_thread_index_passed;
- std::string m_thread_name;
- std::string m_queue_name;
- std::string m_condition;
- bool m_one_shot;
- bool m_enable_passed;
- bool m_enable_value;
- bool m_name_passed;
- bool m_queue_passed;
- bool m_condition_passed;
- bool m_one_shot_passed;
- bool m_use_dummy;
- };
-
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
+ Target *target = GetSelectedOrDummyTarget(m_dummy_opts.m_use_dummy);
if (target == nullptr) {
result.AppendError("Invalid target. No existing target or breakpoints.");
result.SetStatus(eReturnStatusFailed);
@@ -979,7 +960,8 @@ protected:
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids);
+ command, target, result, &valid_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::disablePerm);
if (result.Succeeded()) {
const size_t count = valid_bp_ids.GetSize();
@@ -992,49 +974,12 @@ protected:
if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
BreakpointLocation *location =
bp->FindLocationByID(cur_bp_id.GetLocationID()).get();
- if (location) {
- if (m_options.m_thread_id_passed)
- location->SetThreadID(m_options.m_thread_id);
-
- if (m_options.m_thread_index_passed)
- location->SetThreadIndex(m_options.m_thread_index);
-
- if (m_options.m_name_passed)
- location->SetThreadName(m_options.m_thread_name.c_str());
-
- if (m_options.m_queue_passed)
- location->SetQueueName(m_options.m_queue_name.c_str());
-
- if (m_options.m_ignore_count != 0)
- location->SetIgnoreCount(m_options.m_ignore_count);
-
- if (m_options.m_enable_passed)
- location->SetEnabled(m_options.m_enable_value);
-
- if (m_options.m_condition_passed)
- location->SetCondition(m_options.m_condition.c_str());
- }
+ if (location)
+ location->GetLocationOptions()
+ ->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions());
} else {
- if (m_options.m_thread_id_passed)
- bp->SetThreadID(m_options.m_thread_id);
-
- if (m_options.m_thread_index_passed)
- bp->SetThreadIndex(m_options.m_thread_index);
-
- if (m_options.m_name_passed)
- bp->SetThreadName(m_options.m_thread_name.c_str());
-
- if (m_options.m_queue_passed)
- bp->SetQueueName(m_options.m_queue_name.c_str());
-
- if (m_options.m_ignore_count != 0)
- bp->SetIgnoreCount(m_options.m_ignore_count);
-
- if (m_options.m_enable_passed)
- bp->SetEnabled(m_options.m_enable_value);
-
- if (m_options.m_condition_passed)
- bp->SetCondition(m_options.m_condition.c_str());
+ bp->GetOptions()
+ ->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions());
}
}
}
@@ -1044,7 +989,9 @@ protected:
}
private:
- CommandOptions m_options;
+ BreakpointOptionGroup m_bp_opts;
+ BreakpointDummyOptionGroup m_dummy_opts;
+ OptionGroupOptions m_options;
};
//-------------------------------------------------------------------------
@@ -1093,7 +1040,7 @@ protected:
if (command.empty()) {
// No breakpoint selected; enable all currently set breakpoints.
- target->EnableAllBreakpoints();
+ target->EnableAllowedBreakpoints();
result.AppendMessageWithFormat("All breakpoints enabled. (%" PRIu64
" breakpoints)\n",
(uint64_t)num_breakpoints);
@@ -1102,7 +1049,8 @@ protected:
// Particular breakpoint selected; enable that breakpoint.
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids);
+ command, target, result, &valid_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::disablePerm);
if (result.Succeeded()) {
int enable_count = 0;
@@ -1206,7 +1154,7 @@ protected:
if (command.empty()) {
// No breakpoint selected; disable all currently set breakpoints.
- target->DisableAllBreakpoints();
+ target->DisableAllowedBreakpoints();
result.AppendMessageWithFormat("All breakpoints disabled. (%" PRIu64
" breakpoints)\n",
(uint64_t)num_breakpoints);
@@ -1216,7 +1164,8 @@ protected:
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids);
+ command, target, result, &valid_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::disablePerm);
if (result.Succeeded()) {
int disable_count = 0;
@@ -1383,14 +1332,17 @@ protected:
result.AppendMessage("Current breakpoints:");
for (size_t i = 0; i < num_breakpoints; ++i) {
Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex(i).get();
- AddBreakpointDescription(&output_stream, breakpoint, m_options.m_level);
+ if (breakpoint->AllowList())
+ AddBreakpointDescription(&output_stream, breakpoint,
+ m_options.m_level);
}
result.SetStatus(eReturnStatusSuccessFinishNoResult);
} else {
// Particular breakpoints selected; show info about that breakpoint.
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids);
+ command, target, result, &valid_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::listPerm);
if (result.Succeeded()) {
for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) {
@@ -1678,7 +1630,7 @@ protected:
true)) {
result.AppendMessage("Operation cancelled...");
} else {
- target->RemoveAllBreakpoints();
+ target->RemoveAllowedBreakpoints();
result.AppendMessageWithFormat(
"All breakpoints removed. (%" PRIu64 " breakpoint%s)\n",
(uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
@@ -1688,7 +1640,8 @@ protected:
// Particular breakpoint selected; disable that breakpoint.
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids);
+ command, target, result, &valid_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::deletePerm);
if (result.Succeeded()) {
int delete_count = 0;
@@ -1734,9 +1687,10 @@ private:
static OptionDefinition g_breakpoint_name_options[] = {
// clang-format off
- {LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
- {LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointID, "Specify a breakpoint ID to use."},
- {LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
+ {LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
+ {LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointID, "Specify a breakpoint ID to use."},
+ {LLDB_OPT_SET_3, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
+ {LLDB_OPT_SET_4, false, "help-string", 'H', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "A help string describing the purpose of this name."},
// clang-format on
};
class BreakpointNameOptionGroup : public OptionGroup {
@@ -1762,7 +1716,6 @@ public:
error.Success())
m_name.SetValueFromString(option_arg);
break;
-
case 'B':
if (m_breakpoint.SetValueFromString(option_arg).Fail())
error.SetErrorStringWithFormat(
@@ -1775,6 +1728,9 @@ public:
"unrecognized value \"%s\" for use-dummy",
option_arg.str().c_str());
break;
+ case 'H':
+ m_help_string.SetValueFromString(option_arg);
+ break;
default:
error.SetErrorStringWithFormat("unrecognized short option '%c'",
@@ -1789,11 +1745,200 @@ public:
m_breakpoint.Clear();
m_use_dummy.Clear();
m_use_dummy.SetDefaultValue(false);
+ m_help_string.Clear();
}
OptionValueString m_name;
OptionValueUInt64 m_breakpoint;
OptionValueBoolean m_use_dummy;
+ OptionValueString m_help_string;
+};
+
+static OptionDefinition g_breakpoint_access_options[] = {
+ // clang-format off
+ {LLDB_OPT_SET_1, false, "allow-list", 'L', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Determines whether the breakpoint will show up in break list if not referred to explicitly."},
+ {LLDB_OPT_SET_2, false, "allow-disable", 'A', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Determines whether the breakpoint can be disabled by name or when all breakpoints are disabled."},
+ {LLDB_OPT_SET_3, false, "allow-delete", 'D', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Determines whether the breakpoint can be deleted by name or when all breakpoints are deleted."},
+ // clang-format on
+};
+
+class BreakpointAccessOptionGroup : public OptionGroup
+{
+public:
+ BreakpointAccessOptionGroup() :
+ OptionGroup()
+ {}
+
+ ~BreakpointAccessOptionGroup() override = default;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_breakpoint_access_options);
+ }
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Status error;
+ const int short_option
+ = g_breakpoint_access_options[option_idx].short_option;
+
+ switch (short_option) {
+ case 'L': {
+ bool value, success;
+ value = Args::StringToBoolean(option_arg, false, &success);
+ if (success) {
+ m_permissions.SetAllowList(value);
+ } else
+ error.SetErrorStringWithFormat(
+ "invalid boolean value '%s' passed for -L option",
+ option_arg.str().c_str());
+ } break;
+ case 'A': {
+ bool value, success;
+ value = Args::StringToBoolean(option_arg, false, &success);
+ if (success) {
+ m_permissions.SetAllowDisable(value);
+ } else
+ error.SetErrorStringWithFormat(
+ "invalid boolean value '%s' passed for -L option",
+ option_arg.str().c_str());
+ } break;
+ case 'D': {
+ bool value, success;
+ value = Args::StringToBoolean(option_arg, false, &success);
+ if (success) {
+ m_permissions.SetAllowDelete(value);
+ } else
+ error.SetErrorStringWithFormat(
+ "invalid boolean value '%s' passed for -L option",
+ option_arg.str().c_str());
+ } break;
+
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ }
+
+ const BreakpointName::Permissions &GetPermissions() const
+ {
+ return m_permissions;
+ }
+ BreakpointName::Permissions m_permissions;
+};
+
+class CommandObjectBreakpointNameConfigure : public CommandObjectParsed {
+public:
+ CommandObjectBreakpointNameConfigure(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "configure", "Configure the options for the breakpoint"
+ " name provided. "
+ "If you provide a breakpoint id, the options will be copied from "
+ "the breakpoint, otherwise only the options specified will be set "
+ "on the name.",
+ "breakpoint name configure <command-options> "
+ "<breakpoint-name-list>"),
+ m_bp_opts(), m_option_group() {
+ // Create the first variant for the first (and only) argument for this
+ // command.
+ CommandArgumentEntry arg1;
+ CommandArgumentData id_arg;
+ id_arg.arg_type = eArgTypeBreakpointName;
+ id_arg.arg_repetition = eArgRepeatOptional;
+ arg1.push_back(id_arg);
+ m_arguments.push_back(arg1);
+
+ m_option_group.Append(&m_bp_opts,
+ LLDB_OPT_SET_ALL,
+ LLDB_OPT_SET_1);
+ m_option_group.Append(&m_access_options,
+ LLDB_OPT_SET_ALL,
+ LLDB_OPT_SET_ALL);
+ m_option_group.Append(&m_bp_id,
+ LLDB_OPT_SET_2|LLDB_OPT_SET_4,
+ LLDB_OPT_SET_ALL);
+ m_option_group.Finalize();
+ }
+
+ ~CommandObjectBreakpointNameConfigure() override = default;
+
+ Options *GetOptions() override { return &m_option_group; }
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+
+ const size_t argc = command.GetArgumentCount();
+ if (argc == 0) {
+ result.AppendError("No names provided.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ Target *target =
+ GetSelectedOrDummyTarget(false);
+
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No existing target or breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
+
+ // Make a pass through first to see that all the names are legal.
+ for (auto &entry : command.entries()) {
+ Status error;
+ if (!BreakpointID::StringIsBreakpointName(entry.ref, error))
+ {
+ result.AppendErrorWithFormat("Invalid breakpoint name: %s - %s",
+ entry.c_str(), error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+ // 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())
+ {
+ lldb::break_id_t bp_id = m_bp_id.m_breakpoint.GetUInt64Value();
+ bp_sp = target->GetBreakpointByID(bp_id);
+ if (!bp_sp)
+ {
+ result.AppendErrorWithFormatv("Could not find specified breakpoint {0}",
+ bp_id);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+
+ Status error;
+ for (auto &entry : command.entries()) {
+ ConstString name(entry.c_str());
+ BreakpointName *bp_name = target->FindBreakpointName(name, true, error);
+ if (!bp_name)
+ continue;
+ if (m_bp_id.m_help_string.OptionWasSet())
+ bp_name->SetHelp(m_bp_id.m_help_string.GetStringValue().str().c_str());
+
+ if (bp_sp)
+ target->ConfigureBreakpointName(*bp_name,
+ *bp_sp->GetOptions(),
+ m_access_options.GetPermissions());
+ else
+ target->ConfigureBreakpointName(*bp_name,
+ m_bp_opts.GetBreakpointOptions(),
+ m_access_options.GetPermissions());
+ }
+ return true;
+ }
+
+private:
+ BreakpointNameOptionGroup m_bp_id; // Only using the id part of this.
+ BreakpointOptionGroup m_bp_opts;
+ BreakpointAccessOptionGroup m_access_options;
+ OptionGroupOptions m_option_group;
};
class CommandObjectBreakpointNameAdd : public CommandObjectParsed {
@@ -1851,7 +1996,8 @@ protected:
// Particular breakpoint selected; disable that breakpoint.
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
- command, target, result, &valid_bp_ids);
+ command, target, result, &valid_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::listPerm);
if (result.Succeeded()) {
if (valid_bp_ids.GetSize() == 0) {
@@ -1860,13 +2006,14 @@ protected:
return false;
}
size_t num_valid_ids = valid_bp_ids.GetSize();
+ const char *bp_name = m_name_options.m_name.GetCurrentValue();
+ Status error; // This error reports illegal names, but we've already
+ // checked that, so we don't need to check it again here.
for (size_t index = 0; index < num_valid_ids; index++) {
lldb::break_id_t bp_id =
valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
- Status error; // We don't need to check the error here, since the option
- // parser checked it...
- bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
+ target->AddNameToBreakpoint(bp_sp, bp_name, error);
}
}
@@ -1934,7 +2081,8 @@ protected:
// Particular breakpoint selected; disable that breakpoint.
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
- command, target, result, &valid_bp_ids);
+ command, target, result, &valid_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::deletePerm);
if (result.Succeeded()) {
if (valid_bp_ids.GetSize() == 0) {
@@ -1942,12 +2090,13 @@ protected:
result.SetStatus(eReturnStatusFailed);
return false;
}
+ ConstString bp_name(m_name_options.m_name.GetCurrentValue());
size_t num_valid_ids = valid_bp_ids.GetSize();
for (size_t index = 0; index < num_valid_ids; index++) {
lldb::break_id_t bp_id =
valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
- bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
+ target->RemoveNameFromBreakpoint(bp_sp, bp_name);
}
}
@@ -1963,11 +2112,12 @@ class CommandObjectBreakpointNameList : public CommandObjectParsed {
public:
CommandObjectBreakpointNameList(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "list",
- "List either the names for a breakpoint or the "
- "breakpoints for a given name.",
+ "List either the names for a breakpoint or info "
+ "about a given name. With no arguments, lists all "
+ "names",
"breakpoint name list <command-options>"),
m_name_options(), m_option_group() {
- m_option_group.Append(&m_name_options);
+ m_option_group.Append(&m_name_options, LLDB_OPT_SET_3, LLDB_OPT_SET_ALL);
m_option_group.Finalize();
}
@@ -1985,42 +2135,57 @@ protected:
result.SetStatus(eReturnStatusFailed);
return false;
}
-
- if (m_name_options.m_name.OptionWasSet()) {
- const char *name = m_name_options.m_name.GetCurrentValue();
- std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
-
- BreakpointList &breakpoints = target->GetBreakpointList();
- for (BreakpointSP bp_sp : breakpoints.Breakpoints()) {
- if (bp_sp->MatchesName(name)) {
+
+
+ std::vector<std::string> name_list;
+ if (command.empty()) {
+ target->GetBreakpointNames(name_list);
+ } else {
+ for (const Args::ArgEntry &arg : command)
+ {
+ name_list.push_back(arg.c_str());
+ }
+ }
+
+ if (name_list.empty()) {
+ result.AppendMessage("No breakpoint names found.");
+ } else {
+ for (const std::string &name_str : name_list) {
+ const char *name = name_str.c_str();
+ // First print out the options for the name:
+ Status error;
+ BreakpointName *bp_name = target->FindBreakpointName(ConstString(name),
+ false,
+ error);
+ if (bp_name)
+ {
StreamString s;
- bp_sp->GetDescription(&s, eDescriptionLevelBrief);
- s.EOL();
- result.AppendMessage(s.GetString());
+ result.AppendMessageWithFormat("Name: %s\n", name);
+ if (bp_name->GetDescription(&s, eDescriptionLevelFull))
+ {
+ result.AppendMessage(s.GetString());
+ }
+
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
+
+ BreakpointList &breakpoints = target->GetBreakpointList();
+ bool any_set = false;
+ for (BreakpointSP bp_sp : breakpoints.Breakpoints()) {
+ if (bp_sp->MatchesName(name)) {
+ StreamString s;
+ any_set = true;
+ bp_sp->GetDescription(&s, eDescriptionLevelBrief);
+ s.EOL();
+ result.AppendMessage(s.GetString());
+ }
+ }
+ if (!any_set)
+ result.AppendMessage("No breakpoints using this name.");
+ } else {
+ result.AppendMessageWithFormat("Name: %s not found.\n", name);
}
}
-
- } else if (m_name_options.m_breakpoint.OptionWasSet()) {
- BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(
- m_name_options.m_breakpoint.GetCurrentValue());
- if (bp_sp) {
- std::vector<std::string> names;
- bp_sp->GetNames(names);
- result.AppendMessage("Names:");
- for (auto name : names)
- result.AppendMessageWithFormat(" %s\n", name.c_str());
- } else {
- result.AppendErrorWithFormat(
- "Could not find breakpoint %" PRId64 ".\n",
- m_name_options.m_breakpoint.GetCurrentValue());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- } else {
- result.SetError("Must specify -N or -B option to list.");
- result.SetStatus(eReturnStatusFailed);
- return false;
}
return true;
}
@@ -2045,10 +2210,13 @@ public:
new CommandObjectBreakpointNameDelete(interpreter));
CommandObjectSP list_command_object(
new CommandObjectBreakpointNameList(interpreter));
+ CommandObjectSP configure_command_object(
+ new CommandObjectBreakpointNameConfigure(interpreter));
LoadSubCommand("add", add_command_object);
LoadSubCommand("delete", delete_command_object);
LoadSubCommand("list", list_command_object);
+ LoadSubCommand("configure", configure_command_object);
}
~CommandObjectBreakpointName() override = default;
@@ -2274,7 +2442,8 @@ protected:
BreakpointIDList valid_bp_ids;
if (!command.empty()) {
CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
- command, target, result, &valid_bp_ids);
+ command, target, result, &valid_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::listPerm);
if (!result.Succeeded()) {
result.SetStatus(eReturnStatusFailed);
@@ -2359,7 +2528,10 @@ CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint() = default;
void CommandObjectMultiwordBreakpoint::VerifyIDs(Args &args, Target *target,
bool allow_locations,
CommandReturnObject &result,
- BreakpointIDList *valid_ids) {
+ BreakpointIDList *valid_ids,
+ BreakpointName::Permissions
+ ::PermissionKinds
+ purpose) {
// args can be strings representing 1). integers (for breakpoint ids)
// 2). the full breakpoint & location
// canonical representation
@@ -2393,8 +2565,8 @@ void CommandObjectMultiwordBreakpoint::VerifyIDs(Args &args, Target *target,
// all the breakpoint ids in the range, and shove all of those breakpoint id
// strings into TEMP_ARGS.
- BreakpointIDList::FindAndReplaceIDRanges(args, target, allow_locations,
- result, temp_args);
+ BreakpointIDList::FindAndReplaceIDRanges(args, target, allow_locations,
+ purpose, result, temp_args);
// NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual
// BreakpointIDList:
diff --git a/source/Commands/CommandObjectBreakpoint.h b/source/Commands/CommandObjectBreakpoint.h
index 6e14b8f876a01..5e1026a6b7eaf 100644
--- a/source/Commands/CommandObjectBreakpoint.h
+++ b/source/Commands/CommandObjectBreakpoint.h
@@ -18,11 +18,14 @@
// Other libraries and framework includes
// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Breakpoint/BreakpointName.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/STLUtils.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/Options.h"
+
namespace lldb_private {
//-------------------------------------------------------------------------
@@ -37,20 +40,26 @@ public:
static void VerifyBreakpointOrLocationIDs(Args &args, Target *target,
CommandReturnObject &result,
- BreakpointIDList *valid_ids) {
- VerifyIDs(args, target, true, result, valid_ids);
+ BreakpointIDList *valid_ids,
+ BreakpointName::Permissions
+ ::PermissionKinds purpose) {
+ VerifyIDs(args, target, true, result, valid_ids, purpose);
}
static void VerifyBreakpointIDs(Args &args, Target *target,
CommandReturnObject &result,
- BreakpointIDList *valid_ids) {
- VerifyIDs(args, target, false, result, valid_ids);
+ BreakpointIDList *valid_ids,
+ BreakpointName::Permissions::PermissionKinds
+ purpose) {
+ VerifyIDs(args, target, false, result, valid_ids, purpose);
}
private:
static void VerifyIDs(Args &args, Target *target, bool allow_locations,
CommandReturnObject &result,
- BreakpointIDList *valid_ids);
+ BreakpointIDList *valid_ids,
+ BreakpointName::Permissions::PermissionKinds
+ purpose);
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectBreakpointCommand.cpp b/source/Commands/CommandObjectBreakpointCommand.cpp
index de49119531076..170cb85131160 100644
--- a/source/Commands/CommandObjectBreakpointCommand.cpp
+++ b/source/Commands/CommandObjectBreakpointCommand.cpp
@@ -390,7 +390,8 @@ protected:
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids);
+ command, target, result, &valid_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::listPerm);
m_bp_options_vec.clear();
@@ -571,7 +572,8 @@ protected:
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids);
+ command, target, result, &valid_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::listPerm);
if (result.Succeeded()) {
const size_t count = valid_bp_ids.GetSize();
@@ -662,7 +664,8 @@ protected:
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids);
+ command, target, result, &valid_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::listPerm);
if (result.Succeeded()) {
const size_t count = valid_bp_ids.GetSize();
@@ -673,48 +676,49 @@ protected:
target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
if (bp) {
- const BreakpointOptions *bp_options = nullptr;
+ BreakpointLocationSP bp_loc_sp;
if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
- BreakpointLocationSP bp_loc_sp(
- bp->FindLocationByID(cur_bp_id.GetLocationID()));
- if (bp_loc_sp)
- bp_options = bp_loc_sp->GetOptionsNoCreate();
- else {
+ bp_loc_sp = bp->FindLocationByID(cur_bp_id.GetLocationID());
+ if (!bp_loc_sp)
+ {
result.AppendErrorWithFormat("Invalid breakpoint ID: %u.%u.\n",
cur_bp_id.GetBreakpointID(),
cur_bp_id.GetLocationID());
result.SetStatus(eReturnStatusFailed);
return false;
}
- } else {
- bp_options = bp->GetOptions();
}
- if (bp_options) {
- StreamString id_str;
- BreakpointID::GetCanonicalReference(&id_str,
- cur_bp_id.GetBreakpointID(),
- cur_bp_id.GetLocationID());
- const Baton *baton = bp_options->GetBaton();
- if (baton) {
- result.GetOutputStream().Printf("Breakpoint %s:\n",
- id_str.GetData());
- result.GetOutputStream().IndentMore();
- baton->GetDescription(&result.GetOutputStream(),
- eDescriptionLevelFull);
- result.GetOutputStream().IndentLess();
- } else {
- result.AppendMessageWithFormat(
- "Breakpoint %s does not have an associated command.\n",
- id_str.GetData());
- }
+ StreamString id_str;
+ BreakpointID::GetCanonicalReference(&id_str,
+ cur_bp_id.GetBreakpointID(),
+ cur_bp_id.GetLocationID());
+ const Baton *baton = nullptr;
+ if (bp_loc_sp)
+ baton = bp_loc_sp
+ ->GetOptionsSpecifyingKind(BreakpointOptions::eCallback)
+ ->GetBaton();
+ else
+ baton = bp->GetOptions()->GetBaton();
+
+ if (baton) {
+ result.GetOutputStream().Printf("Breakpoint %s:\n",
+ id_str.GetData());
+ result.GetOutputStream().IndentMore();
+ baton->GetDescription(&result.GetOutputStream(),
+ eDescriptionLevelFull);
+ result.GetOutputStream().IndentLess();
+ } else {
+ result.AppendMessageWithFormat(
+ "Breakpoint %s does not have an associated command.\n",
+ id_str.GetData());
}
- result.SetStatus(eReturnStatusSuccessFinishResult);
- } else {
- result.AppendErrorWithFormat("Invalid breakpoint ID: %u.\n",
- cur_bp_id.GetBreakpointID());
- result.SetStatus(eReturnStatusFailed);
}
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat("Invalid breakpoint ID: %u.\n",
+ cur_bp_id.GetBreakpointID());
+ result.SetStatus(eReturnStatusFailed);
}
}
}
diff --git a/source/Commands/CommandObjectDisassemble.cpp b/source/Commands/CommandObjectDisassemble.cpp
index 5d0f2417f992e..31c54b7d433b3 100644
--- a/source/Commands/CommandObjectDisassemble.cpp
+++ b/source/Commands/CommandObjectDisassemble.cpp
@@ -163,8 +163,7 @@ Status CommandObjectDisassemble::CommandOptions::SetOptionValue(
auto target_sp =
execution_context ? execution_context->GetTargetSP() : TargetSP();
auto platform_sp = target_sp ? target_sp->GetPlatform() : PlatformSP();
- if (!arch.SetTriple(option_arg, platform_sp.get()))
- arch.SetTriple(option_arg);
+ arch = Platform::GetAugmentedArchSpec(platform_sp.get(), option_arg);
}
break;
diff --git a/source/Commands/CommandObjectDisassemble.h b/source/Commands/CommandObjectDisassemble.h
index 8ca390056dd86..af15d45eb76bc 100644
--- a/source/Commands/CommandObjectDisassemble.h
+++ b/source/Commands/CommandObjectDisassemble.h
@@ -10,13 +10,9 @@
#ifndef liblldb_CommandObjectDisassemble_h_
#define liblldb_CommandObjectDisassemble_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/Options.h"
+#include "lldb/Utility/ArchSpec.h"
namespace lldb_private {
diff --git a/source/Commands/CommandObjectExpression.cpp b/source/Commands/CommandObjectExpression.cpp
index b6e0016c88e49..01ca311115556 100644
--- a/source/Commands/CommandObjectExpression.cpp
+++ b/source/Commands/CommandObjectExpression.cpp
@@ -228,6 +228,16 @@ CommandObjectExpression::CommandObjectExpression(
m_command_options(), m_expr_line_count(0), m_expr_lines() {
SetHelpLong(
R"(
+Single and multi-line expressions:
+
+)"
+ " The expression provided on the command line must be a complete expression \
+with no newlines. To evaluate a multi-line expression, \
+hit a return after an empty expression, and lldb will enter the multi-line expression editor. \
+Hit return on an empty line to end the multi-line expression."
+
+ R"(
+
Timeouts:
)"
@@ -256,6 +266,7 @@ from the stack with \"thread return -x\" or if you are still interested in the e
you can issue the \"continue\" command and the expression evaluation will complete and the \
expression result will be available using the \"thread.completed-expression\" key in the thread \
format."
+
R"(
Examples:
diff --git a/source/Commands/CommandObjectFrame.h b/source/Commands/CommandObjectFrame.h
index 875bcc944a384..3199399163df3 100644
--- a/source/Commands/CommandObjectFrame.h
+++ b/source/Commands/CommandObjectFrame.h
@@ -10,11 +10,6 @@
#ifndef liblldb_CommandObjectFrame_h_
#define liblldb_CommandObjectFrame_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/Options.h"
diff --git a/source/Commands/CommandObjectPlatform.cpp b/source/Commands/CommandObjectPlatform.cpp
index 5fa851f584a75..8ed003767d588 100644
--- a/source/Commands/CommandObjectPlatform.cpp
+++ b/source/Commands/CommandObjectPlatform.cpp
@@ -302,7 +302,7 @@ protected:
platform_sp->GetStatus(ostrm);
result.SetStatus(eReturnStatusSuccessFinishResult);
} else {
- result.AppendError("no platform us currently selected\n");
+ result.AppendError("no platform is currently selected\n");
result.SetStatus(eReturnStatusFailed);
}
return result.Succeeded();
@@ -1337,8 +1337,8 @@ protected:
PlatformSP platform_sp =
debugger_sp ? debugger_sp->GetPlatformList().GetSelectedPlatform()
: PlatformSP();
- match_info.GetProcessInfo().GetArchitecture().SetTriple(
- option_arg, platform_sp.get());
+ match_info.GetProcessInfo().GetArchitecture() =
+ Platform::GetAugmentedArchSpec(platform_sp.get(), option_arg);
} break;
case 'n':
diff --git a/source/Commands/CommandObjectSource.cpp b/source/Commands/CommandObjectSource.cpp
index f3c92b9a28c05..066cc59c5c315 100644
--- a/source/Commands/CommandObjectSource.cpp
+++ b/source/Commands/CommandObjectSource.cpp
@@ -902,7 +902,7 @@ protected:
// We don't care about the column here.
const uint32_t column = 0;
return target->GetSourceManager().DisplaySourceLinesWithLineNumbers(
- start_file, line_no, 0, m_options.num_lines, column, "",
+ start_file, line_no, column, 0, m_options.num_lines, "",
&result.GetOutputStream(), GetBreakpointLocations());
} else {
result.AppendErrorWithFormat(
@@ -1161,7 +1161,7 @@ protected:
? sc.line_entry.column
: 0;
target->GetSourceManager().DisplaySourceLinesWithLineNumbers(
- sc.comp_unit, sc.line_entry.line, lines_to_back_up, column,
+ sc.comp_unit, sc.line_entry.line, column, lines_to_back_up,
m_options.num_lines - lines_to_back_up, "->",
&result.GetOutputStream(), GetBreakpointLocations());
result.SetStatus(eReturnStatusSuccessFinishResult);
@@ -1283,8 +1283,9 @@ protected:
m_options.num_lines = 10;
const uint32_t column = 0;
target->GetSourceManager().DisplaySourceLinesWithLineNumbers(
- sc.comp_unit, m_options.start_line, 0, m_options.num_lines,
- column, "", &result.GetOutputStream(), GetBreakpointLocations());
+ sc.comp_unit, m_options.start_line, column,
+ 0, m_options.num_lines,
+ "", &result.GetOutputStream(), GetBreakpointLocations());
result.SetStatus(eReturnStatusSuccessFinishResult);
} else {
diff --git a/source/Commands/CommandObjectTarget.cpp b/source/Commands/CommandObjectTarget.cpp
index a80acf19be2d4..c83061d8de740 100644
--- a/source/Commands/CommandObjectTarget.cpp
+++ b/source/Commands/CommandObjectTarget.cpp
@@ -52,6 +52,7 @@
#include "lldb/Utility/Timer.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/FormatAdapters.h"
// C Includes
// C++ Includes
@@ -135,25 +136,6 @@ static uint32_t DumpTargetList(TargetList &target_list,
return num_targets;
}
-// TODO: Remove this once llvm can pretty-print time points
-static void DumpTimePoint(llvm::sys::TimePoint<> tp, Stream &s, uint32_t width) {
-#ifndef LLDB_DISABLE_POSIX
- char time_buf[32];
- time_t time = llvm::sys::toTimeT(tp);
- char *time_cstr = ::ctime_r(&time, time_buf);
- if (time_cstr) {
- char *newline = ::strpbrk(time_cstr, "\n\r");
- if (newline)
- *newline = '\0';
- if (width > 0)
- s.Printf("%-*s", width, time_cstr);
- else
- s.PutCString(time_cstr);
- } else if (width > 0)
- s.Printf("%-*s", width, "");
-#endif
-}
-
#pragma mark CommandObjectTargetCreate
//-------------------------------------------------------------------------
@@ -2053,6 +2035,8 @@ protected:
result.GetOutputStream().EOL();
result.GetOutputStream().EOL();
}
+ if (m_interpreter.WasInterrupted())
+ break;
num_dumped++;
DumpModuleSymtab(
m_interpreter, result.GetOutputStream(),
@@ -2081,6 +2065,8 @@ protected:
result.GetOutputStream().EOL();
result.GetOutputStream().EOL();
}
+ if (m_interpreter.WasInterrupted())
+ break;
num_dumped++;
DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
module, m_options.m_sort_order);
@@ -2146,6 +2132,8 @@ protected:
" modules.\n",
(uint64_t)num_modules);
for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
+ if (m_interpreter.WasInterrupted())
+ break;
num_dumped++;
DumpModuleSections(
m_interpreter, result.GetOutputStream(),
@@ -2167,6 +2155,8 @@ protected:
FindModulesByName(target, arg_cstr, module_list, true);
if (num_matches > 0) {
for (size_t i = 0; i < num_matches; ++i) {
+ if (m_interpreter.WasInterrupted())
+ break;
Module *module = module_list.GetModulePointerAtIndex(i);
if (module) {
num_dumped++;
@@ -2239,6 +2229,8 @@ protected:
" modules.\n",
(uint64_t)num_modules);
for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
+ if (m_interpreter.WasInterrupted())
+ break;
if (DumpModuleSymbolVendor(
result.GetOutputStream(),
target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
@@ -2260,6 +2252,8 @@ protected:
FindModulesByName(target, arg_cstr, module_list, true);
if (num_matches > 0) {
for (size_t i = 0; i < num_matches; ++i) {
+ if (m_interpreter.WasInterrupted())
+ break;
Module *module = module_list.GetModulePointerAtIndex(i);
if (module) {
if (DumpModuleSymbolVendor(result.GetOutputStream(), module))
@@ -2327,6 +2321,8 @@ protected:
if (num_modules > 0) {
uint32_t num_dumped = 0;
for (uint32_t i = 0; i < num_modules; ++i) {
+ if (m_interpreter.WasInterrupted())
+ break;
if (DumpCompileUnitLineTable(
m_interpreter, result.GetOutputStream(),
target_modules.GetModulePointerAtIndexUnlocked(i),
@@ -2572,7 +2568,7 @@ public:
"Fullpath or basename for module to load.", ""),
m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
"Write file contents to the memory.", false, true),
- m_pc_option(LLDB_OPT_SET_1, false, "--set-pc-to-entry", 'p',
+ m_pc_option(LLDB_OPT_SET_1, false, "set-pc-to-entry", 'p',
"Set PC to the entry point."
" Only applicable with '--load' option.",
false, true),
@@ -3162,7 +3158,8 @@ protected:
} break;
case 'm':
- DumpTimePoint(module->GetModificationTime(), strm, width);
+ strm.Format("{0:%c}", llvm::fmt_align(module->GetModificationTime(),
+ llvm::AlignStyle::Left, width));
break;
case 'p':
@@ -3969,7 +3966,8 @@ public:
"Add a debug symbol file to one of the target's current modules by "
"specifying a path to a debug symbols file, or using the options "
"to specify a module to download symbols for.",
- "target symbols add [<symfile>]", eCommandRequiresTarget),
+ "target symbols add <cmd-options> [<symfile>]",
+ eCommandRequiresTarget),
m_option_group(),
m_file_option(
LLDB_OPT_SET_1, false, "shlib", 's',
@@ -4289,18 +4287,22 @@ protected:
if (uuid_option_set) {
result.AppendError("specify either one or more paths to symbol files "
"or use the --uuid option without arguments");
- } else if (file_option_set) {
- result.AppendError("specify either one or more paths to symbol files "
- "or use the --file option without arguments");
} else if (frame_option_set) {
result.AppendError("specify either one or more paths to symbol files "
"or use the --frame option without arguments");
+ } else if (file_option_set && argc > 1) {
+ result.AppendError("specify at most one symbol file path when "
+ "--shlib option is set");
} else {
PlatformSP platform_sp(target->GetPlatform());
for (auto &entry : args.entries()) {
if (!entry.ref.empty()) {
module_spec.GetSymbolFileSpec().SetFile(entry.ref, true);
+ if (file_option_set) {
+ module_spec.GetFileSpec() =
+ m_file_option.GetOptionValue().GetCurrentValue();
+ }
if (platform_sp) {
FileSpec symfile_spec;
if (platform_sp
diff --git a/source/Commands/CommandObjectTarget.h b/source/Commands/CommandObjectTarget.h
index 865534111eec5..643ce547dcb62 100644
--- a/source/Commands/CommandObjectTarget.h
+++ b/source/Commands/CommandObjectTarget.h
@@ -10,11 +10,6 @@
#ifndef liblldb_CommandObjectTarget_h_
#define liblldb_CommandObjectTarget_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/Options.h"
diff --git a/source/Commands/CommandObjectThread.cpp b/source/Commands/CommandObjectThread.cpp
index 6a933df43e149..b68aa920b5821 100644
--- a/source/Commands/CommandObjectThread.cpp
+++ b/source/Commands/CommandObjectThread.cpp
@@ -94,7 +94,7 @@ public:
bool all_threads = false;
if (command.GetArgumentCount() == 0) {
Thread *thread = m_exe_ctx.GetThreadPtr();
- if (!HandleOneThread(thread->GetID(), result))
+ if (!thread || !HandleOneThread(thread->GetID(), result))
return false;
return result.Succeeded();
} else if (command.GetArgumentCount() == 1) {
@@ -775,6 +775,12 @@ protected:
else
error = process->Resume();
+ if (!error.Success()) {
+ result.AppendMessage(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
// 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
diff --git a/source/Core/Address.cpp b/source/Core/Address.cpp
index 0c929c22f75f6..54b485ce03549 100644
--- a/source/Core/Address.cpp
+++ b/source/Core/Address.cpp
@@ -8,8 +8,6 @@
//===----------------------------------------------------------------------===//
#include "lldb/Core/Address.h"
-
-#include "lldb/Core/ArchSpec.h" // for ArchSpec
#include "lldb/Core/DumpDataExtractor.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h" // for ModuleList
diff --git a/source/Core/AddressRange.cpp b/source/Core/AddressRange.cpp
index c1507797b374c..e125b693d6f64 100644
--- a/source/Core/AddressRange.cpp
+++ b/source/Core/AddressRange.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "lldb/Core/AddressRange.h"
-#include "lldb/Core/ArchSpec.h" // for ArchSpec
#include "lldb/Core/Module.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ConstString.h" // for ConstString
diff --git a/source/Core/CMakeLists.txt b/source/Core/CMakeLists.txt
index c345afb4064ad..cac56e29fc191 100644
--- a/source/Core/CMakeLists.txt
+++ b/source/Core/CMakeLists.txt
@@ -13,7 +13,6 @@ add_lldb_library(lldbCore
AddressResolver.cpp
AddressResolverFileLine.cpp
AddressResolverName.cpp
- ArchSpec.cpp
Broadcaster.cpp
Communication.cpp
Debugger.cpp
diff --git a/source/Core/Debugger.cpp b/source/Core/Debugger.cpp
index d42e4df56d8bc..a4d78151c75fd 100644
--- a/source/Core/Debugger.cpp
+++ b/source/Core/Debugger.cpp
@@ -1170,7 +1170,7 @@ TestPromptFormats (StackFrame *frame)
return;
StreamString s;
- const char *prompt_format =
+ const char *prompt_format =
"{addr = '${addr}'\n}"
"{addr-file-or-load = '${addr-file-or-load}'\n}"
"{current-pc-arrow = '${current-pc-arrow}'\n}"
diff --git a/source/Core/DumpDataExtractor.cpp b/source/Core/DumpDataExtractor.cpp
index c2a9115c30682..e564e86478fc1 100644
--- a/source/Core/DumpDataExtractor.cpp
+++ b/source/Core/DumpDataExtractor.cpp
@@ -272,6 +272,13 @@ lldb::offset_t lldb_private::DumpDataExtractor(
case eFormatChar:
case eFormatCharPrintable:
case eFormatCharArray: {
+ // Reject invalid item_byte_size.
+ if (item_byte_size > 8) {
+ s->Printf("error: unsupported byte size (%" PRIu64 ") for char format",
+ (uint64_t)item_byte_size);
+ return offset;
+ }
+
// If we are only printing one character surround it with single
// quotes
if (item_count == 1 && item_format == eFormatChar)
diff --git a/source/Core/FileSpecList.cpp b/source/Core/FileSpecList.cpp
index a69f490f9aedd..5b0bdac654e13 100644
--- a/source/Core/FileSpecList.cpp
+++ b/source/Core/FileSpecList.cpp
@@ -49,7 +49,7 @@ void FileSpecList::Append(const FileSpec &file_spec) {
// contained a copy of "file_spec".
//------------------------------------------------------------------
bool FileSpecList::AppendIfUnique(const FileSpec &file_spec) {
- collection::iterator pos, end = m_files.end();
+ collection::iterator end = m_files.end();
if (find(m_files.begin(), end, file_spec) == end) {
m_files.push_back(file_spec);
return true;
@@ -147,36 +147,5 @@ size_t FileSpecList::GetSize() const { return m_files.size(); }
size_t FileSpecList::GetFilesMatchingPartialPath(const char *path,
bool dir_okay,
FileSpecList &matches) {
-#if 0 // FIXME: Just sketching...
- matches.Clear();
- using namespace llvm::sys::fs;
- file_status stats;
- if (status(path, stats, false))
- return 0;
- if (exists(stats)) {
- if (is_symlink_file(stats)) {
- // Shouldn't there be a method that realpath's a file?
- }
- if (is_regular_file(stats) || (is_directory(stats) && dir_okay)) {
- matches.Append(FileSpec(path));
- return 1;
- } else if (is_directory(stats)) {
- // Fill the match list with all the files in the directory:
- } else {
- return 0;
- }
- } else {
- ConstString dir_name = path_spec.GetDirectory();
- ConstString file_name = GetFilename();
- if (dir_name == nullptr)
- {
- // Match files in the CWD.
- }
- else
- {
- // Match files in the given directory:
- }
- }
-#endif
return 0;
}
diff --git a/source/Core/FormatEntity.cpp b/source/Core/FormatEntity.cpp
index 6002efe9244d9..0cb74cc7658da 100644
--- a/source/Core/FormatEntity.cpp
+++ b/source/Core/FormatEntity.cpp
@@ -11,7 +11,6 @@
#include "lldb/Core/Address.h"
#include "lldb/Core/AddressRange.h" // for AddressRange
-#include "lldb/Core/ArchSpec.h" // for ArchSpec
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/RegisterValue.h" // for RegisterValue
@@ -42,6 +41,7 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/AnsiTerminal.h"
+#include "lldb/Utility/ArchSpec.h" // for ArchSpec
#include "lldb/Utility/ConstString.h" // for ConstString, oper...
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h" // for Log
diff --git a/source/Core/IOHandler.cpp b/source/Core/IOHandler.cpp
index 194fec8a87984..103b5ecde94a8 100644
--- a/source/Core/IOHandler.cpp
+++ b/source/Core/IOHandler.cpp
@@ -1146,7 +1146,7 @@ public:
const char *text = m_delegate_sp->WindowDelegateGetHelpText();
KeyHelp *key_help = m_delegate_sp->WindowDelegateGetKeyHelp();
if ((text && text[0]) || key_help) {
- std::auto_ptr<HelpDialogDelegate> help_delegate_ap(
+ std::unique_ptr<HelpDialogDelegate> help_delegate_ap(
new HelpDialogDelegate(text, key_help));
const size_t num_lines = help_delegate_ap->GetNumLines();
const size_t max_length = help_delegate_ap->GetMaxLineLength();
diff --git a/source/Core/Module.cpp b/source/Core/Module.cpp
index aaae4700db350..8f80be45f1b06 100644
--- a/source/Core/Module.cpp
+++ b/source/Core/Module.cpp
@@ -129,43 +129,6 @@ Module *Module::GetAllocatedModuleAtIndex(size_t idx) {
return nullptr;
}
-#if 0
-// These functions help us to determine if modules are still loaded, yet don't require that
-// you have a command interpreter and can easily be called from an external debugger.
-namespace lldb {
-
- void
- ClearModuleInfo (void)
- {
- const bool mandatory = true;
- ModuleList::RemoveOrphanSharedModules(mandatory);
- }
-
- void
- DumpModuleInfo (void)
- {
- Mutex::Locker locker (Module::GetAllocationModuleCollectionMutex());
- ModuleCollection &modules = GetModuleCollection();
- const size_t count = modules.size();
- printf ("%s: %" PRIu64 " modules:\n", LLVM_PRETTY_FUNCTION, (uint64_t)count);
- for (size_t i = 0; i < count; ++i)
- {
-
- StreamString strm;
- Module *module = modules[i];
- const bool in_shared_module_list = ModuleList::ModuleIsInCache (module);
- module->GetDescription(&strm, eDescriptionLevelFull);
- printf ("%p: shared = %i, ref_count = %3u, module = %s\n",
- module,
- in_shared_module_list,
- (uint32_t)module->use_count(),
- strm.GetString().c_str());
- }
- }
-}
-
-#endif
-
Module::Module(const ModuleSpec &module_spec)
: m_object_offset(0), m_file_has_changed(false),
m_first_file_changed_log(false) {
diff --git a/source/Core/ModuleList.cpp b/source/Core/ModuleList.cpp
index b04299ead8042..3970052b7bf3f 100644
--- a/source/Core/ModuleList.cpp
+++ b/source/Core/ModuleList.cpp
@@ -8,8 +8,6 @@
//===----------------------------------------------------------------------===//
#include "lldb/Core/ModuleList.h"
-
-#include "lldb/Core/ArchSpec.h" // for ArchSpec
#include "lldb/Core/FileSpecList.h" // for FileSpecList
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
@@ -18,6 +16,7 @@
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h" // for SymbolContextList, SymbolCon...
#include "lldb/Symbol/VariableList.h"
+#include "lldb/Utility/ArchSpec.h" // for ArchSpec
#include "lldb/Utility/ConstString.h" // for ConstString
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Logging.h" // for GetLogIfAnyCategoriesSet
diff --git a/source/Core/PluginManager.cpp b/source/Core/PluginManager.cpp
index 9bb615b6a55e2..a49fbc3f90fef 100644
--- a/source/Core/PluginManager.cpp
+++ b/source/Core/PluginManager.cpp
@@ -275,6 +275,54 @@ PluginManager::GetABICreateCallbackForPluginName(const ConstString &name) {
return nullptr;
}
+#pragma mark Architecture
+
+struct ArchitectureInstance {
+ ConstString name;
+ std::string description;
+ PluginManager::ArchitectureCreateInstance create_callback;
+};
+
+typedef std::vector<ArchitectureInstance> ArchitectureInstances;
+
+static std::mutex g_architecture_mutex;
+
+static ArchitectureInstances &GetArchitectureInstances() {
+ static ArchitectureInstances g_instances;
+ return g_instances;
+}
+
+void PluginManager::RegisterPlugin(const ConstString &name,
+ llvm::StringRef description,
+ ArchitectureCreateInstance create_callback) {
+ std::lock_guard<std::mutex> guard(g_architecture_mutex);
+ GetArchitectureInstances().push_back({name, description, create_callback});
+}
+
+void PluginManager::UnregisterPlugin(
+ ArchitectureCreateInstance create_callback) {
+ std::lock_guard<std::mutex> guard(g_architecture_mutex);
+ auto &instances = GetArchitectureInstances();
+
+ for (auto pos = instances.begin(), end = instances.end(); pos != end; ++pos) {
+ if (pos->create_callback == create_callback) {
+ instances.erase(pos);
+ return;
+ }
+ }
+ llvm_unreachable("Plugin not found");
+}
+
+std::unique_ptr<Architecture>
+PluginManager::CreateArchitectureInstance(const ArchSpec &arch) {
+ std::lock_guard<std::mutex> guard(g_architecture_mutex);
+ for (const auto &instances : GetArchitectureInstances()) {
+ if (auto plugin_up = instances.create_callback(arch))
+ return plugin_up;
+ }
+ return nullptr;
+}
+
#pragma mark Disassembler
struct DisassemblerInstance {
diff --git a/source/Core/RegisterValue.cpp b/source/Core/RegisterValue.cpp
index 28ce67e63dc2f..f64c14019cc62 100644
--- a/source/Core/RegisterValue.cpp
+++ b/source/Core/RegisterValue.cpp
@@ -539,6 +539,9 @@ bool RegisterValue::SignExtend(uint32_t sign_bitpos) {
}
bool RegisterValue::CopyValue(const RegisterValue &rhs) {
+ if (this == &rhs)
+ return rhs.m_type == eTypeInvalid ? false : true;
+
m_type = rhs.m_type;
switch (m_type) {
case eTypeInvalid:
diff --git a/source/Core/Section.cpp b/source/Core/Section.cpp
index 3b76dd361ff3f..c9faf9f891571 100644
--- a/source/Core/Section.cpp
+++ b/source/Core/Section.cpp
@@ -65,6 +65,8 @@ static const char *GetSectionTypeAsCString(lldb::SectionType sect_type) {
return "dwarf-addr";
case eSectionTypeDWARFDebugAranges:
return "dwarf-aranges";
+ case eSectionTypeDWARFDebugCuIndex:
+ return "dwarf-cu-index";
case eSectionTypeDWARFDebugFrame:
return "dwarf-frame";
case eSectionTypeDWARFDebugInfo:
@@ -133,7 +135,7 @@ Section::Section(const ModuleSP &module_sp, ObjectFile *obj_file,
m_file_offset(file_offset), m_file_size(file_size),
m_log2align(log2align), m_children(), m_fake(false), m_encrypted(false),
m_thread_specific(false), m_readable(false), m_writable(false),
- m_executable(false), m_target_byte_size(target_byte_size) {
+ m_executable(false), m_relocated(false), m_target_byte_size(target_byte_size) {
// printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ",
// addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 "
// - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s\n",
@@ -155,7 +157,7 @@ Section::Section(const lldb::SectionSP &parent_section_sp,
m_file_offset(file_offset), m_file_size(file_size),
m_log2align(log2align), m_children(), m_fake(false), m_encrypted(false),
m_thread_specific(false), m_readable(false), m_writable(false),
- m_executable(false), m_target_byte_size(target_byte_size) {
+ m_executable(false), m_relocated(false), m_target_byte_size(target_byte_size) {
// printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ",
// addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 "
// - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s.%s\n",
@@ -390,7 +392,7 @@ lldb::offset_t Section::GetSectionData(void *dst, lldb::offset_t dst_len,
return 0;
}
-lldb::offset_t Section::GetSectionData(DataExtractor &section_data) const {
+lldb::offset_t Section::GetSectionData(DataExtractor &section_data) {
if (m_obj_file)
return m_obj_file->ReadSectionData(this, section_data);
return 0;
diff --git a/source/Core/Value.cpp b/source/Core/Value.cpp
index 63385511edb66..d415f1b09eb79 100644
--- a/source/Core/Value.cpp
+++ b/source/Core/Value.cpp
@@ -10,7 +10,6 @@
#include "lldb/Core/Value.h"
#include "lldb/Core/Address.h" // for Address
-#include "lldb/Core/ArchSpec.h" // for ArchSpec
#include "lldb/Core/Module.h"
#include "lldb/Core/State.h"
#include "lldb/Symbol/CompilerType.h"
@@ -143,6 +142,9 @@ Type *Value::GetType() {
}
size_t Value::AppendDataToHostBuffer(const Value &rhs) {
+ if (this == &rhs)
+ return 0;
+
size_t curr_size = m_data_buffer.GetByteSize();
Status error;
switch (rhs.GetValueType()) {
@@ -379,31 +381,6 @@ Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
} else
address = LLDB_INVALID_ADDRESS;
}
- // else
- // {
- // ModuleSP exe_module_sp
- // (target->GetExecutableModule());
- // if (exe_module_sp)
- // {
- // address =
- // m_value.ULongLong(LLDB_INVALID_ADDRESS);
- // if (address != LLDB_INVALID_ADDRESS)
- // {
- // if
- // (exe_module_sp->ResolveFileAddress(address,
- // file_so_addr))
- // {
- // data.SetByteOrder(target->GetArchitecture().GetByteOrder());
- // data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
- // address_type = eAddressTypeFile;
- // }
- // else
- // {
- // address = LLDB_INVALID_ADDRESS;
- // }
- // }
- // }
- // }
} else {
error.SetErrorString("can't read load address (invalid process)");
}
@@ -560,7 +537,7 @@ Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
"trying to read from host address of 0.");
return error;
}
- memcpy(dst, (uint8_t *)NULL + address, byte_size);
+ memcpy(dst, reinterpret_cast<uint8_t *>(address), byte_size);
} else if ((address_type == eAddressTypeLoad) ||
(address_type == eAddressTypeFile)) {
if (file_so_addr.IsValid()) {
diff --git a/source/Core/ValueObjectDynamicValue.cpp b/source/Core/ValueObjectDynamicValue.cpp
index bb39caa767eb9..0013d0dbf740f 100644
--- a/source/Core/ValueObjectDynamicValue.cpp
+++ b/source/Core/ValueObjectDynamicValue.cpp
@@ -8,9 +8,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Core/ValueObjectDynamicValue.h"
-
-#include "lldb/Core/ArchSpec.h" // for ArchSpec
-#include "lldb/Core/Scalar.h" // for Scalar, operator!=
+#include "lldb/Core/Scalar.h" // for Scalar, operator!=
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Symbol/CompilerType.h"
diff --git a/source/Core/ValueObjectMemory.cpp b/source/Core/ValueObjectMemory.cpp
index 713751110dcef..e26900014c9da 100644
--- a/source/Core/ValueObjectMemory.cpp
+++ b/source/Core/ValueObjectMemory.cpp
@@ -8,9 +8,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Core/ValueObjectMemory.h"
-
-#include "lldb/Core/ArchSpec.h" // for ArchSpec
-#include "lldb/Core/Scalar.h" // for Scalar, operator!=
+#include "lldb/Core/Scalar.h" // for Scalar, operator!=
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Symbol/Type.h"
diff --git a/source/Core/ValueObjectVariable.cpp b/source/Core/ValueObjectVariable.cpp
index 9b9e51a0abb87..8436ba529a54c 100644
--- a/source/Core/ValueObjectVariable.cpp
+++ b/source/Core/ValueObjectVariable.cpp
@@ -11,7 +11,6 @@
#include "lldb/Core/Address.h" // for Address
#include "lldb/Core/AddressRange.h" // for AddressRange
-#include "lldb/Core/ArchSpec.h" // for ArchSpec
#include "lldb/Core/Module.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h" // for Scalar, operator!=
@@ -156,9 +155,8 @@ bool ValueObjectVariable::UpdateValue() {
target);
}
Value old_value(m_value);
- if (expr.Evaluate(&exe_ctx, nullptr, nullptr, nullptr,
- loclist_base_load_addr, nullptr, nullptr, m_value,
- &m_error)) {
+ if (expr.Evaluate(&exe_ctx, nullptr, loclist_base_load_addr, nullptr,
+ nullptr, m_value, &m_error)) {
m_resolved_value = m_value;
m_value.SetContext(Value::eContextTypeVariable, variable);
diff --git a/source/Expression/DWARFExpression.cpp b/source/Expression/DWARFExpression.cpp
index 592a30cdd7800..14011aece7c99 100644
--- a/source/Expression/DWARFExpression.cpp
+++ b/source/Expression/DWARFExpression.cpp
@@ -24,9 +24,6 @@
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/VMRange.h"
-#include "Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h"
-#include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h"
-
#include "lldb/Host/Host.h"
#include "lldb/Utility/Endian.h"
@@ -1245,23 +1242,21 @@ bool DWARFExpression::DumpLocationForAddress(Stream *s,
}
bool DWARFExpression::Evaluate(ExecutionContextScope *exe_scope,
- ClangExpressionVariableList *expr_locals,
- ClangExpressionDeclMap *decl_map,
lldb::addr_t loclist_base_load_addr,
const Value *initial_value_ptr,
const Value *object_address_ptr, Value &result,
Status *error_ptr) const {
ExecutionContext exe_ctx(exe_scope);
- return Evaluate(&exe_ctx, expr_locals, decl_map, nullptr,
- loclist_base_load_addr, initial_value_ptr, object_address_ptr,
- result, error_ptr);
+ return Evaluate(&exe_ctx, nullptr, loclist_base_load_addr, initial_value_ptr,
+ object_address_ptr, result, error_ptr);
}
-bool DWARFExpression::Evaluate(
- ExecutionContext *exe_ctx, ClangExpressionVariableList *expr_locals,
- ClangExpressionDeclMap *decl_map, RegisterContext *reg_ctx,
- lldb::addr_t loclist_base_load_addr, const Value *initial_value_ptr,
- const Value *object_address_ptr, Value &result, Status *error_ptr) const {
+bool DWARFExpression::Evaluate(ExecutionContext *exe_ctx,
+ RegisterContext *reg_ctx,
+ lldb::addr_t loclist_base_load_addr,
+ const Value *initial_value_ptr,
+ const Value *object_address_ptr, Value &result,
+ Status *error_ptr) const {
ModuleSP module_sp = m_module_wp.lock();
if (IsLocationList()) {
@@ -1307,9 +1302,9 @@ bool DWARFExpression::Evaluate(
if (length > 0 && lo_pc <= pc && pc < hi_pc) {
return DWARFExpression::Evaluate(
- exe_ctx, expr_locals, decl_map, reg_ctx, module_sp, m_data,
- m_dwarf_cu, offset, length, m_reg_kind, initial_value_ptr,
- object_address_ptr, result, error_ptr);
+ exe_ctx, reg_ctx, module_sp, m_data, m_dwarf_cu, offset, length,
+ m_reg_kind, initial_value_ptr, object_address_ptr, result,
+ error_ptr);
}
offset += length;
}
@@ -1321,14 +1316,12 @@ bool DWARFExpression::Evaluate(
// Not a location list, just a single expression.
return DWARFExpression::Evaluate(
- exe_ctx, expr_locals, decl_map, reg_ctx, module_sp, m_data, m_dwarf_cu, 0,
- m_data.GetByteSize(), m_reg_kind, initial_value_ptr, object_address_ptr,
- result, error_ptr);
+ exe_ctx, reg_ctx, module_sp, m_data, m_dwarf_cu, 0, m_data.GetByteSize(),
+ m_reg_kind, initial_value_ptr, object_address_ptr, result, error_ptr);
}
bool DWARFExpression::Evaluate(
- ExecutionContext *exe_ctx, ClangExpressionVariableList *expr_locals,
- ClangExpressionDeclMap *decl_map, RegisterContext *reg_ctx,
+ ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
lldb::ModuleSP module_sp, const DataExtractor &opcodes,
DWARFCompileUnit *dwarf_cu, const lldb::offset_t opcodes_offset,
const lldb::offset_t opcodes_length, const lldb::RegisterKind reg_kind,
diff --git a/source/Expression/IRExecutionUnit.cpp b/source/Expression/IRExecutionUnit.cpp
index 363e6fe8678fd..be53f37e0bcc7 100644
--- a/source/Expression/IRExecutionUnit.cpp
+++ b/source/Expression/IRExecutionUnit.cpp
@@ -260,7 +260,6 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr,
llvm::Triple triple(m_module->getTargetTriple());
llvm::Reloc::Model relocModel;
- llvm::CodeModel::Model codeModel;
if (triple.isOSBinFormatELF()) {
relocModel = llvm::Reloc::Static;
@@ -268,9 +267,6 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr,
relocModel = llvm::Reloc::PIC_;
}
- // This will be small for 32-bit and large for 64-bit.
- codeModel = llvm::CodeModel::JITDefault;
-
m_module_ap->getContext().setInlineAsmDiagnosticHandler(ReportInlineAsmError,
&error);
@@ -281,7 +277,6 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr,
.setRelocationModel(relocModel)
.setMCJITMemoryManager(
std::unique_ptr<MemoryManager>(new MemoryManager(*this)))
- .setCodeModel(codeModel)
.setOptLevel(llvm::CodeGenOpt::Less);
llvm::StringRef mArch;
@@ -1114,6 +1109,7 @@ bool IRExecutionUnit::CommitOneAllocation(lldb::ProcessSP &process_sp,
case lldb::eSectionTypeDWARFDebugAbbrev:
case lldb::eSectionTypeDWARFDebugAddr:
case lldb::eSectionTypeDWARFDebugAranges:
+ case lldb::eSectionTypeDWARFDebugCuIndex:
case lldb::eSectionTypeDWARFDebugFrame:
case lldb::eSectionTypeDWARFDebugInfo:
case lldb::eSectionTypeDWARFDebugLine:
diff --git a/source/Expression/IRInterpreter.cpp b/source/Expression/IRInterpreter.cpp
index 6b5e22329af83..a809bff20039b 100644
--- a/source/Expression/IRInterpreter.cpp
+++ b/source/Expression/IRInterpreter.cpp
@@ -385,11 +385,6 @@ public:
return ret;
}
- lldb::addr_t MallocPointer() {
- return Malloc(m_target_data.getPointerSize(),
- m_target_data.getPointerPrefAlignment());
- }
-
lldb::addr_t Malloc(llvm::Type *type) {
lldb_private::Status alloc_error;
diff --git a/source/Host/CMakeLists.txt b/source/Host/CMakeLists.txt
index 1696e7eab6ea9..2b6f0e48a3f20 100644
--- a/source/Host/CMakeLists.txt
+++ b/source/Host/CMakeLists.txt
@@ -31,6 +31,7 @@ add_host_subdirectory(common
common/SoftwareBreakpoint.cpp
common/StringConvert.cpp
common/Symbols.cpp
+ common/TaskPool.cpp
common/TCPSocket.cpp
common/Terminal.cpp
common/ThreadLauncher.cpp
diff --git a/source/Host/common/Host.cpp b/source/Host/common/Host.cpp
index 8248aa3c5118a..97581185ad9e6 100644
--- a/source/Host/common/Host.cpp
+++ b/source/Host/common/Host.cpp
@@ -48,10 +48,6 @@
// C++ Includes
#include <csignal>
-// Other libraries and framework includes
-// Project includes
-
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/HostProcess.h"
diff --git a/source/Host/common/HostInfoBase.cpp b/source/Host/common/HostInfoBase.cpp
index a6c9e91a98e80..aff887f9f1d2e 100644
--- a/source/Host/common/HostInfoBase.cpp
+++ b/source/Host/common/HostInfoBase.cpp
@@ -9,11 +9,11 @@
#include "lldb/Host/Config.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/HostInfoBase.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"
@@ -103,6 +103,14 @@ const ArchSpec &HostInfoBase::GetArchitecture(ArchitectureKind arch_kind) {
: g_fields->m_host_arch_32;
}
+llvm::Optional<HostInfoBase::ArchitectureKind> HostInfoBase::ParseArchitectureKind(llvm::StringRef kind) {
+ return llvm::StringSwitch<llvm::Optional<ArchitectureKind>>(kind)
+ .Case(LLDB_ARCH_DEFAULT, eArchKindDefault)
+ .Case(LLDB_ARCH_DEFAULT_32BIT, eArchKind32)
+ .Case(LLDB_ARCH_DEFAULT_64BIT, eArchKind64)
+ .Default(llvm::None);
+}
+
bool HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec) {
file_spec.Clear();
@@ -251,6 +259,27 @@ bool HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec) {
return true;
}
+ArchSpec HostInfoBase::GetAugmentedArchSpec(llvm::StringRef triple) {
+ if (triple.empty())
+ return ArchSpec();
+ llvm::Triple normalized_triple(llvm::Triple::normalize(triple));
+ if (!ArchSpec::ContainsOnlyArch(normalized_triple))
+ return ArchSpec(triple);
+
+ if (auto kind = HostInfo::ParseArchitectureKind(triple))
+ return HostInfo::GetArchitecture(*kind);
+
+ llvm::Triple host_triple(llvm::sys::getDefaultTargetTriple());
+
+ if (normalized_triple.getVendorName().empty())
+ normalized_triple.setVendor(host_triple.getVendor());
+ if (normalized_triple.getOSName().empty())
+ normalized_triple.setOS(host_triple.getOS());
+ if (normalized_triple.getEnvironmentName().empty())
+ normalized_triple.setEnvironment(host_triple.getEnvironment());
+ return ArchSpec(normalized_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",
diff --git a/source/Host/common/MainLoop.cpp b/source/Host/common/MainLoop.cpp
index d0e0d00a31511..6cbb5a8425623 100644
--- a/source/Host/common/MainLoop.cpp
+++ b/source/Host/common/MainLoop.cpp
@@ -28,6 +28,8 @@
#include <sys/event.h>
#elif defined(LLVM_ON_WIN32)
#include <winsock2.h>
+#elif defined(__ANDROID__)
+#include <sys/syscall.h>
#else
#include <poll.h>
#endif
@@ -38,10 +40,6 @@
#define POLL poll
#endif
-#ifdef __ANDROID__
-#define FORCE_PSELECT
-#endif
-
#if SIGNAL_POLLING_UNSUPPORTED
#ifdef LLVM_ON_WIN32
typedef int sigset_t;
@@ -86,7 +84,7 @@ private:
int num_events = -1;
#else
-#ifdef FORCE_PSELECT
+#ifdef __ANDROID__
fd_set read_fd_set;
#else
std::vector<struct pollfd> read_fds;
@@ -134,7 +132,7 @@ void MainLoop::RunImpl::ProcessEvents() {
}
#else
MainLoop::RunImpl::RunImpl(MainLoop &loop) : loop(loop) {
-#ifndef FORCE_PSELECT
+#ifndef __ANDROID__
read_fds.reserve(loop.m_read_fds.size());
#endif
}
@@ -154,8 +152,14 @@ sigset_t MainLoop::RunImpl::get_sigmask() {
#endif
}
-#ifdef FORCE_PSELECT
+#ifdef __ANDROID__
Status MainLoop::RunImpl::Poll() {
+ // ppoll(2) is not supported on older all android versions. Also, older
+ // versions android (API <= 19) implemented pselect in a non-atomic way, as a
+ // combination of pthread_sigmask and select. This is not sufficient for us,
+ // as we rely on the atomicity to correctly implement signal polling, so we
+ // call the underlying syscall ourselves.
+
FD_ZERO(&read_fd_set);
int nfds = 0;
for (const auto &fd : loop.m_read_fds) {
@@ -163,8 +167,19 @@ Status MainLoop::RunImpl::Poll() {
nfds = std::max(nfds, fd.first + 1);
}
- sigset_t sigmask = get_sigmask();
- if (pselect(nfds, &read_fd_set, nullptr, nullptr, nullptr, &sigmask) == -1 &&
+ union {
+ sigset_t set;
+ uint64_t pad;
+ } kernel_sigset;
+ memset(&kernel_sigset, 0, sizeof(kernel_sigset));
+ kernel_sigset.set = get_sigmask();
+
+ struct {
+ void *sigset_ptr;
+ size_t sigset_len;
+ } extra_data = {&kernel_sigset, sizeof(kernel_sigset)};
+ if (syscall(__NR_pselect6, nfds, &read_fd_set, nullptr, nullptr, nullptr,
+ &extra_data) == -1 &&
errno != EINTR)
return Status(errno, eErrorTypePOSIX);
@@ -193,7 +208,7 @@ Status MainLoop::RunImpl::Poll() {
#endif
void MainLoop::RunImpl::ProcessEvents() {
-#ifdef FORCE_PSELECT
+#ifdef __ANDROID__
// 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
@@ -206,7 +221,7 @@ void MainLoop::RunImpl::ProcessEvents() {
for (const auto &handle : fds) {
#else
for (const auto &fd : read_fds) {
- if ((fd.revents & POLLIN) == 0)
+ if ((fd.revents & (POLLIN | POLLHUP)) == 0)
continue;
IOObject::WaitableHandle handle = fd.fd;
#endif
diff --git a/source/Host/common/NativeProcessProtocol.cpp b/source/Host/common/NativeProcessProtocol.cpp
index b5b6e9d8b9239..1fcb11b8b6f5d 100644
--- a/source/Host/common/NativeProcessProtocol.cpp
+++ b/source/Host/common/NativeProcessProtocol.cpp
@@ -8,8 +8,6 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/common/NativeProcessProtocol.h"
-
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
@@ -90,23 +88,23 @@ bool NativeProcessProtocol::SetExitStatus(WaitStatus status,
return true;
}
-NativeThreadProtocolSP NativeProcessProtocol::GetThreadAtIndex(uint32_t idx) {
+NativeThreadProtocol *NativeProcessProtocol::GetThreadAtIndex(uint32_t idx) {
std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
if (idx < m_threads.size())
- return m_threads[idx];
- return NativeThreadProtocolSP();
+ return m_threads[idx].get();
+ return nullptr;
}
-NativeThreadProtocolSP
+NativeThreadProtocol *
NativeProcessProtocol::GetThreadByIDUnlocked(lldb::tid_t tid) {
- for (auto thread_sp : m_threads) {
- if (thread_sp->GetID() == tid)
- return thread_sp;
+ for (const auto &thread : m_threads) {
+ if (thread->GetID() == tid)
+ return thread.get();
}
- return NativeThreadProtocolSP();
+ return nullptr;
}
-NativeThreadProtocolSP NativeProcessProtocol::GetThreadByID(lldb::tid_t tid) {
+NativeThreadProtocol *NativeProcessProtocol::GetThreadByID(lldb::tid_t tid) {
std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
return GetThreadByIDUnlocked(tid);
}
@@ -116,14 +114,6 @@ bool NativeProcessProtocol::IsAlive() const {
m_state != eStateInvalid && m_state != eStateUnloaded;
}
-bool NativeProcessProtocol::GetByteOrder(lldb::ByteOrder &byte_order) const {
- ArchSpec process_arch;
- if (!GetArchitecture(process_arch))
- return false;
- byte_order = process_arch.GetByteOrder();
- return true;
-}
-
const NativeWatchpointList::WatchpointMap &
NativeProcessProtocol::GetWatchpointMap() const {
return m_watchpoint_list.GetWatchpointMap();
@@ -134,27 +124,16 @@ NativeProcessProtocol::GetHardwareDebugSupportInfo() const {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
// get any thread
- NativeThreadProtocolSP thread_sp(
+ NativeThreadProtocol *thread(
const_cast<NativeProcessProtocol *>(this)->GetThreadAtIndex(0));
- if (!thread_sp) {
- if (log)
- log->Warning("NativeProcessProtocol::%s (): failed to find a thread to "
- "grab a NativeRegisterContext!",
- __FUNCTION__);
+ if (!thread) {
+ LLDB_LOG(log, "failed to find a thread to grab a NativeRegisterContext!");
return llvm::None;
}
- NativeRegisterContextSP reg_ctx_sp(thread_sp->GetRegisterContext());
- if (!reg_ctx_sp) {
- if (log)
- log->Warning("NativeProcessProtocol::%s (): failed to get a "
- "RegisterContextNativeProcess from the first thread!",
- __FUNCTION__);
- return llvm::None;
- }
-
- return std::make_pair(reg_ctx_sp->NumSupportedHardwareBreakpoints(),
- reg_ctx_sp->NumSupportedHardwareWatchpoints());
+ NativeRegisterContext &reg_ctx = thread->GetRegisterContext();
+ return std::make_pair(reg_ctx.NumSupportedHardwareBreakpoints(),
+ reg_ctx.NumSupportedHardwareWatchpoints());
}
Status NativeProcessProtocol::SetWatchpoint(lldb::addr_t addr, size_t size,
@@ -175,7 +154,7 @@ Status NativeProcessProtocol::SetWatchpoint(lldb::addr_t addr, size_t size,
// 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<NativeThreadProtocolSP> watchpoint_established_threads;
+ 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,
@@ -184,40 +163,33 @@ Status NativeProcessProtocol::SetWatchpoint(lldb::addr_t addr, size_t size,
// 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 (auto thread_sp : m_threads) {
- assert(thread_sp && "thread list should not have a NULL thread!");
- if (!thread_sp)
- continue;
+ for (const auto &thread : m_threads) {
+ assert(thread && "thread list should not have a NULL thread!");
Status thread_error =
- thread_sp->SetWatchpoint(addr, size, watch_flags, hardware);
+ 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.
- thread_error = thread_sp->SetWatchpoint(addr, size, watch_flags, false);
- if (thread_error.Success()) {
- if (log)
- log->Warning(
- "hardware watchpoint requested but software watchpoint set");
- }
+ thread_error = thread->SetWatchpoint(addr, size, watch_flags, false);
+ if (thread_error.Success())
+ LLDB_LOG(log,
+ "hardware watchpoint requested but software watchpoint set");
}
if (thread_error.Success()) {
// Remember that we set this watchpoint successfully in
// case we need to clear it later.
- watchpoint_established_threads.push_back(thread_sp);
+ 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.
for (auto unwatch_thread_sp : watchpoint_established_threads) {
Status remove_error = unwatch_thread_sp->RemoveWatchpoint(addr);
- if (remove_error.Fail() && log) {
- log->Warning("NativeProcessProtocol::%s (): RemoveWatchpoint failed "
- "for pid=%" PRIu64 ", tid=%" PRIu64 ": %s",
- __FUNCTION__, GetID(), unwatch_thread_sp->GetID(),
- remove_error.AsCString());
- }
+ if (remove_error.Fail())
+ LLDB_LOG(log, "RemoveWatchpoint failed for pid={0}, tid={1}: {2}",
+ GetID(), unwatch_thread_sp->GetID(), remove_error);
}
return thread_error;
@@ -233,12 +205,10 @@ Status NativeProcessProtocol::RemoveWatchpoint(lldb::addr_t addr) {
Status overall_error;
std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
- for (auto thread_sp : m_threads) {
- assert(thread_sp && "thread list should not have a NULL thread!");
- if (!thread_sp)
- continue;
+ for (const auto &thread : m_threads) {
+ assert(thread && "thread list should not have a NULL thread!");
- const Status thread_error = thread_sp->RemoveWatchpoint(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
@@ -277,20 +247,18 @@ Status NativeProcessProtocol::SetHardwareBreakpoint(lldb::addr_t addr,
// set this hardware breakpoint. If any of the current process threads fails
// to set this hardware breakpoint then roll back and remove this breakpoint
// for all the threads that had already set it successfully.
- std::vector<NativeThreadProtocolSP> breakpoint_established_threads;
+ std::vector<NativeThreadProtocol *> breakpoint_established_threads;
// Request to set a hardware breakpoint for each of current process threads.
std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
- for (auto thread_sp : m_threads) {
- assert(thread_sp && "thread list should not have a NULL thread!");
- if (!thread_sp)
- continue;
+ for (const auto &thread : m_threads) {
+ assert(thread && "thread list should not have a NULL thread!");
- Status thread_error = thread_sp->SetHardwareBreakpoint(addr, size);
+ 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.
- breakpoint_established_threads.push_back(thread_sp);
+ 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
@@ -298,12 +266,10 @@ Status NativeProcessProtocol::SetHardwareBreakpoint(lldb::addr_t addr,
for (auto rollback_thread_sp : breakpoint_established_threads) {
Status remove_error =
rollback_thread_sp->RemoveHardwareBreakpoint(addr);
- if (remove_error.Fail() && log) {
- log->Warning("NativeProcessProtocol::%s (): RemoveHardwareBreakpoint"
- " failed for pid=%" PRIu64 ", tid=%" PRIu64 ": %s",
- __FUNCTION__, GetID(), rollback_thread_sp->GetID(),
- remove_error.AsCString());
- }
+ if (remove_error.Fail())
+ LLDB_LOG(log,
+ "RemoveHardwareBreakpoint failed for pid={0}, tid={1}: {2}",
+ GetID(), rollback_thread_sp->GetID(), remove_error);
}
return thread_error;
@@ -324,12 +290,9 @@ Status NativeProcessProtocol::RemoveHardwareBreakpoint(lldb::addr_t addr) {
Status error;
std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
- for (auto thread_sp : m_threads) {
- assert(thread_sp && "thread list should not have a NULL thread!");
- if (!thread_sp)
- continue;
-
- error = thread_sp->RemoveHardwareBreakpoint(addr);
+ for (const auto &thread : m_threads) {
+ assert(thread && "thread list should not have a NULL thread!");
+ error = thread->RemoveHardwareBreakpoint(addr);
}
// Also remove from hardware breakpoint map of current process.
diff --git a/source/Host/common/NativeRegisterContext.cpp b/source/Host/common/NativeRegisterContext.cpp
index 629b0247422d2..60eaebdc94cd2 100644
--- a/source/Host/common/NativeRegisterContext.cpp
+++ b/source/Host/common/NativeRegisterContext.cpp
@@ -19,9 +19,8 @@
using namespace lldb;
using namespace lldb_private;
-NativeRegisterContext::NativeRegisterContext(NativeThreadProtocol &thread,
- uint32_t concrete_frame_idx)
- : m_thread(thread), m_concrete_frame_idx(concrete_frame_idx) {}
+NativeRegisterContext::NativeRegisterContext(NativeThreadProtocol &thread)
+ : m_thread(thread) {}
//----------------------------------------------------------------------
// Destructor
@@ -368,13 +367,8 @@ Status NativeRegisterContext::ReadRegisterValueFromMemory(
// 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.
- lldb::ByteOrder byte_order;
- if (process.GetByteOrder(byte_order)) {
- error.SetErrorString("NativeProcessProtocol::GetByteOrder () failed");
- return error;
- }
-
- reg_value.SetFromMemoryData(reg_info, src, src_len, byte_order, error);
+ reg_value.SetFromMemoryData(reg_info, src, src_len, process.GetByteOrder(),
+ error);
return error;
}
@@ -393,12 +387,8 @@ Status NativeRegisterContext::WriteRegisterValueToMemory(
// order of the memory data doesn't match the process. For now we are
// assuming
// they are the same.
- lldb::ByteOrder byte_order;
- if (!process.GetByteOrder(byte_order))
- return Status("NativeProcessProtocol::GetByteOrder () failed");
-
- const size_t bytes_copied =
- reg_value.GetAsMemoryData(reg_info, dst, dst_len, byte_order, error);
+ const size_t bytes_copied = reg_value.GetAsMemoryData(
+ reg_info, dst, dst_len, process.GetByteOrder(), error);
if (error.Success()) {
if (bytes_copied == 0) {
diff --git a/source/Host/common/NativeThreadProtocol.cpp b/source/Host/common/NativeThreadProtocol.cpp
index 54ac96dd3c6fd..3f3915e006da6 100644
--- a/source/Host/common/NativeThreadProtocol.cpp
+++ b/source/Host/common/NativeThreadProtocol.cpp
@@ -22,43 +22,33 @@ NativeThreadProtocol::NativeThreadProtocol(NativeProcessProtocol &process,
Status NativeThreadProtocol::ReadRegister(uint32_t reg,
RegisterValue &reg_value) {
- NativeRegisterContextSP register_context_sp = GetRegisterContext();
- if (!register_context_sp)
- return Status("no register context");
+ NativeRegisterContext &register_context = GetRegisterContext();
const RegisterInfo *const reg_info =
- register_context_sp->GetRegisterInfoAtIndex(reg);
+ register_context.GetRegisterInfoAtIndex(reg);
if (!reg_info)
return Status("no register info for reg num %" PRIu32, reg);
- return register_context_sp->ReadRegister(reg_info, reg_value);
+ return register_context.ReadRegister(reg_info, reg_value);
;
}
Status NativeThreadProtocol::WriteRegister(uint32_t reg,
const RegisterValue &reg_value) {
- NativeRegisterContextSP register_context_sp = GetRegisterContext();
- if (!register_context_sp)
- return Status("no register context");
+ NativeRegisterContext& register_context = GetRegisterContext();
const RegisterInfo *const reg_info =
- register_context_sp->GetRegisterInfoAtIndex(reg);
+ register_context.GetRegisterInfoAtIndex(reg);
if (!reg_info)
return Status("no register info for reg num %" PRIu32, reg);
- return register_context_sp->WriteRegister(reg_info, reg_value);
+ return register_context.WriteRegister(reg_info, reg_value);
}
Status NativeThreadProtocol::SaveAllRegisters(lldb::DataBufferSP &data_sp) {
- NativeRegisterContextSP register_context_sp = GetRegisterContext();
- if (!register_context_sp)
- return Status("no register context");
- return register_context_sp->WriteAllRegisterValues(data_sp);
+ return GetRegisterContext().WriteAllRegisterValues(data_sp);
}
Status NativeThreadProtocol::RestoreAllRegisters(lldb::DataBufferSP &data_sp) {
- NativeRegisterContextSP register_context_sp = GetRegisterContext();
- if (!register_context_sp)
- return Status("no register context");
- return register_context_sp->ReadAllRegisterValues(data_sp);
+ return GetRegisterContext().ReadAllRegisterValues(data_sp);
}
diff --git a/source/Host/common/PseudoTerminal.cpp b/source/Host/common/PseudoTerminal.cpp
index 58c32e4a1c4ba..9657cb6523dce 100644
--- a/source/Host/common/PseudoTerminal.cpp
+++ b/source/Host/common/PseudoTerminal.cpp
@@ -24,7 +24,7 @@
int posix_openpt(int flags);
#endif
-using namespace lldb_utility;
+using namespace lldb_private;
//----------------------------------------------------------------------
// PseudoTerminal constructor
diff --git a/source/Host/common/Socket.cpp b/source/Host/common/Socket.cpp
index 5490e9b30bdaf..4c23e4eb560c4 100644
--- a/source/Host/common/Socket.cpp
+++ b/source/Host/common/Socket.cpp
@@ -450,7 +450,7 @@ NativeSocket Socket::AcceptSocket(NativeSocket sockfd, struct sockaddr *addr,
close(fd);
}
return fd;
-#elif defined(SOCK_CLOEXEC)
+#elif defined(SOCK_CLOEXEC) && defined(HAVE_ACCEPT4)
int flags = 0;
if (!child_processes_inherit) {
flags |= SOCK_CLOEXEC;
diff --git a/source/Host/common/Symbols.cpp b/source/Host/common/Symbols.cpp
index e7bdf084d385a..3f70fdc4bf951 100644
--- a/source/Host/common/Symbols.cpp
+++ b/source/Host/common/Symbols.cpp
@@ -8,11 +8,11 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/Symbols.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Log.h"
@@ -109,25 +109,25 @@ static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
// Remove the binary name from the FileSpec
parent_dirs.RemoveLastPathComponent();
- // Add a ".dSYM" name to each directory component of the path, stripping
- // off components. e.g. we may have a binary like
+ // 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.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.
+ // 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 bundle's
- // top level directory?
+ // Does this part of the path have a "." character - could it be a
+ // bundle's top level directory?
const char *fn = parent_dirs.GetFilename().AsCString();
if (fn == nullptr)
- break;
- if (::strchr (fn, '.') != nullptr) {
+ break;
+ if (::strchr(fn, '.') != nullptr) {
dsym_fspec = parent_dirs;
dsym_fspec.RemoveLastPathComponent();
@@ -140,16 +140,17 @@ static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
dsym_fspec.AppendPathComponent("Contents");
dsym_fspec.AppendPathComponent("Resources");
dsym_fspec.AppendPathComponent("DWARF");
- dsym_fspec.AppendPathComponent(exec_fspec->GetFilename().AsCString());
+ dsym_fspec.AppendPathComponent(
+ exec_fspec->GetFilename().AsCString());
if (dsym_fspec.Exists() &&
- FileAtPathContainsArchAndUUID(
- dsym_fspec, module_spec.GetArchitecturePtr(),
- module_spec.GetUUIDPtr())) {
- if (log) {
- log->Printf("dSYM with matching UUID & arch found at %s",
- dsym_fspec.GetPath().c_str());
- }
- return true;
+ FileAtPathContainsArchAndUUID(
+ dsym_fspec, module_spec.GetArchitecturePtr(),
+ module_spec.GetUUIDPtr())) {
+ if (log) {
+ log->Printf("dSYM with matching UUID & arch found at %s",
+ dsym_fspec.GetPath().c_str());
+ }
+ return true;
}
}
parent_dirs.RemoveLastPathComponent();
@@ -231,7 +232,8 @@ FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) {
#ifndef LLVM_ON_WIN32
#if defined(__NetBSD__)
// Add /usr/libdata/debug directory.
- debug_file_search_paths.AppendIfUnique(FileSpec("/usr/libdata/debug", true));
+ debug_file_search_paths.AppendIfUnique(
+ FileSpec("/usr/libdata/debug", true));
#else
// Add /usr/lib/debug directory.
debug_file_search_paths.AppendIfUnique(FileSpec("/usr/lib/debug", true));
@@ -285,7 +287,11 @@ FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) {
if (num_specs == 1) {
ModuleSpec mspec;
if (specs.GetModuleSpecAtIndex(0, mspec)) {
- if (mspec.GetUUID() == module_uuid)
+ // 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/Utility/TaskPool.cpp b/source/Host/common/TaskPool.cpp
index d33f23cd861c6..156a079429985 100644
--- a/source/Utility/TaskPool.cpp
+++ b/source/Host/common/TaskPool.cpp
@@ -7,12 +7,15 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Utility/TaskPool.h"
+#include "lldb/Host/TaskPool.h"
+#include "lldb/Host/ThreadLauncher.h"
#include <cstdint> // for uint32_t
#include <queue> // for queue
#include <thread> // for thread
+namespace lldb_private {
+
namespace {
class TaskPoolImpl {
public:
@@ -23,6 +26,8 @@ public:
private:
TaskPoolImpl();
+ static lldb::thread_result_t WorkerPtr(void *pool);
+
static void Worker(TaskPoolImpl *pool);
std::queue<std::function<void()>> m_tasks;
@@ -43,21 +48,36 @@ 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.
+ static const unsigned g_hardware_concurrency =
+ std::max(1u, std::thread::hardware_concurrency());
+ return g_hardware_concurrency;
+}
+
void TaskPoolImpl::AddTask(std::function<void()> &&task_fn) {
- static const uint32_t max_threads = std::thread::hardware_concurrency();
+ const size_t min_stack_size = 8 * 1024 * 1024;
std::unique_lock<std::mutex> lock(m_tasks_mutex);
m_tasks.emplace(std::move(task_fn));
- if (m_thread_count < max_threads) {
+ 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).
- std::thread(Worker, this).detach();
+ lldb_private::ThreadLauncher::LaunchThread("task-pool.worker", WorkerPtr,
+ this, nullptr, min_stack_size)
+ .Release();
}
}
+lldb::thread_result_t TaskPoolImpl::WorkerPtr(void *pool) {
+ Worker((TaskPoolImpl *)pool);
+ return 0;
+}
+
void TaskPoolImpl::Worker(TaskPoolImpl *pool) {
while (true) {
std::unique_lock<std::mutex> lock(pool->m_tasks_mutex);
@@ -66,7 +86,7 @@ void TaskPoolImpl::Worker(TaskPoolImpl *pool) {
break;
}
- std::function<void()> f = pool->m_tasks.front();
+ std::function<void()> f = std::move(pool->m_tasks.front());
pool->m_tasks.pop();
lock.unlock();
@@ -76,10 +96,9 @@ void TaskPoolImpl::Worker(TaskPoolImpl *pool) {
void TaskMapOverInt(size_t begin, size_t end,
const llvm::function_ref<void(size_t)> &func) {
+ const size_t num_workers = std::min<size_t>(end, GetHardwareConcurrencyHint());
std::atomic<size_t> idx{begin};
- size_t num_workers =
- std::min<size_t>(end, std::thread::hardware_concurrency());
-
+
auto wrapper = [&idx, end, &func]() {
while (true) {
size_t i = idx.fetch_add(1);
@@ -96,3 +115,6 @@ void TaskMapOverInt(size_t begin, size_t end,
for (size_t i = 0; i < num_workers; i++)
futures[i].wait();
}
+
+} // namespace lldb_private
+
diff --git a/source/Host/common/XML.cpp b/source/Host/common/XML.cpp
index c637d938dffa6..c3169bd6e08d1 100644
--- a/source/Host/common/XML.cpp
+++ b/source/Host/common/XML.cpp
@@ -339,7 +339,7 @@ XMLNode XMLNode::FindFirstChildElementWithName(const char *name) const {
#if defined(LIBXML2_DEFINED)
ForEachChildElementWithName(
- name, [&result_node, name](const XMLNode &node) -> bool {
+ name, [&result_node](const XMLNode &node) -> bool {
result_node = node;
// Stop iterating, we found the node we wanted
return false;
diff --git a/source/Host/freebsd/Host.cpp b/source/Host/freebsd/Host.cpp
index 037dfc7f5e033..124a8a760133a 100644
--- a/source/Host/freebsd/Host.cpp
+++ b/source/Host/freebsd/Host.cpp
@@ -73,7 +73,14 @@ GetFreeBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
if (!cstr)
return false;
- process_info.GetExecutableFile().SetFile(cstr, false);
+ // Get pathname for pid. If that fails fall back to argv[0].
+ char pathname[MAXPATHLEN];
+ 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);
+ else
+ process_info.GetExecutableFile().SetFile(cstr, false);
if (!(match_info_ptr == NULL ||
NameMatches(process_info.GetExecutableFile().GetFilename().GetCString(),
diff --git a/source/Host/macosx/Host.mm b/source/Host/macosx/Host.mm
index 75624ef21f432..7359815fdf704 100644
--- a/source/Host/macosx/Host.mm
+++ b/source/Host/macosx/Host.mm
@@ -20,7 +20,7 @@
#define __XPC_PRIVATE_H__
#include <xpc/xpc.h>
-#define LaunchUsingXPCRightName "com.apple.dt.Xcode.RootDebuggingXPCService"
+#define LaunchUsingXPCRightName "com.apple.lldb.RootDebuggingXPCService"
// These XPC messaging keys are used for communication between Host.mm and the
// XPC service.
@@ -54,7 +54,6 @@
#include <sys/types.h>
#include <unistd.h>
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Communication.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
@@ -63,6 +62,7 @@
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
diff --git a/source/Host/macosx/Symbols.cpp b/source/Host/macosx/Symbols.cpp
index 9d1e8fe96ae98..98c110b1bed67 100644
--- a/source/Host/macosx/Symbols.cpp
+++ b/source/Host/macosx/Symbols.cpp
@@ -23,11 +23,11 @@
#include "Host/macosx/cfcpp/CFCData.h"
#include "Host/macosx/cfcpp/CFCReleaser.h"
#include "Host/macosx/cfcpp/CFCString.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/DataExtractor.h"
@@ -361,6 +361,7 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
// If we see DBGVersion with a value of 2 or higher, this is a new style
// DBGSourcePathRemapping dictionary
bool new_style_source_remapping_dictionary = false;
+ bool do_truncate_remapping_names = false;
std::string original_DBGSourcePath_value = DBGSourcePath;
cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
CFSTR("DBGVersion"));
@@ -372,6 +373,9 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
if (version_number > 1) {
new_style_source_remapping_dictionary = true;
}
+ if (version_number == 2) {
+ do_truncate_remapping_names = true;
+ }
}
}
@@ -409,9 +413,24 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
FileSpec resolved_source_path(DBGSourcePath.c_str(), true);
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.
module_spec.GetSourceMappingList().Append(
ConstString(DBGBuildSourcePath.c_str()),
ConstString(DBGSourcePath.c_str()), true);
+ if (do_truncate_remapping_names) {
+ FileSpec build_path(DBGBuildSourcePath.c_str(), false);
+ FileSpec source_path(DBGSourcePath.c_str(), false);
+ build_path.RemoveLastPathComponent();
+ build_path.RemoveLastPathComponent();
+ source_path.RemoveLastPathComponent();
+ source_path.RemoveLastPathComponent();
+ module_spec.GetSourceMappingList().Append(
+ ConstString(build_path.GetPath().c_str()),
+ ConstString(source_path.GetPath().c_str()), true);
+ }
}
}
if (keys)
diff --git a/source/Host/posix/HostThreadPosix.cpp b/source/Host/posix/HostThreadPosix.cpp
index 0f4434d25e2eb..71abb76dc600b 100644
--- a/source/Host/posix/HostThreadPosix.cpp
+++ b/source/Host/posix/HostThreadPosix.cpp
@@ -43,7 +43,7 @@ Status HostThreadPosix::Cancel() {
if (IsJoinable()) {
#ifndef __ANDROID__
#ifndef __FreeBSD__
- assert(false && "someone is calling HostThread::Cancel()");
+ llvm_unreachable("someone is calling HostThread::Cancel()");
#endif
int err = ::pthread_cancel(m_thread);
error.SetError(err, eErrorTypePOSIX);
diff --git a/source/Host/posix/ProcessLauncherPosixFork.cpp b/source/Host/posix/ProcessLauncherPosixFork.cpp
index 66c0229e0dab4..ac1d9011c2b78 100644
--- a/source/Host/posix/ProcessLauncherPosixFork.cpp
+++ b/source/Host/posix/ProcessLauncherPosixFork.cpp
@@ -29,7 +29,7 @@
#define PT_TRACE_ME PTRACE_TRACEME
#endif
-#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
+#if defined(__ANDROID_API__) && __ANDROID_API__ < 15
#include <linux/personality.h>
#elif defined(__linux__)
#include <sys/personality.h>
@@ -95,10 +95,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) {
- // First, make sure we disable all logging. If we are logging to stdout, our
- // logs can be mistaken for inferior output.
- Log::DisableAllLogChannels();
-
// Do not inherit setgid powers.
if (setgid(getgid()) != 0)
ExitWithError(error_fd, "setgid");
diff --git a/source/Initialization/SystemInitializerCommon.cpp b/source/Initialization/SystemInitializerCommon.cpp
index e76ba4122bb6f..a8fc46c119d8b 100644
--- a/source/Initialization/SystemInitializerCommon.cpp
+++ b/source/Initialization/SystemInitializerCommon.cpp
@@ -69,8 +69,10 @@ void SystemInitializerCommon::Initialize() {
}
#endif
+#if not defined(__APPLE__)
llvm::EnablePrettyStackTrace();
- InitializeLog();
+#endif
+ Log::Initialize();
HostInfo::Initialize();
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
diff --git a/source/Interpreter/Args.cpp b/source/Interpreter/Args.cpp
index a23ba3094b22b..07e5191f898aa 100644
--- a/source/Interpreter/Args.cpp
+++ b/source/Interpreter/Args.cpp
@@ -185,6 +185,11 @@ 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();
diff --git a/source/Interpreter/CommandInterpreter.cpp b/source/Interpreter/CommandInterpreter.cpp
index 986be7ffbf89c..8dc5637b6e4eb 100644
--- a/source/Interpreter/CommandInterpreter.cpp
+++ b/source/Interpreter/CommandInterpreter.cpp
@@ -546,7 +546,7 @@ void CommandInterpreter::LoadCommandDictionary() {
char buffer[1024];
int num_printed =
snprintf(buffer, 1024, "%s %s", break_regexes[i][1], "-o");
- assert(num_printed < 1024);
+ lldbassert(num_printed < 1024);
UNUSED_IF_ASSERT_DISABLED(num_printed);
success =
tbreak_regex_cmd_ap->AddRegexCommand(break_regexes[i][0], buffer);
@@ -891,8 +891,8 @@ bool CommandInterpreter::AddCommand(llvm::StringRef name,
const lldb::CommandObjectSP &cmd_sp,
bool can_replace) {
if (cmd_sp.get())
- assert((this == &cmd_sp->GetCommandInterpreter()) &&
- "tried to add a CommandObject from a different interpreter");
+ lldbassert((this == &cmd_sp->GetCommandInterpreter()) &&
+ "tried to add a CommandObject from a different interpreter");
if (name.empty())
return false;
@@ -913,8 +913,8 @@ bool CommandInterpreter::AddUserCommand(llvm::StringRef name,
const lldb::CommandObjectSP &cmd_sp,
bool can_replace) {
if (cmd_sp.get())
- assert((this == &cmd_sp->GetCommandInterpreter()) &&
- "tried to add a CommandObject from a different interpreter");
+ lldbassert((this == &cmd_sp->GetCommandInterpreter()) &&
+ "tried to add a CommandObject from a different interpreter");
if (!name.empty()) {
// do not allow replacement of internal commands
@@ -1062,8 +1062,8 @@ CommandInterpreter::AddAlias(llvm::StringRef alias_name,
lldb::CommandObjectSP &command_obj_sp,
llvm::StringRef args_string) {
if (command_obj_sp.get())
- assert((this == &command_obj_sp->GetCommandInterpreter()) &&
- "tried to add a CommandObject from a different interpreter");
+ lldbassert((this == &command_obj_sp->GetCommandInterpreter()) &&
+ "tried to add a CommandObject from a different interpreter");
std::unique_ptr<CommandAlias> command_alias_up(
new CommandAlias(*this, command_obj_sp, args_string, alias_name));
@@ -1541,6 +1541,12 @@ bool CommandInterpreter::HandleCommand(const char *command_line,
if (!no_context_switching)
UpdateExecutionContext(override_context);
+ if (WasInterrupted()) {
+ result.AppendError("interrupted");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
bool add_to_history;
if (lazy_add_to_history == eLazyBoolCalculate)
add_to_history = (m_command_source_depth == 0);
@@ -1839,7 +1845,7 @@ int CommandInterpreter::HandleCompletion(
matches.Clear();
// Only max_return_elements == -1 is supported at present:
- assert(max_return_elements == -1);
+ lldbassert(max_return_elements == -1);
bool word_complete;
num_command_matches = HandleCompletionMatches(
parsed_line, cursor_index, cursor_char_position, match_start_point,
@@ -2210,7 +2216,7 @@ void CommandInterpreter::HandleCommands(const StringList &commands,
m_debugger.SetAsyncExecution(false);
}
- for (size_t idx = 0; idx < num_lines; idx++) {
+ for (size_t idx = 0; idx < num_lines && !WasInterrupted(); idx++) {
const char *cmd = commands.GetStringAtIndex(idx);
if (cmd[0] == '\0')
continue;
@@ -2569,7 +2575,7 @@ void CommandInterpreter::OutputHelpText(Stream &strm, llvm::StringRef word_text,
while (!text.empty()) {
if (text.front() == '\n' ||
- (text.front() == ' ' && nextWordLength(text.ltrim(' ')) < chars_left)) {
+ (text.front() == ' ' && nextWordLength(text.ltrim(' ')) > chars_left)) {
strm.EOL();
strm.Indent();
chars_left = max_columns - indent_size;
@@ -2677,8 +2683,67 @@ size_t CommandInterpreter::GetProcessOutput() {
return total_bytes;
}
+void CommandInterpreter::StartHandlingCommand() {
+ auto idle_state = CommandHandlingState::eIdle;
+ if (m_command_state.compare_exchange_strong(
+ idle_state, CommandHandlingState::eInProgress))
+ lldbassert(m_iohandler_nesting_level == 0);
+ else
+ lldbassert(m_iohandler_nesting_level > 0);
+ ++m_iohandler_nesting_level;
+}
+
+void CommandInterpreter::FinishHandlingCommand() {
+ lldbassert(m_iohandler_nesting_level > 0);
+ if (--m_iohandler_nesting_level == 0) {
+ auto prev_state = m_command_state.exchange(CommandHandlingState::eIdle);
+ lldbassert(prev_state != CommandHandlingState::eIdle);
+ }
+}
+
+bool CommandInterpreter::InterruptCommand() {
+ auto in_progress = CommandHandlingState::eInProgress;
+ return m_command_state.compare_exchange_strong(
+ in_progress, CommandHandlingState::eInterrupted);
+}
+
+bool CommandInterpreter::WasInterrupted() const {
+ bool was_interrupted =
+ (m_command_state == CommandHandlingState::eInterrupted);
+ lldbassert(!was_interrupted || m_iohandler_nesting_level > 0);
+ return was_interrupted;
+}
+
+void CommandInterpreter::PrintCommandOutput(Stream &stream,
+ llvm::StringRef str) {
+ // Split the output into lines and poll for interrupt requests
+ const char *data = str.data();
+ size_t size = str.size();
+ while (size > 0 && !WasInterrupted()) {
+ size_t chunk_size = 0;
+ for (; chunk_size < size; ++chunk_size) {
+ lldbassert(data[chunk_size] != '\0');
+ if (data[chunk_size] == '\n') {
+ ++chunk_size;
+ break;
+ }
+ }
+ chunk_size = stream.Write(data, chunk_size);
+ lldbassert(size >= chunk_size);
+ data += chunk_size;
+ size -= chunk_size;
+ }
+ if (size > 0) {
+ stream.Printf("\n... Interrupted.\n");
+ }
+}
+
void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler,
std::string &line) {
+ // If we were interrupted, bail out...
+ if (WasInterrupted())
+ return;
+
const bool is_interactive = io_handler.GetIsInteractive();
if (is_interactive == false) {
// When we are not interactive, don't execute blank lines. This will happen
@@ -2700,6 +2765,8 @@ void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler,
line.c_str());
}
+ StartHandlingCommand();
+
lldb_private::CommandReturnObject result;
HandleCommand(line.c_str(), eLazyBoolCalculate, result);
@@ -2710,18 +2777,18 @@ void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler,
if (!result.GetImmediateOutputStream()) {
llvm::StringRef output = result.GetOutputData();
- if (!output.empty())
- io_handler.GetOutputStreamFile()->PutCString(output);
+ PrintCommandOutput(*io_handler.GetOutputStreamFile(), output);
}
// Now emit the command error text from the command we just executed
if (!result.GetImmediateErrorStream()) {
llvm::StringRef error = result.GetErrorData();
- if (!error.empty())
- io_handler.GetErrorStreamFile()->PutCString(error);
+ PrintCommandOutput(*io_handler.GetErrorStreamFile(), error);
}
}
+ FinishHandlingCommand();
+
switch (result.GetStatus()) {
case eReturnStatusInvalid:
case eReturnStatusSuccessFinishNoResult:
@@ -2777,6 +2844,9 @@ bool CommandInterpreter::IOHandlerInterrupt(IOHandler &io_handler) {
ExecutionContext exe_ctx(GetExecutionContext());
Process *process = exe_ctx.GetProcessPtr();
+ if (InterruptCommand())
+ return true;
+
if (process) {
StateType state = process->GetState();
if (StateIsRunningState(state)) {
@@ -2998,7 +3068,7 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line,
result.AppendRawError(error_msg.GetString());
} else {
// We didn't have only one match, otherwise we wouldn't get here.
- assert(num_matches == 0);
+ lldbassert(num_matches == 0);
result.AppendErrorWithFormat("'%s' is not a valid command.\n",
next_word.c_str());
}
diff --git a/source/Interpreter/CommandObject.cpp b/source/Interpreter/CommandObject.cpp
index f9a5b10bb4b8f..98a6a941864e7 100644
--- a/source/Interpreter/CommandObject.cpp
+++ b/source/Interpreter/CommandObject.cpp
@@ -17,8 +17,8 @@
#include <stdlib.h>
#include "lldb/Core/Address.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Interpreter/Options.h"
+#include "lldb/Utility/ArchSpec.h"
// These are for the Sourcename completers.
// FIXME: Make a separate file for the completers.
@@ -57,7 +57,7 @@ llvm::StringRef CommandObject::GetHelp() { return m_cmd_help_short; }
llvm::StringRef CommandObject::GetHelpLong() { return m_cmd_help_long; }
llvm::StringRef CommandObject::GetSyntax() {
- if (m_cmd_syntax.empty())
+ if (!m_cmd_syntax.empty())
return m_cmd_syntax;
StreamString syntax_str;
@@ -1113,7 +1113,8 @@ CommandObject::ArgumentTableEntry CommandObject::g_arguments_data[] = {
{ eArgTypeWatchpointID, "watchpt-id", CommandCompletions::eNoCompletion, { nullptr, false }, "Watchpoint IDs are positive integers." },
{ eArgTypeWatchpointIDRange, "watchpt-id-list", CommandCompletions::eNoCompletion, { nullptr, false }, "For example, '1-3' or '1 to 3'." },
{ eArgTypeWatchType, "watch-type", CommandCompletions::eNoCompletion, { nullptr, false }, "Specify the type for a watchpoint." },
- { eArgRawInput, "raw-input", CommandCompletions::eNoCompletion, { nullptr, false }, "Free-form text passed to a command without prior interpretation, allowing spaces without requiring quotes. To pass arguments and free form text put two dashes ' -- ' between the last argument and any raw input." }
+ { eArgRawInput, "raw-input", CommandCompletions::eNoCompletion, { nullptr, false }, "Free-form text passed to a command without prior interpretation, allowing spaces without requiring quotes. To pass arguments and free form text put two dashes ' -- ' between the last argument and any raw input." },
+ { eArgTypeCommand, "command", CommandCompletions::eNoCompletion, { nullptr, false }, "An LLDB Command line command." }
// clang-format on
};
diff --git a/source/Interpreter/OptionGroupArchitecture.cpp b/source/Interpreter/OptionGroupArchitecture.cpp
index d5354fe0739cb..bbd69b8f13fce 100644
--- a/source/Interpreter/OptionGroupArchitecture.cpp
+++ b/source/Interpreter/OptionGroupArchitecture.cpp
@@ -8,12 +8,8 @@
//===----------------------------------------------------------------------===//
#include "lldb/Interpreter/OptionGroupArchitecture.h"
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Host/OptionParser.h"
+#include "lldb/Target/Platform.h"
using namespace lldb;
using namespace lldb_private;
@@ -34,10 +30,7 @@ llvm::ArrayRef<OptionDefinition> OptionGroupArchitecture::GetDefinitions() {
bool OptionGroupArchitecture::GetArchitecture(Platform *platform,
ArchSpec &arch) {
- if (m_arch_str.empty())
- arch.Clear();
- else
- arch.SetTriple(m_arch_str.c_str(), platform);
+ arch = Platform::GetAugmentedArchSpec(platform, m_arch_str);
return arch.IsValid();
}
diff --git a/source/Interpreter/OptionGroupFormat.cpp b/source/Interpreter/OptionGroupFormat.cpp
index 7c4239f92642e..75d8df950f183 100644
--- a/source/Interpreter/OptionGroupFormat.cpp
+++ b/source/Interpreter/OptionGroupFormat.cpp
@@ -9,11 +9,6 @@
#include "lldb/Interpreter/OptionGroupFormat.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Host/OptionParser.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Target/ExecutionContext.h"
diff --git a/source/Interpreter/OptionValueDictionary.cpp b/source/Interpreter/OptionValueDictionary.cpp
index b245a09c19514..a57ede4863193 100644
--- a/source/Interpreter/OptionValueDictionary.cpp
+++ b/source/Interpreter/OptionValueDictionary.cpp
@@ -227,8 +227,7 @@ OptionValueDictionary::GetSubValue(const ExecutionContext *exe_ctx,
}
assert(!temp.empty());
- llvm::StringRef key, value;
- llvm::StringRef quote_char;
+ llvm::StringRef key, quote_char;
if (temp[0] == '\"' || temp[0] == '\'') {
quote_char = temp.take_front();
diff --git a/source/Interpreter/ScriptInterpreter.cpp b/source/Interpreter/ScriptInterpreter.cpp
index 57f7eea6e4c1c..497ad283f1a4a 100644
--- a/source/Interpreter/ScriptInterpreter.cpp
+++ b/source/Interpreter/ScriptInterpreter.cpp
@@ -69,10 +69,9 @@ lldb::ScriptLanguage
ScriptInterpreter::StringToLanguage(const llvm::StringRef &language) {
if (language.equals_lower(LanguageToString(eScriptLanguageNone)))
return eScriptLanguageNone;
- else if (language.equals_lower(LanguageToString(eScriptLanguagePython)))
+ if (language.equals_lower(LanguageToString(eScriptLanguagePython)))
return eScriptLanguagePython;
- else
- return eScriptLanguageUnknown;
+ return eScriptLanguageUnknown;
}
Status ScriptInterpreter::SetBreakpointCommandCallback(
diff --git a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
index fd5ee6ede4c37..1bd1c1bf8dd40 100644
--- a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
+++ b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
@@ -1413,10 +1413,6 @@ bool ABIMacOSX_arm::PrepareTrivialCall(Thread &thread, addr_t sp,
if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_num, return_addr))
return false;
- // Set "sp" to the requested value
- if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp))
- return false;
-
// If bit zero or 1 is set, this must be a thumb function, no need to figure
// this out from the symbols.
so_addr.SetLoadAddress(function_addr, target_sp.get());
@@ -1441,6 +1437,11 @@ bool ABIMacOSX_arm::PrepareTrivialCall(Thread &thread, addr_t sp,
function_addr &=
~1ull; // clear bit zero since the CPSR will take care of the mode for us
+ // Update the sp - stack pointer - to be aligned to 16-bytes
+ sp &= ~(0xfull);
+ if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp))
+ return false;
+
// Set "pc" to the address requested
if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, function_addr))
return false;
diff --git a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
index f91ed851a3e54..dbe333c4649e5 100644
--- a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
+++ b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
@@ -2018,7 +2018,7 @@ bool ABISysV_arm64::RegisterIsVolatile(const RegisterInfo *reg_info) {
if (name[0] == 'l' && name[1] == 'r') // lr
return false;
- if (name[0] == 'x') {
+ 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.
diff --git a/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp b/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
index 63da5a77b48fb..d799c587dd077 100644
--- a/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
+++ b/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
@@ -205,11 +205,12 @@ ABISysV_i386::GetRegisterInfoArray(uint32_t &count) {
ABISP
ABISysV_i386::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
static ABISP g_abi_sp;
- if ((arch.GetTriple().getArch() == llvm::Triple::x86) &&
- arch.GetTriple().isOSLinux()) {
- if (!g_abi_sp)
- g_abi_sp.reset(new ABISysV_i386(process_sp));
- return g_abi_sp;
+ if (arch.GetTriple().getVendor() != llvm::Triple::Apple) {
+ if (arch.GetTriple().getArch() == llvm::Triple::x86) {
+ if (!g_abi_sp)
+ g_abi_sp.reset(new ABISysV_i386(process_sp));
+ return g_abi_sp;
+ }
}
return ABISP();
}
diff --git a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
index 06a8ce932fdae..2fee176739f3f 100644
--- a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
+++ b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
@@ -291,47 +291,6 @@ bool ABISysV_ppc::PrepareTrivialCall(Thread &thread, addr_t sp,
RegisterValue reg_value;
-#if 0
- // This code adds an extra frame so that we don't lose the function that we came from
- // by pushing the PC and the FP and then writing the current FP to point to the FP value
- // we just pushed. It is disabled for now until the stack backtracing code can be debugged.
-
- // Save current PC
- const RegisterInfo *fp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
- if (reg_ctx->ReadRegister(pc_reg_info, reg_value))
- {
- if (log)
- log->Printf("Pushing the current PC onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, reg_value.GetAsUInt64());
-
- if (!process_sp->WritePointerToMemory(sp, reg_value.GetAsUInt64(), error))
- return false;
-
- sp -= 8;
-
- // Save current FP
- if (reg_ctx->ReadRegister(fp_reg_info, reg_value))
- {
- if (log)
- log->Printf("Pushing the current FP onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, reg_value.GetAsUInt64());
-
- if (!process_sp->WritePointerToMemory(sp, reg_value.GetAsUInt64(), error))
- return false;
- }
- // Setup FP backchain
- reg_value.SetUInt64 (sp);
-
- if (log)
- log->Printf("Writing FP: 0x%" PRIx64 " (for FP backchain)", reg_value.GetAsUInt64());
-
- if (!reg_ctx->WriteRegister(fp_reg_info, reg_value))
- {
- return false;
- }
-
- sp -= 8;
- }
-#endif
-
if (log)
log->Printf("Pushing the return address onto the stack: 0x%" PRIx64
": 0x%" PRIx64,
diff --git a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
index c090f01ccb1cd..0348853c7fa06 100644
--- a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
+++ b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
@@ -291,47 +291,6 @@ bool ABISysV_ppc64::PrepareTrivialCall(Thread &thread, addr_t sp,
RegisterValue reg_value;
-#if 0
- // This code adds an extra frame so that we don't lose the function that we came from
- // by pushing the PC and the FP and then writing the current FP to point to the FP value
- // we just pushed. It is disabled for now until the stack backtracing code can be debugged.
-
- // Save current PC
- const RegisterInfo *fp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
- if (reg_ctx->ReadRegister(pc_reg_info, reg_value))
- {
- if (log)
- log->Printf("Pushing the current PC onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, reg_value.GetAsUInt64());
-
- if (!process_sp->WritePointerToMemory(sp, reg_value.GetAsUInt64(), error))
- return false;
-
- sp -= 8;
-
- // Save current FP
- if (reg_ctx->ReadRegister(fp_reg_info, reg_value))
- {
- if (log)
- log->Printf("Pushing the current FP onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, reg_value.GetAsUInt64());
-
- if (!process_sp->WritePointerToMemory(sp, reg_value.GetAsUInt64(), error))
- return false;
- }
- // Setup FP backchain
- reg_value.SetUInt64 (sp);
-
- if (log)
- log->Printf("Writing FP: 0x%" PRIx64 " (for FP backchain)", reg_value.GetAsUInt64());
-
- if (!reg_ctx->WriteRegister(fp_reg_info, reg_value))
- {
- return false;
- }
-
- sp -= 8;
- }
-#endif
-
if (log)
log->Printf("Pushing the return address onto the stack: 0x%" PRIx64
": 0x%" PRIx64,
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 10bbae5664918..41d146f245269 100644
--- a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
+++ b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
@@ -13,6 +13,7 @@
// C++ Includes
// Other libraries and framework includes
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
// Project includes
@@ -1160,48 +1161,6 @@ bool ABISysV_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp,
ProcessSP process_sp(thread.GetProcess());
RegisterValue reg_value;
-
-#if 0
- // This code adds an extra frame so that we don't lose the function that we came from
- // by pushing the PC and the FP and then writing the current FP to point to the FP value
- // we just pushed. It is disabled for now until the stack backtracing code can be debugged.
-
- // Save current PC
- const RegisterInfo *fp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
- if (reg_ctx->ReadRegister(pc_reg_info, reg_value))
- {
- if (log)
- log->Printf("Pushing the current PC onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, reg_value.GetAsUInt64());
-
- if (!process_sp->WritePointerToMemory(sp, reg_value.GetAsUInt64(), error))
- return false;
-
- sp -= 8;
-
- // Save current FP
- if (reg_ctx->ReadRegister(fp_reg_info, reg_value))
- {
- if (log)
- log->Printf("Pushing the current FP onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, reg_value.GetAsUInt64());
-
- if (!process_sp->WritePointerToMemory(sp, reg_value.GetAsUInt64(), error))
- return false;
- }
- // Setup FP backchain
- reg_value.SetUInt64 (sp);
-
- if (log)
- log->Printf("Writing FP: 0x%" PRIx64 " (for FP backchain)", reg_value.GetAsUInt64());
-
- if (!reg_ctx->WriteRegister(fp_reg_info, reg_value))
- {
- return false;
- }
-
- sp -= 8;
- }
-#endif
-
if (log)
log->Printf("Pushing the return address onto the stack: 0x%" PRIx64
": 0x%" PRIx64,
@@ -1908,52 +1867,16 @@ bool ABISysV_x86_64::RegisterIsVolatile(const RegisterInfo *reg_info) {
// It's being revised & updated at https://github.com/hjl-tools/x86-psABI/
bool ABISysV_x86_64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
- if (reg_info) {
- // Preserved registers are :
- // rbx, rsp, rbp, r12, r13, r14, r15
- // mxcsr (partially preserved)
- // x87 control word
-
- const char *name = reg_info->name;
- if (name[0] == 'r') {
- switch (name[1]) {
- case '1': // r12, r13, r14, r15
- if (name[2] >= '2' && name[2] <= '5')
- return name[3] == '\0';
- break;
-
- default:
- break;
- }
- }
-
- // Accept shorter-variant versions, rbx/ebx, rip/ eip, etc.
- if (name[0] == 'r' || name[0] == 'e') {
- switch (name[1]) {
- case 'b': // rbp, rbx
- if (name[2] == 'p' || name[2] == 'x')
- return name[3] == '\0';
- break;
-
- case 'i': // rip
- if (name[2] == 'p')
- return name[3] == '\0';
- break;
-
- case 's': // rsp
- if (name[2] == 'p')
- return name[3] == '\0';
- break;
- }
- }
- if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
- return true;
- if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
- return true;
- if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
- return true;
- }
- return false;
+ if (!reg_info)
+ return false;
+ assert(reg_info->name != nullptr && "unnamed register?");
+ std::string Name = std::string(reg_info->name);
+ bool IsCalleeSaved =
+ llvm::StringSwitch<bool>(Name)
+ .Cases("r12", "r13", "r14", "r15", "rbp", "ebp", "rbx", "ebx", true)
+ .Cases("rip", "eip", "rsp", "esp", "sp", "fp", "pc", true)
+ .Default(false);
+ return IsCalleeSaved;
}
void ABISysV_x86_64::Initialize() {
diff --git a/source/Plugins/Architecture/Arm/ArchitectureArm.cpp b/source/Plugins/Architecture/Arm/ArchitectureArm.cpp
new file mode 100644
index 0000000000000..abac6d3001af1
--- /dev/null
+++ b/source/Plugins/Architecture/Arm/ArchitectureArm.cpp
@@ -0,0 +1,131 @@
+//===-- ArchitectureArm.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/Arm/ArchitectureArm.h"
+#include "Plugins/Process/Utility/ARMDefines.h"
+#include "Plugins/Process/Utility/InstructionUtils.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/ArchSpec.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+ConstString ArchitectureArm::GetPluginNameStatic() {
+ return ConstString("arm");
+}
+
+void ArchitectureArm::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ "Arm-specific algorithms",
+ &ArchitectureArm::Create);
+}
+
+void ArchitectureArm::Terminate() {
+ PluginManager::UnregisterPlugin(&ArchitectureArm::Create);
+}
+
+std::unique_ptr<Architecture> ArchitectureArm::Create(const ArchSpec &arch) {
+ if (arch.GetMachine() != llvm::Triple::arm)
+ return nullptr;
+ return std::unique_ptr<Architecture>(new ArchitectureArm());
+}
+
+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.
+ //
+ // 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
+ // 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.
+ //
+ // 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).
+
+ RegisterContextSP reg_ctx_sp(thread.GetRegisterContext());
+ if (!reg_ctx_sp)
+ return;
+
+ const uint32_t cpsr = reg_ctx_sp->GetFlags(0);
+ if (cpsr == 0)
+ return;
+
+ // Read the J and T bits to get the ISETSTATE
+ const uint32_t J = Bit32(cpsr, 24);
+ const uint32_t T = Bit32(cpsr, 5);
+ 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.
+// I will check with the lldb-dev list first before I enable this.
+#if 0
+ // ARM mode: check for condition on intsruction
+ 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.
+ const uint64_t opcode = thread.GetProcess()->ReadUnsignedIntegerFromMemory(pc, 4, UINT64_MAX, error);
+ if (opcode <= UINT32_MAX)
+ {
+ const uint32_t condition = Bits32((uint32_t)opcode, 31, 28);
+ 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
+ thread.SetStopInfo (StopInfoSP());
+ }
+ }
+#endif
+ } else if (ISETSTATE == 1) {
+ // Thumb mode
+ const uint32_t ITSTATE = Bits32(cpsr, 15, 10) << 2 | Bits32(cpsr, 26, 25);
+ if (ITSTATE != 0) {
+ const uint32_t condition = Bits32(ITSTATE, 7, 4);
+ if (!ARMConditionPassed(condition, cpsr)) {
+ // We ARE stopped in a Thumb IT instruction on an instruction whose
+ // condition doesn't pass so this instruction won't get executed.
+ // 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
new file mode 100644
index 0000000000000..9ce6c69ef271f
--- /dev/null
+++ b/source/Plugins/Architecture/Arm/ArchitectureArm.h
@@ -0,0 +1,35 @@
+//===-- ArchitectureArm.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_ARM_H
+#define LLDB_PLUGIN_ARCHITECTURE_ARM_H
+
+#include "lldb/Core/Architecture.h"
+
+namespace lldb_private {
+
+class ArchitectureArm : public Architecture {
+public:
+ static ConstString GetPluginNameStatic();
+ static void Initialize();
+ static void Terminate();
+
+ ConstString GetPluginName() override;
+ uint32_t GetPluginVersion() override;
+
+ void OverrideStopInfo(Thread &thread) override;
+
+private:
+ static std::unique_ptr<Architecture> Create(const ArchSpec &arch);
+ ArchitectureArm() = default;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_PLUGIN_ARCHITECTURE_ARM_H
diff --git a/source/Plugins/Architecture/Arm/CMakeLists.txt b/source/Plugins/Architecture/Arm/CMakeLists.txt
new file mode 100644
index 0000000000000..60bbe69a99fbf
--- /dev/null
+++ b/source/Plugins/Architecture/Arm/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_lldb_library(lldbPluginArchitectureArm PLUGIN
+ ArchitectureArm.cpp
+
+ LINK_LIBS
+ lldbPluginProcessUtility
+ lldbCore
+ lldbTarget
+ lldbUtility
+ LINK_COMPONENTS
+ Support
+ )
diff --git a/source/Plugins/Architecture/CMakeLists.txt b/source/Plugins/Architecture/CMakeLists.txt
new file mode 100644
index 0000000000000..5abaa8e682310
--- /dev/null
+++ b/source/Plugins/Architecture/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(Arm)
diff --git a/source/Plugins/CMakeLists.txt b/source/Plugins/CMakeLists.txt
index ac1afcbc331ea..5092b210a12cf 100644
--- a/source/Plugins/CMakeLists.txt
+++ b/source/Plugins/CMakeLists.txt
@@ -1,4 +1,5 @@
add_subdirectory(ABI)
+add_subdirectory(Architecture)
add_subdirectory(Disassembler)
add_subdirectory(DynamicLoader)
add_subdirectory(ExpressionParser)
diff --git a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
index a82b3fe267b3f..a81a0306671e1 100644
--- a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ b/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -1229,6 +1229,16 @@ 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 (kext_summaries[new_kext].GetUUID().IsValid()
+ && m_kernel.GetUUID().IsValid()
+ && kext_summaries[new_kext].GetUUID() == m_kernel.GetUUID()) {
+ to_be_added[new_kext] = false;
+ break;
+ }
if (add_this_one) {
number_of_new_kexts_being_added++;
}
@@ -1397,7 +1407,7 @@ bool DynamicLoaderDarwinKernel::ReadAllKextSummaries() {
void DynamicLoaderDarwinKernel::KextImageInfo::PutToLog(Log *log) const {
if (log == NULL)
return;
- const uint8_t *u = (uint8_t *)m_uuid.GetBytes();
+ const uint8_t *u = static_cast<const uint8_t *>(m_uuid.GetBytes());
if (m_load_address == LLDB_INVALID_ADDRESS) {
if (u) {
diff --git a/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp b/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
index 1ef1be5d0adb3..c49cdc2f11b1e 100644
--- a/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
+++ b/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
@@ -7,10 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolContext.h"
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
index c1986976b0fc4..e601d64f0d8d0 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
@@ -7,10 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Symbol.h"
@@ -18,6 +14,7 @@
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
diff --git a/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp b/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
index c381326ebf4fe..6502d7a7a58ce 100644
--- a/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
+++ b/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
@@ -11,8 +11,11 @@
#include "DynamicLoaderWindowsDYLD.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
+#include "lldb/Target/ThreadPlanStepInstruction.h"
#include "llvm/ADT/Triple.h"
@@ -72,5 +75,44 @@ uint32_t DynamicLoaderWindowsDYLD::GetPluginVersion() { return 1; }
ThreadPlanSP
DynamicLoaderWindowsDYLD::GetStepThroughTrampolinePlan(Thread &thread,
bool stop) {
- return ThreadPlanSP();
+ auto arch = m_process->GetTarget().GetArchitecture();
+ if (arch.GetMachine() != llvm::Triple::x86) {
+ return ThreadPlanSP();
+ }
+
+ uint64_t pc = thread.GetRegisterContext()->GetPC();
+ // Max size of an instruction in x86 is 15 bytes.
+ AddressRange range(pc, 2 * 15);
+
+ ExecutionContext exe_ctx(m_process->GetTarget());
+ DisassemblerSP disassembler_sp = Disassembler::DisassembleRange(
+ arch, nullptr, nullptr, exe_ctx, range, true);
+ if (!disassembler_sp) {
+ return ThreadPlanSP();
+ }
+
+ InstructionList *insn_list = &disassembler_sp->GetInstructionList();
+ if (insn_list == nullptr) {
+ return ThreadPlanSP();
+ }
+
+ // First instruction in a x86 Windows trampoline is going to be an indirect
+ // jump through the IAT and the next one will be a nop (usually there for
+ // alignment purposes). e.g.:
+ // 0x70ff4cfc <+956>: jmpl *0x7100c2a8
+ // 0x70ff4d02 <+962>: nop
+
+ auto first_insn = insn_list->GetInstructionAtIndex(0);
+ auto second_insn = insn_list->GetInstructionAtIndex(1);
+
+ if (first_insn == nullptr || second_insn == nullptr ||
+ strcmp(first_insn->GetMnemonic(&exe_ctx), "jmpl") != 0 ||
+ strcmp(second_insn->GetMnemonic(&exe_ctx), "nop") != 0) {
+ return ThreadPlanSP();
+ }
+
+ assert(first_insn->DoesBranch() && !second_insn->DoesBranch());
+
+ return ThreadPlanSP(new ThreadPlanStepInstruction(
+ thread, false, false, eVoteNoOpinion, eVoteNoOpinion));
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
index 7622791778ba2..7f031356b3c3f 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
@@ -51,8 +51,94 @@ private:
};
}
+ClangASTSource::ClangASTSource(const lldb::TargetSP &target)
+ : m_import_in_progress(false), m_lookups_enabled(false), m_target(target),
+ m_ast_context(NULL), m_active_lexical_decls(), m_active_lookups() {
+ if (!target->GetUseModernTypeLookup()) {
+ m_ast_importer_sp = m_target->GetClangASTImporter();
+ }
+}
+
+void ClangASTSource::InstallASTContext(clang::ASTContext &ast_context,
+ clang::FileManager &file_manager,
+ bool is_shared_context) {
+ m_ast_context = &ast_context;
+ m_file_manager = &file_manager;
+ if (m_target->GetUseModernTypeLookup()) {
+ // Configure the ExternalASTMerger. The merger needs to be able to import
+ // types from any source that we would do lookups in, which includes the
+ // persistent AST context as well as the modules and Objective-C runtime
+ // AST contexts.
+
+ lldbassert(!m_merger_up);
+ clang::ExternalASTMerger::ImporterTarget target = {ast_context,
+ file_manager};
+ std::vector<clang::ExternalASTMerger::ImporterSource> sources;
+ for (lldb::ModuleSP module_sp : m_target->GetImages().Modules()) {
+ if (auto *module_ast_ctx = llvm::cast_or_null<ClangASTContext>(
+ module_sp->GetTypeSystemForLanguage(lldb::eLanguageTypeC))) {
+ lldbassert(module_ast_ctx->getASTContext());
+ lldbassert(module_ast_ctx->getFileManager());
+ sources.push_back({*module_ast_ctx->getASTContext(),
+ *module_ast_ctx->getFileManager(),
+ module_ast_ctx->GetOriginMap()
+ });
+ }
+ }
+
+ do {
+ lldb::ProcessSP process(m_target->GetProcessSP());
+
+ if (!process)
+ break;
+
+ ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
+
+ if (!language_runtime)
+ break;
+
+ DeclVendor *runtime_decl_vendor = language_runtime->GetDeclVendor();
+
+ if (!runtime_decl_vendor)
+ break;
+
+ sources.push_back(runtime_decl_vendor->GetImporterSource());
+ } while (0);
+
+ do {
+ DeclVendor *modules_decl_vendor =
+ m_target->GetClangModulesDeclVendor();
+
+ if (!modules_decl_vendor)
+ break;
+
+ sources.push_back(modules_decl_vendor->GetImporterSource());
+ } while (0);
+
+ if (!is_shared_context) {
+ // Update the scratch AST context's merger to reflect any new sources we
+ // might have come across since the last time an expression was parsed.
+
+ auto scratch_ast_context = static_cast<ClangASTContextForExpressions*>(
+ m_target->GetScratchClangASTContext());
+
+ scratch_ast_context->GetMergerUnchecked().AddSources(sources);
+
+ sources.push_back({*scratch_ast_context->getASTContext(),
+ *scratch_ast_context->getFileManager(),
+ scratch_ast_context->GetOriginMap()});
+ } while (0);
+
+ m_merger_up =
+ llvm::make_unique<clang::ExternalASTMerger>(target, sources);
+ } else {
+ m_ast_importer_sp->InstallMapCompleter(&ast_context, *this);
+ }
+}
+
ClangASTSource::~ClangASTSource() {
- m_ast_importer_sp->ForgetDestination(m_ast_context);
+ if (m_ast_importer_sp)
+ m_ast_importer_sp->ForgetDestination(m_ast_context);
// We are in the process of destruction, don't create clang ast context on
// demand
@@ -69,7 +155,7 @@ ClangASTSource::~ClangASTSource() {
if (!scratch_ast_context)
return;
- if (m_ast_context != scratch_ast_context)
+ if (m_ast_context != scratch_ast_context && m_ast_importer_sp)
m_ast_importer_sp->ForgetSource(scratch_ast_context, m_ast_context);
}
@@ -203,6 +289,13 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) {
m_active_lexical_decls.insert(tag_decl);
ScopedLexicalDeclEraser eraser(m_active_lexical_decls, tag_decl);
+ if (!m_ast_importer_sp) {
+ if (HasMerger()) {
+ GetMergerUnchecked().CompleteType(tag_decl);
+ }
+ return;
+ }
+
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.
@@ -337,6 +430,22 @@ void ClangASTSource::CompleteType(clang::ObjCInterfaceDecl *interface_decl) {
dumper.ToLog(log, " [COID] ");
}
+ if (!m_ast_importer_sp) {
+ if (HasMerger()) {
+ ObjCInterfaceDecl *complete_iface_decl =
+ GetCompleteObjCInterface(interface_decl);
+
+ if (complete_iface_decl && (complete_iface_decl != interface_decl)) {
+ m_merger_up->ForceRecordOrigin(interface_decl, {complete_iface_decl, &complete_iface_decl->getASTContext()});
+ }
+
+ GetMergerUnchecked().CompleteType(interface_decl);
+ } else {
+ lldbassert(0 && "No mechanism for completing a type!");
+ }
+ return;
+ }
+
Decl *original_decl = NULL;
ASTContext *original_ctx = NULL;
@@ -367,7 +476,7 @@ void ClangASTSource::CompleteType(clang::ObjCInterfaceDecl *interface_decl) {
}
clang::ObjCInterfaceDecl *ClangASTSource::GetCompleteObjCInterface(
- clang::ObjCInterfaceDecl *interface_decl) {
+ const clang::ObjCInterfaceDecl *interface_decl) {
lldb::ProcessSP process(m_target->GetProcessSP());
if (!process)
@@ -411,6 +520,22 @@ void ClangASTSource::FindExternalLexicalDecls(
const DeclContext *decl_context,
llvm::function_ref<bool(Decl::Kind)> predicate,
llvm::SmallVectorImpl<Decl *> &decls) {
+
+ if (HasMerger()) {
+ if (auto *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl_context)) {
+ ObjCInterfaceDecl *complete_iface_decl =
+ GetCompleteObjCInterface(interface_decl);
+
+ if (complete_iface_decl && (complete_iface_decl != interface_decl)) {
+ m_merger_up->ForceRecordOrigin(interface_decl, {complete_iface_decl, &complete_iface_decl->getASTContext()});
+ }
+ }
+ return GetMergerUnchecked().FindExternalLexicalDecls(decl_context,
+ predicate,
+ decls);
+ } else if (!m_ast_importer_sp)
+ return;
+
ClangASTMetrics::RegisterLexicalQuery();
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -507,8 +632,7 @@ void ClangASTSource::FindExternalLexicalDecls(
decl->getDeclKindName(), ast_dumper.GetCString());
}
- Decl *copied_decl =
- m_ast_importer_sp->CopyDecl(m_ast_context, original_ctx, decl);
+ Decl *copied_decl = CopyDecl(decl);
if (!copied_decl)
continue;
@@ -568,12 +692,31 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) {
name.GetCString(), context.m_decl_context->getDeclKindName());
}
+ if (HasMerger() && !isa<TranslationUnitDecl>(context.m_decl_context)
+ /* possibly handle NamespaceDecls here? */) {
+ if (auto *interface_decl =
+ dyn_cast<ObjCInterfaceDecl>(context.m_decl_context)) {
+ ObjCInterfaceDecl *complete_iface_decl =
+ GetCompleteObjCInterface(interface_decl);
+
+ if (complete_iface_decl && (complete_iface_decl != interface_decl)) {
+ GetMergerUnchecked().ForceRecordOrigin(
+ interface_decl,
+ {complete_iface_decl, &complete_iface_decl->getASTContext()});
+ }
+ }
+
+ GetMergerUnchecked().FindExternalVisibleDeclsByName(context.m_decl_context,
+ context.m_decl_name);
+ return; // otherwise we may need to fall back
+ }
+
context.m_namespace_map.reset(new ClangASTImporter::NamespaceMap);
if (const NamespaceDecl *namespace_context =
dyn_cast<NamespaceDecl>(context.m_decl_context)) {
- ClangASTImporter::NamespaceMapSP namespace_map =
- m_ast_importer_sp->GetNamespaceMap(namespace_context);
+ ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer_sp ?
+ m_ast_importer_sp->GetNamespaceMap(namespace_context) : nullptr;
if (log && log->GetVerbose())
log->Printf(" CAS::FEVD[%u] Inspecting namespace map %p (%d entries)",
@@ -593,7 +736,7 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) {
FindExternalVisibleDecls(context, i->first, i->second, current_id);
}
- } else if (isa<ObjCInterfaceDecl>(context.m_decl_context)) {
+ } else if (isa<ObjCInterfaceDecl>(context.m_decl_context) && !HasMerger()) {
FindObjCPropertyAndIvarDecls(context);
} else if (!isa<TranslationUnitDecl>(context.m_decl_context)) {
// we shouldn't be getting FindExternalVisibleDecls calls for these
@@ -623,6 +766,25 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) {
}
}
+bool ClangASTSource::IgnoreName(const ConstString name,
+ bool ignore_all_dollar_names) {
+ static const ConstString id_name("id");
+ static const ConstString Class_name("Class");
+
+ if (name == id_name || name == Class_name)
+ return true;
+
+ StringRef name_string_ref = name.GetStringRef();
+
+ // The ClangASTSource is not responsible for finding $-names.
+ if (name_string_ref.empty() ||
+ (ignore_all_dollar_names && name_string_ref.startswith("$")) ||
+ name_string_ref.startswith("_$"))
+ return true;
+
+ return false;
+}
+
void ClangASTSource::FindExternalVisibleDecls(
NameSearchContext &context, lldb::ModuleSP module_sp,
CompilerDeclContext &namespace_decl, unsigned int current_id) {
@@ -633,20 +795,7 @@ void ClangASTSource::FindExternalVisibleDecls(
SymbolContextList sc_list;
const ConstString name(context.m_decl_name.getAsString().c_str());
-
- const char *name_unique_cstr = name.GetCString();
-
- static ConstString id_name("id");
- static ConstString Class_name("Class");
-
- if (name == id_name || name == Class_name)
- return;
-
- if (name_unique_cstr == NULL)
- return;
-
- // The ClangASTSource is not responsible for finding $-names.
- if (name_unique_cstr[0] == '$')
+ if (IgnoreName(name, true))
return;
if (module_sp && namespace_decl) {
@@ -671,7 +820,7 @@ void ClangASTSource::FindExternalVisibleDecls(
module_sp->GetFileSpec().GetFilename().GetCString());
}
}
- } else {
+ } else if (!HasMerger()) {
const ModuleList &target_images = m_target->GetImages();
std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
@@ -774,9 +923,7 @@ void ClangASTSource::FindExternalVisibleDecls(
if (llvm::isa<clang::TypeDecl>(decl_from_modules) ||
llvm::isa<clang::ObjCContainerDecl>(decl_from_modules) ||
llvm::isa<clang::EnumConstantDecl>(decl_from_modules)) {
- clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
- m_ast_context, &decl_from_modules->getASTContext(),
- decl_from_modules);
+ clang::Decl *copied_decl = CopyDecl(decl_from_modules);
clang::NamedDecl *copied_named_decl =
copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
@@ -831,8 +978,7 @@ void ClangASTSource::FindExternalVisibleDecls(
current_id, name.GetCString());
}
- clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
- m_ast_context, &decls[0]->getASTContext(), decls[0]);
+ clang::Decl *copied_decl = CopyDecl(decls[0]);
clang::NamedDecl *copied_named_decl =
copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
@@ -875,7 +1021,7 @@ public:
DeclFromParser() : TaggedASTDecl<D>() {}
DeclFromParser(D *_decl) : TaggedASTDecl<D>(_decl) {}
- DeclFromUser<D> GetOrigin(ClangASTImporter *importer);
+ DeclFromUser<D> GetOrigin(ClangASTSource &source);
};
template <class D> class DeclFromUser : public TaggedASTDecl<D> {
@@ -883,32 +1029,29 @@ public:
DeclFromUser() : TaggedASTDecl<D>() {}
DeclFromUser(D *_decl) : TaggedASTDecl<D>(_decl) {}
- DeclFromParser<D> Import(ClangASTImporter *importer, ASTContext &dest_ctx);
+ DeclFromParser<D> Import(ClangASTSource &source);
};
template <class D>
-DeclFromUser<D> DeclFromParser<D>::GetOrigin(ClangASTImporter *importer) {
+DeclFromUser<D> DeclFromParser<D>::GetOrigin(ClangASTSource &source) {
DeclFromUser<> origin_decl;
- importer->ResolveDeclOrigin(this->decl, &origin_decl.decl, NULL);
+ source.ResolveDeclOrigin(this->decl, &origin_decl.decl, NULL);
if (origin_decl.IsInvalid())
return DeclFromUser<D>();
return DeclFromUser<D>(dyn_cast<D>(origin_decl.decl));
}
template <class D>
-DeclFromParser<D> DeclFromUser<D>::Import(ClangASTImporter *importer,
- ASTContext &dest_ctx) {
- DeclFromParser<> parser_generic_decl(
- importer->CopyDecl(&dest_ctx, &this->decl->getASTContext(), this->decl));
+DeclFromParser<D> DeclFromUser<D>::Import(ClangASTSource &source) {
+ DeclFromParser<> parser_generic_decl(source.CopyDecl(this->decl));
if (parser_generic_decl.IsInvalid())
return DeclFromParser<D>();
return DeclFromParser<D>(dyn_cast<D>(parser_generic_decl.decl));
}
-static bool FindObjCMethodDeclsWithOrigin(
+bool ClangASTSource::FindObjCMethodDeclsWithOrigin(
unsigned int current_id, NameSearchContext &context,
- ObjCInterfaceDecl *original_interface_decl, clang::ASTContext *ast_context,
- ClangASTImporter *ast_importer, const char *log_info) {
+ ObjCInterfaceDecl *original_interface_decl, const char *log_info) {
const DeclarationName &decl_name(context.m_decl_name);
clang::ASTContext *original_ctx = &original_interface_decl->getASTContext();
@@ -967,8 +1110,7 @@ static bool FindObjCMethodDeclsWithOrigin(
if (!result_method)
continue;
- Decl *copied_decl = ast_importer->CopyDecl(
- ast_context, &result_method->getASTContext(), result_method);
+ Decl *copied_decl = CopyDecl(result_method);
if (!copied_decl)
continue;
@@ -995,6 +1137,21 @@ static bool FindObjCMethodDeclsWithOrigin(
void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+ if (HasMerger()) {
+ if (auto *interface_decl = dyn_cast<ObjCInterfaceDecl>(context.m_decl_context)) {
+ ObjCInterfaceDecl *complete_iface_decl =
+ GetCompleteObjCInterface(interface_decl);
+
+ if (complete_iface_decl && (complete_iface_decl != context.m_decl_context)) {
+ m_merger_up->ForceRecordOrigin(interface_decl, {complete_iface_decl, &complete_iface_decl->getASTContext()});
+ }
+ }
+
+ GetMergerUnchecked().FindExternalVisibleDeclsByName(context.m_decl_context,
+ context.m_decl_name);
+ return;
+ }
+
static unsigned int invocation_id = 0;
unsigned int current_id = invocation_id++;
@@ -1021,8 +1178,7 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
dyn_cast<ObjCInterfaceDecl>(original_decl);
if (FindObjCMethodDeclsWithOrigin(current_id, context,
- original_interface_decl, m_ast_context,
- m_ast_importer_sp.get(), "at origin"))
+ original_interface_decl, "at origin"))
return; // found it, no need to look any further
} while (0);
@@ -1160,8 +1316,7 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
continue;
if (found_interface_decl->getName() == interface_decl->getName()) {
- Decl *copied_decl = m_ast_importer_sp->CopyDecl(
- m_ast_context, &method_decl->getASTContext(), method_decl);
+ Decl *copied_decl = CopyDecl(method_decl);
if (!copied_decl)
continue;
@@ -1210,7 +1365,6 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
static_cast<void *>(&complete_iface_decl->getASTContext()));
FindObjCMethodDeclsWithOrigin(current_id, context, complete_interface_decl,
- m_ast_context, m_ast_importer_sp.get(),
"in debug info");
return;
@@ -1238,8 +1392,7 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
break;
if (FindObjCMethodDeclsWithOrigin(
- current_id, context, interface_decl_from_modules, m_ast_context,
- m_ast_importer_sp.get(), "in modules"))
+ current_id, context, interface_decl_from_modules, "in modules"))
return;
}
} while (0);
@@ -1278,14 +1431,12 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
break;
FindObjCMethodDeclsWithOrigin(current_id, context, runtime_interface_decl,
- m_ast_context, m_ast_importer_sp.get(),
"in runtime");
} while (0);
}
static bool FindObjCPropertyAndIvarDeclsWithOrigin(
- unsigned int current_id, NameSearchContext &context,
- clang::ASTContext &ast_context, ClangASTImporter *ast_importer,
+ unsigned int current_id, NameSearchContext &context, ClangASTSource &source,
DeclFromUser<const ObjCInterfaceDecl> &origin_iface_decl) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -1305,7 +1456,7 @@ static bool FindObjCPropertyAndIvarDeclsWithOrigin(
if (origin_property_decl.IsValid()) {
DeclFromParser<ObjCPropertyDecl> parser_property_decl(
- origin_property_decl.Import(ast_importer, ast_context));
+ origin_property_decl.Import(source));
if (parser_property_decl.IsValid()) {
if (log) {
ASTDumper dumper((Decl *)parser_property_decl.decl);
@@ -1323,7 +1474,7 @@ static bool FindObjCPropertyAndIvarDeclsWithOrigin(
if (origin_ivar_decl.IsValid()) {
DeclFromParser<ObjCIvarDecl> parser_ivar_decl(
- origin_ivar_decl.Import(ast_importer, ast_context));
+ origin_ivar_decl.Import(source));
if (parser_ivar_decl.IsValid()) {
if (log) {
ASTDumper dumper((Decl *)parser_ivar_decl.decl);
@@ -1348,7 +1499,7 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
DeclFromParser<const ObjCInterfaceDecl> parser_iface_decl(
cast<ObjCInterfaceDecl>(context.m_decl_context));
DeclFromUser<const ObjCInterfaceDecl> origin_iface_decl(
- parser_iface_decl.GetOrigin(m_ast_importer_sp.get()));
+ parser_iface_decl.GetOrigin(*this));
ConstString class_name(parser_iface_decl->getNameAsString().c_str());
@@ -1360,8 +1511,7 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
context.m_decl_name.getAsString().c_str());
if (FindObjCPropertyAndIvarDeclsWithOrigin(
- current_id, context, *m_ast_context, m_ast_importer_sp.get(),
- origin_iface_decl))
+ current_id, context, *this, origin_iface_decl))
return;
if (log)
@@ -1397,8 +1547,7 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
static_cast<const void *>(complete_iface_decl.decl),
static_cast<void *>(&complete_iface_decl->getASTContext()));
- FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *m_ast_context,
- m_ast_importer_sp.get(),
+ FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *this,
complete_iface_decl);
return;
@@ -1435,9 +1584,8 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
static_cast<const void *>(interface_decl_from_modules.decl),
static_cast<void *>(&interface_decl_from_modules->getASTContext()));
- if (FindObjCPropertyAndIvarDeclsWithOrigin(
- current_id, context, *m_ast_context, m_ast_importer_sp.get(),
- interface_decl_from_modules))
+ if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *this,
+ interface_decl_from_modules))
return;
} while (0);
@@ -1483,8 +1631,7 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
static_cast<void *>(&interface_decl_from_runtime->getASTContext()));
if (FindObjCPropertyAndIvarDeclsWithOrigin(
- current_id, context, *m_ast_context, m_ast_importer_sp.get(),
- interface_decl_from_runtime))
+ current_id, context, *this, interface_decl_from_runtime))
return;
} while (0);
}
@@ -1495,7 +1642,7 @@ typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetMap;
template <class D, class O>
static bool ImportOffsetMap(llvm::DenseMap<const D *, O> &destination_map,
llvm::DenseMap<const D *, O> &source_map,
- ClangASTImporter *importer, ASTContext &dest_ctx) {
+ 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
@@ -1516,7 +1663,7 @@ static bool ImportOffsetMap(llvm::DenseMap<const D *, O> &destination_map,
for (const auto &item : sorted_items) {
DeclFromUser<D> user_decl(const_cast<D *>(item.first));
- DeclFromParser<D> parser_decl(user_decl.Import(importer, dest_ctx));
+ DeclFromParser<D> parser_decl(user_decl.Import(source));
if (parser_decl.IsInvalid())
return false;
destination_map.insert(
@@ -1593,7 +1740,7 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
DeclFromParser<const RecordDecl> parser_record(record);
DeclFromUser<const RecordDecl> origin_record(
- parser_record.GetOrigin(m_ast_importer_sp.get()));
+ parser_record.GetOrigin(*this));
if (origin_record.IsInvalid())
return false;
@@ -1629,7 +1776,7 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
field_idx++;
}
- ASTContext &parser_ast_context(record->getASTContext());
+ lldbassert(&record->getASTContext() == m_ast_context);
DeclFromUser<const CXXRecordDecl> origin_cxx_record(
DynCast<const CXXRecordDecl>(origin_record));
@@ -1642,12 +1789,10 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
return false;
}
- if (!ImportOffsetMap(field_offsets, origin_field_offsets,
- m_ast_importer_sp.get(), parser_ast_context) ||
- !ImportOffsetMap(base_offsets, origin_base_offsets,
- m_ast_importer_sp.get(), parser_ast_context) ||
+ if (!ImportOffsetMap(field_offsets, origin_field_offsets, *this) ||
+ !ImportOffsetMap(base_offsets, origin_base_offsets, *this) ||
!ImportOffsetMap(virtual_base_offsets, origin_virtual_base_offsets,
- m_ast_importer_sp.get(), parser_ast_context))
+ *this))
return false;
size = record_layout.getSize().getQuantity() * m_ast_context->getCharWidth();
@@ -1811,8 +1956,7 @@ NamespaceDecl *ClangASTSource::AddNamespace(
if (!src_namespace_decl)
return nullptr;
- Decl *copied_decl =
- m_ast_importer_sp->CopyDecl(m_ast_context, src_ast, src_namespace_decl);
+ Decl *copied_decl = CopyDecl(src_namespace_decl);
if (!copied_decl)
return nullptr;
@@ -1830,6 +1974,54 @@ NamespaceDecl *ClangASTSource::AddNamespace(
return dyn_cast<NamespaceDecl>(copied_decl);
}
+clang::QualType ClangASTSource::CopyTypeWithMerger(
+ clang::ASTContext &from_context,
+ clang::ExternalASTMerger &merger,
+ clang::QualType type) {
+ if (!merger.HasImporterForOrigin(from_context)) {
+ lldbassert(0 && "Couldn't find the importer for a source context!");
+ return QualType();
+ }
+
+ return merger.ImporterForOrigin(from_context).Import(type);
+}
+
+clang::Decl *ClangASTSource::CopyDecl(Decl *src_decl) {
+ clang::ASTContext &from_context = src_decl->getASTContext();
+ if (m_ast_importer_sp) {
+ return m_ast_importer_sp->CopyDecl(m_ast_context, &from_context, src_decl);
+ } else if (m_merger_up) {
+ if (!m_merger_up->HasImporterForOrigin(from_context)) {
+ lldbassert(0 && "Couldn't find the importer for a source context!");
+ return nullptr;
+ }
+
+ return m_merger_up->ImporterForOrigin(from_context).Import(src_decl);
+ } else {
+ lldbassert(0 && "No mechanism for copying a decl!");
+ return nullptr;
+ }
+}
+
+bool ClangASTSource::ResolveDeclOrigin(const clang::Decl *decl,
+ clang::Decl **original_decl,
+ clang::ASTContext **original_ctx) {
+ if (m_ast_importer_sp) {
+ return m_ast_importer_sp->ResolveDeclOrigin(decl, original_decl,
+ original_ctx);
+ } else if (m_merger_up) {
+ return false; // Implement this correctly in ExternalASTMerger
+ } else {
+ // this can happen early enough that no ExternalASTSource is installed.
+ return false;
+ }
+}
+
+clang::ExternalASTMerger &ClangASTSource::GetMergerUnchecked() {
+ lldbassert(m_merger_up != nullptr);
+ return *m_merger_up;
+}
+
CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) {
ClangASTContext *src_ast =
llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem());
@@ -1840,9 +2032,20 @@ CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) {
SetImportInProgress(true);
- QualType copied_qual_type =
- m_ast_importer_sp->CopyType(m_ast_context, src_ast->getASTContext(),
- ClangUtil::GetQualType(src_type));
+ QualType copied_qual_type;
+
+ if (m_ast_importer_sp) {
+ copied_qual_type =
+ m_ast_importer_sp->CopyType(m_ast_context, src_ast->getASTContext(),
+ ClangUtil::GetQualType(src_type));
+ } else if (m_merger_up) {
+ copied_qual_type =
+ CopyTypeWithMerger(*src_ast->getASTContext(), *m_merger_up,
+ ClangUtil::GetQualType(src_type));
+ } else {
+ lldbassert(0 && "No mechanism for copying a type!");
+ return CompilerType();
+ }
SetImportInProgress(false);
diff --git a/source/Plugins/ExpressionParser/Clang/ClangASTSource.h b/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
index 6362f04cf4886..6f72ad92dc8c0 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
@@ -16,6 +16,7 @@
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Target/Target.h"
+#include "clang/AST/ExternalASTMerger.h"
#include "clang/Basic/IdentifierTable.h"
#include "llvm/ADT/SmallSet.h"
@@ -41,14 +42,10 @@ public:
///
/// Initializes class variables.
///
- /// @param[in] declMap
- /// A reference to the LLDB object that handles entity lookup.
+ /// @param[in] target
+ /// A reference to the target containing debug information to use.
//------------------------------------------------------------------
- ClangASTSource(const lldb::TargetSP &target)
- : m_import_in_progress(false), m_lookups_enabled(false), m_target(target),
- m_ast_context(NULL), m_active_lexical_decls(), m_active_lookups() {
- m_ast_importer_sp = m_target->GetClangASTImporter();
- }
+ ClangASTSource(const lldb::TargetSP &target);
//------------------------------------------------------------------
/// Destructor
@@ -70,10 +67,9 @@ public:
}
void MaterializeVisibleDecls(const clang::DeclContext *DC) { return; }
- void InstallASTContext(clang::ASTContext *ast_context) {
- m_ast_context = ast_context;
- m_ast_importer_sp->InstallMapCompleter(ast_context, *this);
- }
+ void InstallASTContext(clang::ASTContext &ast_context,
+ clang::FileManager &file_manager,
+ bool is_shared_context = false);
//
// APIs for ExternalASTSource
@@ -313,7 +309,7 @@ protected:
/// the complete interface otherwise.
//------------------------------------------------------------------
clang::ObjCInterfaceDecl *
- GetCompleteObjCInterface(clang::ObjCInterfaceDecl *interface_decl);
+ GetCompleteObjCInterface(const clang::ObjCInterfaceDecl *interface_decl);
//------------------------------------------------------------------
/// Find all entities matching a given name in a given module,
@@ -376,6 +372,89 @@ protected:
//------------------------------------------------------------------
CompilerType GuardedCopyType(const CompilerType &src_type);
+public:
+ //------------------------------------------------------------------
+ /// Returns true if a name should be ignored by name lookup.
+ ///
+ /// @param[in] name
+ /// The name to be considered.
+ ///
+ /// @param[in] ignore_all_dollar_nmmes
+ /// True if $-names of all sorts should be ignored.
+ ///
+ /// @return
+ /// True if the name is one of a class of names that are ignored by
+ /// global lookup for performance reasons.
+ //------------------------------------------------------------------
+ bool IgnoreName(const ConstString name, bool ignore_all_dollar_names);
+
+public:
+ //------------------------------------------------------------------
+ /// Copies a single Decl into the parser's AST context.
+ ///
+ /// @param[in] src_decl
+ /// The Decl to copy.
+ ///
+ /// @return
+ /// A copy of the Decl in m_ast_context, or NULL if the copy failed.
+ //------------------------------------------------------------------
+ clang::Decl *CopyDecl(clang::Decl *src_decl);
+
+ //------------------------------------------------------------------
+ /// Copies a single Type to the target of the given ExternalASTMerger.
+ ///
+ /// @param[in] src_context
+ /// The ASTContext containing the type.
+ ///
+ /// @param[in] merger
+ /// The merger to use. This isn't just *m_merger_up because it might be
+ /// the persistent AST context's merger.
+ ///
+ /// @param[in] type
+ /// The type to copy.
+ ///
+ /// @return
+ /// A copy of the Type in the merger's target context.
+ //------------------------------------------------------------------
+ clang::QualType CopyTypeWithMerger(clang::ASTContext &src_context,
+ clang::ExternalASTMerger &merger,
+ clang::QualType type);
+
+ //------------------------------------------------------------------
+ /// Determined the origin of a single Decl, if it can be found.
+ ///
+ /// @param[in] decl
+ /// The Decl whose origin is to be found.
+ ///
+ /// @param[out] original_decl
+ /// A pointer whose target is filled in with the original Decl.
+ ///
+ /// @param[in] original_ctx
+ /// A pointer whose target is filled in with the original's ASTContext.
+ ///
+ /// @return
+ /// True if lookup succeeded; false otherwise.
+ //------------------------------------------------------------------
+ bool ResolveDeclOrigin(const clang::Decl *decl, clang::Decl **original_decl,
+ clang::ASTContext **original_ctx);
+
+ //------------------------------------------------------------------
+ /// Returns m_merger_up. Only call this if the target is configured to use
+ /// modern lookup,
+ //------------------------------------------------------------------
+ clang::ExternalASTMerger &GetMergerUnchecked();
+
+ //------------------------------------------------------------------
+ /// Returns true if there is a merger. This only occurs if the target is
+ /// using modern lookup.
+ //------------------------------------------------------------------
+ bool HasMerger() { return (bool)m_merger_up; }
+
+protected:
+ bool FindObjCMethodDeclsWithOrigin(
+ unsigned int current_id, NameSearchContext &context,
+ clang::ObjCInterfaceDecl *original_interface_decl, const char *log_info);
+
friend struct NameSearchContext;
bool m_import_in_progress;
@@ -385,7 +464,11 @@ protected:
m_target; ///< The target to use in finding variables and types.
clang::ASTContext
*m_ast_context; ///< The AST context requests are coming in for.
+ clang::FileManager
+ *m_file_manager; ///< The file manager paired with the AST context.
lldb::ClangASTImporterSP m_ast_importer_sp; ///< The target's AST importer.
+ std::unique_ptr<clang::ExternalASTMerger> m_merger_up;
+ ///< The ExternalASTMerger for this parse.
std::set<const clang::Decl *> m_active_lexical_decls;
std::set<const char *> m_active_lookups;
};
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index 8fde41052192b..07ff2e97aac77 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -48,8 +48,10 @@
#include "lldb/lldb-private.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTImporter.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclarationName.h"
+#include "clang/AST/RecursiveASTVisitor.h"
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
@@ -178,6 +180,134 @@ ClangExpressionDeclMap::TargetInfo ClangExpressionDeclMap::GetTargetInfo() {
return ret;
}
+namespace {
+/// This class walks an AST and ensures that all DeclContexts defined inside the
+/// current source file are properly complete.
+///
+/// This is used to ensure that persistent types defined in the current source
+/// file migrate completely to the persistent AST context before they are
+/// reused. If that didn't happen, it would be impoossible to complete them
+/// because their origin would be gone.
+///
+/// The stragtegy used by this class is to check the SourceLocation (to be
+/// specific, the FileID) and see if it's the FileID for the current expression.
+/// Alternate strategies could include checking whether an ExternalASTMerger,
+/// set up to not have the current context as a source, can find an original for
+/// the type.
+class Completer : public clang::RecursiveASTVisitor<Completer> {
+private:
+ clang::ASTImporter &m_exporter; /// Used to import Decl contents
+ clang::FileID m_file; /// The file that's going away
+ llvm::DenseSet<clang::Decl *> m_completed; /// Visited Decls, to avoid cycles
+
+ bool ImportAndCheckCompletable(clang::Decl *decl) {
+ (void)m_exporter.Import(decl);
+ if (m_completed.count(decl))
+ return false;
+ if (!llvm::isa<DeclContext>(decl))
+ return false;
+ const clang::SourceLocation loc = decl->getLocation();
+ if (!loc.isValid())
+ return false;
+ const clang::FileID file =
+ 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.
+ lldbassert(!llvm::cast<DeclContext>(decl)->hasExternalLexicalStorage());
+ return true;
+ }
+
+ void Complete(clang::Decl *decl) {
+ m_completed.insert(decl);
+ auto *decl_context = llvm::cast<DeclContext>(decl);
+ (void)m_exporter.Import(decl);
+ m_exporter.CompleteDecl(decl);
+ for (Decl *child : decl_context->decls())
+ if (ImportAndCheckCompletable(child))
+ Complete(child);
+ }
+
+ void MaybeComplete(clang::Decl *decl) {
+ if (ImportAndCheckCompletable(decl))
+ Complete(decl);
+ }
+
+public:
+ Completer(clang::ASTImporter &exporter, clang::FileID file)
+ : m_exporter(exporter), m_file(file) {}
+
+ // Implements the RecursiveASTVisitor's core API. It is called on each Decl
+ // that the RecursiveASTVisitor encounters, and returns true if the traversal
+ // should continue.
+ bool VisitDecl(clang::Decl *decl) {
+ MaybeComplete(decl);
+ return true;
+ }
+};
+}
+
+static void CompleteAllDeclContexts(clang::ASTImporter &exporter,
+ clang::FileID file,
+ clang::QualType root) {
+ clang::QualType canonical_type = root.getCanonicalType();
+ if (clang::TagDecl *tag_decl = canonical_type->getAsTagDecl()) {
+ Completer(exporter, file).TraverseDecl(tag_decl);
+ } else if (auto interface_type = llvm::dyn_cast<ObjCInterfaceType>(
+ canonical_type.getTypePtr())) {
+ Completer(exporter, file).TraverseDecl(interface_type->getDecl());
+ } else {
+ Completer(exporter, file).TraverseType(canonical_type);
+ }
+}
+
+static clang::QualType ExportAllDeclaredTypes(
+ clang::ExternalASTMerger &merger,
+ clang::ASTContext &source, clang::FileManager &source_file_manager,
+ const clang::ExternalASTMerger::OriginMap &source_origin_map,
+ clang::FileID file, clang::QualType root) {
+ clang::ExternalASTMerger::ImporterSource importer_source =
+ { source, source_file_manager, source_origin_map };
+ merger.AddSources(importer_source);
+ clang::ASTImporter &exporter = merger.ImporterForOrigin(source);
+ CompleteAllDeclContexts(exporter, file, root);
+ clang::QualType ret = exporter.Import(root);
+ merger.RemoveSources(importer_source);
+ return ret;
+}
+
+TypeFromUser ClangExpressionDeclMap::DeportType(ClangASTContext &target,
+ ClangASTContext &source,
+ TypeFromParser parser_type) {
+ assert (&target == m_target->GetScratchClangASTContext());
+ assert ((TypeSystem*)&source == parser_type.GetTypeSystem());
+ assert (source.getASTContext() == m_ast_context);
+
+ if (m_ast_importer_sp) {
+ return TypeFromUser(m_ast_importer_sp->DeportType(
+ target.getASTContext(), source.getASTContext(),
+ parser_type.GetOpaqueQualType()),
+ &target);
+ } else if (m_merger_up) {
+ clang::FileID source_file =
+ source.getASTContext()->getSourceManager().getFileID(
+ source.getASTContext()->getTranslationUnitDecl()->getLocation());
+ auto scratch_ast_context = static_cast<ClangASTContextForExpressions*>(
+ m_target->GetScratchClangASTContext());
+ clang::QualType exported_type = ExportAllDeclaredTypes(
+ scratch_ast_context->GetMergerUnchecked(),
+ *source.getASTContext(), *source.getFileManager(),
+ m_merger_up->GetOrigins(),
+ source_file,
+ clang::QualType::getFromOpaquePtr(parser_type.GetOpaqueQualType()));
+ return TypeFromUser(exported_type.getAsOpaquePtr(), &target);
+ } else {
+ lldbassert(0 && "No mechanism for deporting a type!");
+ return TypeFromUser();
+ }
+}
+
bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
const ConstString &name,
TypeFromParser parser_type,
@@ -198,12 +328,8 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
if (target == nullptr)
return false;
- ClangASTContext *context(target->GetScratchClangASTContext());
-
- TypeFromUser user_type(m_ast_importer_sp->DeportType(
- context->getASTContext(), ast->getASTContext(),
- parser_type.GetOpaqueQualType()),
- context);
+ TypeFromUser user_type =
+ DeportType(*target->GetScratchClangASTContext(), *ast, parser_type);
uint32_t offset = m_parser_vars->m_materializer->AddResultVariable(
user_type, is_lvalue, m_keep_result_in_memory, m_result_delegate, err);
@@ -240,10 +366,7 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
ClangASTContext *context(target->GetScratchClangASTContext());
- TypeFromUser user_type(m_ast_importer_sp->DeportType(
- context->getASTContext(), ast->getASTContext(),
- parser_type.GetOpaqueQualType()),
- context);
+ TypeFromUser user_type = DeportType(*context, *ast, parser_type);
if (!user_type.GetOpaqueQualType()) {
if (log)
@@ -688,16 +811,18 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
}
ClangASTImporter::NamespaceMapSP namespace_map =
- m_ast_importer_sp->GetNamespaceMap(namespace_context);
+ m_ast_importer_sp
+ ? m_ast_importer_sp->GetNamespaceMap(namespace_context)
+ : ClangASTImporter::NamespaceMapSP();
+
+ if (!namespace_map)
+ return;
if (log && log->GetVerbose())
log->Printf(" CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries)",
current_id, static_cast<void *>(namespace_map.get()),
(int)namespace_map->size());
-
- if (!namespace_map)
- return;
-
+
for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
e = namespace_map->end();
i != e; ++i) {
@@ -739,16 +864,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
SymbolContextList sc_list;
const ConstString name(context.m_decl_name.getAsString().c_str());
-
- const char *name_unique_cstr = name.GetCString();
-
- if (name_unique_cstr == NULL)
- return;
-
- static ConstString id_name("id");
- static ConstString Class_name("Class");
-
- if (name == id_name || name == Class_name)
+ if (IgnoreName(name, false))
return;
// Only look for functions by name out in our symbols if the function
@@ -784,8 +900,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
if (!persistent_decl)
break;
- Decl *parser_persistent_decl = m_ast_importer_sp->CopyDecl(
- m_ast_context, scratch_ast_context, persistent_decl);
+ Decl *parser_persistent_decl = CopyDecl(persistent_decl);
if (!parser_persistent_decl)
break;
@@ -809,7 +924,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
} while (0);
}
- if (name_unique_cstr[0] == '$' && !namespace_decl) {
+ if (name.GetCString()[0] == '$' && !namespace_decl) {
static ConstString g_lldb_class_name("$__lldb_class");
if (name == g_lldb_class_name) {
@@ -1041,7 +1156,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
if (ast) {
clang::NamespaceDecl *namespace_decl =
ClangASTContext::GetUniqueNamespaceDeclaration(
- m_ast_context, name_unique_cstr, nullptr);
+ m_ast_context, name.GetCString(), nullptr);
if (namespace_decl) {
context.AddNamedDecl(namespace_decl);
clang::DeclContext *clang_decl_ctx =
@@ -1056,7 +1171,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
}
// any other $__lldb names should be weeded out now
- if (!::strncmp(name_unique_cstr, "$__lldb", sizeof("$__lldb") - 1))
+ if (name.GetStringRef().startswith("$__lldb"))
return;
ExpressionVariableSP pvar_sp(
@@ -1329,8 +1444,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
for (clang::NamedDecl *decl : decls_from_modules) {
if (llvm::isa<clang::FunctionDecl>(decl)) {
clang::NamedDecl *copied_decl =
- llvm::cast_or_null<FunctionDecl>(m_ast_importer_sp->CopyDecl(
- m_ast_context, &decl->getASTContext(), decl));
+ llvm::cast_or_null<FunctionDecl>(CopyDecl(decl));
if (copied_decl) {
context.AddNamedDecl(copied_decl);
context.m_found.function_with_type_info = true;
@@ -1372,9 +1486,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
current_id, name.GetCString());
}
- clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
- m_ast_context, &decl_from_modules->getASTContext(),
- decl_from_modules);
+ clang::Decl *copied_decl = CopyDecl(decl_from_modules);
clang::FunctionDecl *copied_function_decl =
copied_decl ? dyn_cast<clang::FunctionDecl>(copied_decl)
: nullptr;
@@ -1401,9 +1513,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
current_id, name.GetCString());
}
- clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
- m_ast_context, &decl_from_modules->getASTContext(),
- decl_from_modules);
+ clang::Decl *copied_decl = CopyDecl(decl_from_modules);
clang::VarDecl *copied_var_decl =
copied_decl ? dyn_cast_or_null<clang::VarDecl>(copied_decl)
: nullptr;
@@ -1430,17 +1540,17 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
// a generic
// data symbol, and -- if it is found -- treat it as a variable.
Status error;
-
+
const Symbol *data_symbol =
m_parser_vars->m_sym_ctx.FindBestGlobalDataSymbol(name, error);
-
+
if (!error.Success()) {
const unsigned diag_id =
m_ast_context->getDiagnostics().getCustomDiagID(
clang::DiagnosticsEngine::Level::Error, "%0");
m_ast_context->getDiagnostics().Report(diag_id) << error.AsCString();
}
-
+
if (data_symbol) {
std::string warning("got name from symbols: ");
warning.append(name.AsCString());
@@ -1455,49 +1565,6 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
}
}
-// static opaque_compiler_type_t
-// MaybePromoteToBlockPointerType
-//(
-// ASTContext *ast_context,
-// opaque_compiler_type_t candidate_type
-//)
-//{
-// if (!candidate_type)
-// return candidate_type;
-//
-// QualType candidate_qual_type = QualType::getFromOpaquePtr(candidate_type);
-//
-// const PointerType *candidate_pointer_type =
-// dyn_cast<PointerType>(candidate_qual_type);
-//
-// if (!candidate_pointer_type)
-// return candidate_type;
-//
-// QualType pointee_qual_type = candidate_pointer_type->getPointeeType();
-//
-// const RecordType *pointee_record_type =
-// dyn_cast<RecordType>(pointee_qual_type);
-//
-// if (!pointee_record_type)
-// return candidate_type;
-//
-// RecordDecl *pointee_record_decl = pointee_record_type->getDecl();
-//
-// if (!pointee_record_decl->isRecord())
-// return candidate_type;
-//
-// if
-// (!pointee_record_decl->getName().startswith(llvm::StringRef("__block_literal_")))
-// return candidate_type;
-//
-// QualType generic_function_type =
-// ast_context->getFunctionNoProtoType(ast_context->UnknownAnyTy);
-// QualType block_pointer_type =
-// ast_context->getBlockPointerType(generic_function_type);
-//
-// return block_pointer_type.getAsOpaquePtr();
-//}
-
bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
lldb_private::Value &var_location,
TypeFromUser *user_type,
@@ -1537,7 +1604,6 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
"There is no AST context for the current execution context");
return false;
}
- // var_clang_type = MaybePromoteToBlockPointerType (ast, var_clang_type);
DWARFExpression &var_location_expr = var->LocationExpression();
@@ -1762,7 +1828,9 @@ bool ClangExpressionDeclMap::ResolveUnknownTypes() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
- ClangASTContext *scratch_ast_context = target->GetScratchClangASTContext();
+ ClangASTContextForExpressions *scratch_ast_context =
+ static_cast<ClangASTContextForExpressions*>(
+ target->GetScratchClangASTContext());
for (size_t index = 0, num_entities = m_found_entities.GetSize();
index < num_entities; ++index) {
@@ -1793,9 +1861,20 @@ bool ClangExpressionDeclMap::ResolveUnknownTypes() {
var_type.getAsOpaquePtr(),
ClangASTContext::GetASTContext(&var_decl->getASTContext()));
- lldb::opaque_compiler_type_t copied_type = m_ast_importer_sp->CopyType(
- scratch_ast_context->getASTContext(), &var_decl->getASTContext(),
- var_type.getAsOpaquePtr());
+ lldb::opaque_compiler_type_t copied_type = 0;
+ if (m_ast_importer_sp) {
+ copied_type = m_ast_importer_sp->CopyType(
+ scratch_ast_context->getASTContext(), &var_decl->getASTContext(),
+ var_type.getAsOpaquePtr());
+ } else if (HasMerger()) {
+ copied_type = CopyTypeWithMerger(
+ var_decl->getASTContext(),
+ scratch_ast_context->GetMergerUnchecked(),
+ var_type).getAsOpaquePtr();
+ } else {
+ lldbassert(0 && "No mechanism to copy a resolved unknown type!");
+ return false;
+ }
if (!copied_type) {
if (log)
@@ -1892,8 +1971,7 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
if (!extern_c) {
TypeSystem *type_system = function->GetDeclContext().GetTypeSystem();
- if (ClangASTContext *src_ast =
- llvm::dyn_cast<ClangASTContext>(type_system)) {
+ if (llvm::isa<ClangASTContext>(type_system)) {
clang::DeclContext *src_decl_context =
(clang::DeclContext *)function->GetDeclContext()
.GetOpaqueDeclContext();
@@ -1905,9 +1983,7 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
src_function_decl->getTemplateSpecializationInfo()->getTemplate();
clang::FunctionTemplateDecl *copied_function_template =
llvm::dyn_cast_or_null<clang::FunctionTemplateDecl>(
- m_ast_importer_sp->CopyDecl(m_ast_context,
- src_ast->getASTContext(),
- function_template));
+ CopyDecl(function_template));
if (copied_function_template) {
if (log) {
ASTDumper ast_dumper((clang::Decl *)copied_function_template);
@@ -1928,9 +2004,7 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
} else if (src_function_decl) {
if (clang::FunctionDecl *copied_function_decl =
llvm::dyn_cast_or_null<clang::FunctionDecl>(
- m_ast_importer_sp->CopyDecl(m_ast_context,
- src_ast->getASTContext(),
- src_function_decl))) {
+ CopyDecl(src_function_decl))) {
if (log) {
ASTDumper ast_dumper((clang::Decl *)copied_function_decl);
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
index e8a9ba6862db7..d163ad4f7e29a 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
@@ -613,6 +613,23 @@ private:
void AddThisType(NameSearchContext &context, TypeFromUser &type,
unsigned int current_id);
+ //------------------------------------------------------------------
+ /// Move a type out of the current ASTContext into another, but make sure to
+ /// export all components of the type also.
+ ///
+ /// @param[in] target
+ /// The ClangASTContext to move to.
+ /// @param[in] source
+ /// The ClangASTContext to move from. This is assumed to be going away.
+ /// @param[in] parser_type
+ /// The type as it appears in the source context.
+ ///
+ /// @return
+ /// Returns the moved type, or an empty type if there was a problem.
+ //------------------------------------------------------------------
+ TypeFromUser DeportType(ClangASTContext &target, ClangASTContext &source,
+ TypeFromParser parser_type);
+
ClangASTContext *GetClangASTContext();
};
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 4e20be79f68b7..d9e53074b3fbc 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -66,7 +66,6 @@
#include "ClangPersistentVariables.h"
#include "IRForTarget.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Module.h"
@@ -351,7 +350,6 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope,
LLDB_LOGV(log, "LinkerVersion: '{0}'", opts.LinkerVersion);
StringList::LogDump(log, opts.FeaturesAsWritten, "FeaturesAsWritten");
StringList::LogDump(log, opts.Features, "Features");
- StringList::LogDump(log, opts.Reciprocals, "Reciprocals");
}
// 4. Create and install the target on the compiler.
@@ -391,6 +389,14 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope,
// FIXME: the following language option is a temporary workaround,
// to "ask for ObjC, get ObjC++" (see comment above).
m_compiler->getLangOpts().CPlusPlus = true;
+
+ // 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.
+ m_compiler->getLangOpts().CPlusPlus11 = true;
break;
case lldb::eLanguageTypeC_plus_plus:
case lldb::eLanguageTypeC_plus_plus_11:
@@ -526,7 +532,7 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope,
if (decl_map) {
llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source(
decl_map->CreateProxy());
- decl_map->InstallASTContext(ast_context.get());
+ decl_map->InstallASTContext(*ast_context, m_compiler->getFileManager());
ast_context->setExternalSource(ast_source);
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
index 3e6a109a4af38..41f290f2e127c 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
@@ -10,10 +10,10 @@
#ifndef liblldb_ClangExpressionParser_h_
#define liblldb_ClangExpressionParser_h_
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/ExpressionParser.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-public.h"
diff --git a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
index 56d1d8412f786..0596d8fde7b9e 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
@@ -17,7 +17,6 @@
#include "ClangExpressionHelper.h"
#include "lldb/Core/Address.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectList.h"
diff --git a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
index bce0eaf6d57e4..b42ceb9afee89 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
@@ -85,6 +85,7 @@ public:
void ForEachMacro(const ModuleVector &modules,
std::function<bool(const std::string &)> handler) override;
+ clang::ExternalASTMerger::ImporterSource GetImporterSource() override;
private:
void
ReportModuleExportsHelper(std::set<ClangModulesDeclVendor::ModuleID> &exports,
@@ -109,6 +110,7 @@ private:
typedef std::set<ModuleID> ImportedModuleSet;
ImportedModuleMap m_imported_modules;
ImportedModuleSet m_user_imported_modules;
+ const clang::ExternalASTMerger::OriginMap m_origin_map;
};
} // anonymous namespace
@@ -548,6 +550,12 @@ ClangModulesDeclVendorImpl::DoGetModule(clang::ModuleIdPath path,
is_inclusion_directive);
}
+clang::ExternalASTMerger::ImporterSource
+ClangModulesDeclVendorImpl::GetImporterSource() {
+ return {m_compiler_instance->getASTContext(),
+ m_compiler_instance->getFileManager(), m_origin_map};
+}
+
static const char *ModuleImportBufferName = "LLDBModulesMemoryBuffer";
lldb_private::ClangModulesDeclVendor *
diff --git a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
index fbabcd736865a..23769ccfb0c04 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
@@ -10,7 +10,6 @@
#ifndef liblldb_ClangModulesDeclVendor_h
#define liblldb_ClangModulesDeclVendor_h
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Symbol/DeclVendor.h"
#include "lldb/Target/Platform.h"
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
index 2a6261a6df4d4..18fe8b49227bd 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
@@ -347,7 +347,6 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
//
ApplyObjcCastHack(m_expr_text);
- // ApplyUnicharHack(m_expr_text);
std::string prefix = m_expr_prefix;
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
index 065e5db4c9f84..0f2aeef27e571 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
@@ -138,15 +138,6 @@ bool ClangUtilityFunction::Install(DiagnosticManager &diagnostic_manager,
}
}
-#if 0
- // jingham: look here
- StreamFile logfile ("/tmp/exprs.txt", "a");
- logfile.Printf ("0x%16.16" PRIx64 ": func = %s, source =\n%s\n",
- m_jit_start_addr,
- m_function_name.c_str(),
- m_function_text.c_str());
-#endif
-
DeclMap()->DidParse();
ResetDeclMap();
diff --git a/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
index d0ef688f07735..262a7914d249d 100644
--- a/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
+++ b/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
@@ -12,12 +12,12 @@
#include "EmulateInstructionARM.h"
#include "EmulationStateARM.h"
#include "lldb/Core/Address.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Host/PosixApi.h"
#include "lldb/Interpreter/OptionValueArray.h"
#include "lldb/Interpreter/OptionValueDictionary.h"
#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Stream.h"
diff --git a/source/Plugins/Instruction/ARM/EmulationStateARM.cpp b/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
index 5e90965c18812..d1032f56f31cf 100644
--- a/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
+++ b/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
@@ -203,7 +203,8 @@ size_t EmulationStateARM::WritePseudoMemory(
uint32_t value1;
uint32_t value2;
memcpy (&value1, dst, sizeof (uint32_t));
- memcpy (&value2, (uint8_t *) dst + sizeof (uint32_t), sizeof (uint32_t));
+ memcpy(&value2, static_cast<const uint8_t *>(dst) + sizeof(uint32_t),
+ sizeof(uint32_t));
if (endian::InlHostByteOrder() == lldb::eByteOrderBig) {
value1 = llvm::ByteSwap_32(value1);
value2 = llvm::ByteSwap_32(value2);
diff --git a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
index 54dd237eb4b73..d882108c25f41 100644
--- a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
+++ b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
@@ -12,10 +12,10 @@
#include <stdlib.h>
#include "lldb/Core/Address.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Stream.h"
@@ -167,10 +167,7 @@ EmulateInstructionARM64::CreateInstance(const ArchSpec &arch,
if (EmulateInstructionARM64::SupportsEmulatingInstructionsOfTypeStatic(
inst_type)) {
if (arch.GetTriple().getArch() == llvm::Triple::aarch64) {
- std::auto_ptr<EmulateInstructionARM64> emulate_insn_ap(
- new EmulateInstructionARM64(arch));
- if (emulate_insn_ap.get())
- return emulate_insn_ap.release();
+ return new EmulateInstructionARM64(arch);
}
}
diff --git a/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp b/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
index 4d1d89abb1d0f..db3d8fc1b8ca2 100644
--- a/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
+++ b/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
@@ -12,12 +12,12 @@
#include <stdlib.h>
#include "lldb/Core/Address.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Opcode.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Stream.h"
@@ -212,10 +212,7 @@ EmulateInstructionMIPS::CreateInstance(const ArchSpec &arch,
inst_type)) {
if (arch.GetTriple().getArch() == llvm::Triple::mips ||
arch.GetTriple().getArch() == llvm::Triple::mipsel) {
- std::auto_ptr<EmulateInstructionMIPS> emulate_insn_ap(
- new EmulateInstructionMIPS(arch));
- if (emulate_insn_ap.get())
- return emulate_insn_ap.release();
+ return new EmulateInstructionMIPS(arch);
}
}
diff --git a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
index 1e6d98756958b..d298589afdd9e 100644
--- a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
+++ b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
@@ -12,12 +12,12 @@
#include <stdlib.h>
#include "lldb/Core/Address.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Opcode.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Host/PosixApi.h"
#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Stream.h"
@@ -199,10 +199,7 @@ EmulateInstructionMIPS64::CreateInstance(const ArchSpec &arch,
inst_type)) {
if (arch.GetTriple().getArch() == llvm::Triple::mips64 ||
arch.GetTriple().getArch() == llvm::Triple::mips64el) {
- std::auto_ptr<EmulateInstructionMIPS64> emulate_insn_ap(
- new EmulateInstructionMIPS64(arch));
- if (emulate_insn_ap.get())
- return emulate_insn_ap.release();
+ return new EmulateInstructionMIPS64(arch);
}
}
@@ -801,7 +798,9 @@ EmulateInstructionMIPS64::GetOpcodeForInstruction(const char *op_name) {
// Branch instructions
//----------------------------------------------------------------------
{"BEQ", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BEQ rs,rt,offset"},
+ {"BEQ64", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BEQ rs,rt,offset"},
{"BNE", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BNE rs,rt,offset"},
+ {"BNE64", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BNE rs,rt,offset"},
{"BEQL", &EmulateInstructionMIPS64::Emulate_BXX_3ops,
"BEQL rs,rt,offset"},
{"BNEL", &EmulateInstructionMIPS64::Emulate_BXX_3ops,
@@ -814,6 +813,7 @@ EmulateInstructionMIPS64::GetOpcodeForInstruction(const char *op_name) {
{"BALC", &EmulateInstructionMIPS64::Emulate_BALC, "BALC offset"},
{"BC", &EmulateInstructionMIPS64::Emulate_BC, "BC offset"},
{"BGEZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZ rs,offset"},
+ {"BGEZ64", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZ rs,offset"},
{"BLEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
"BLEZALC rs,offset"},
{"BGEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
@@ -828,34 +828,61 @@ EmulateInstructionMIPS64::GetOpcodeForInstruction(const char *op_name) {
"BNEZALC rs,offset"},
{"BEQC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
"BEQC rs,rt,offset"},
+ {"BEQC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
+ "BEQC rs,rt,offset"},
{"BNEC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
"BNEC rs,rt,offset"},
+ {"BNEC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
+ "BNEC rs,rt,offset"},
{"BLTC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
"BLTC rs,rt,offset"},
+ {"BLTC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
+ "BLTC rs,rt,offset"},
{"BGEC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
"BGEC rs,rt,offset"},
+ {"BGEC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
+ "BGEC rs,rt,offset"},
{"BLTUC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
"BLTUC rs,rt,offset"},
+ {"BLTUC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
+ "BLTUC rs,rt,offset"},
{"BGEUC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
"BGEUC rs,rt,offset"},
+ {"BGEUC64", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
+ "BGEUC rs,rt,offset"},
{"BLTZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
"BLTZC rt,offset"},
+ {"BLTZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
+ "BLTZC rt,offset"},
{"BLEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
"BLEZC rt,offset"},
+ {"BLEZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
+ "BLEZC rt,offset"},
{"BGEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
"BGEZC rt,offset"},
+ {"BGEZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
+ "BGEZC rt,offset"},
{"BGTZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
"BGTZC rt,offset"},
+ {"BGTZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
+ "BGTZC rt,offset"},
{"BEQZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
"BEQZC rt,offset"},
+ {"BEQZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
+ "BEQZC rt,offset"},
{"BNEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
"BNEZC rt,offset"},
+ {"BNEZC64", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
+ "BNEZC rt,offset"},
{"BGEZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZL rt,offset"},
{"BGTZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZ rt,offset"},
+ {"BGTZ64", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZ rt,offset"},
{"BGTZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZL rt,offset"},
{"BLEZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZ rt,offset"},
+ {"BLEZ64", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZ rt,offset"},
{"BLEZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZL rt,offset"},
{"BLTZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLTZ rt,offset"},
+ {"BLTZ64", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLTZ rt,offset"},
{"BLTZAL", &EmulateInstructionMIPS64::Emulate_Bcond_Link,
"BLTZAL rt,offset"},
{"BLTZALL", &EmulateInstructionMIPS64::Emulate_Bcond_Link,
@@ -872,8 +899,11 @@ EmulateInstructionMIPS64::GetOpcodeForInstruction(const char *op_name) {
{"JALR64", &EmulateInstructionMIPS64::Emulate_JALR, "JALR target"},
{"JALR_HB", &EmulateInstructionMIPS64::Emulate_JALR, "JALR.HB target"},
{"JIALC", &EmulateInstructionMIPS64::Emulate_JIALC, "JIALC rt,offset"},
+ {"JIALC64", &EmulateInstructionMIPS64::Emulate_JIALC, "JIALC rt,offset"},
{"JIC", &EmulateInstructionMIPS64::Emulate_JIC, "JIC rt,offset"},
+ {"JIC64", &EmulateInstructionMIPS64::Emulate_JIC, "JIC rt,offset"},
{"JR", &EmulateInstructionMIPS64::Emulate_JR, "JR target"},
+ {"JR64", &EmulateInstructionMIPS64::Emulate_JR, "JR target"},
{"JR_HB", &EmulateInstructionMIPS64::Emulate_JR, "JR.HB target"},
{"BC1F", &EmulateInstructionMIPS64::Emulate_FP_branch, "BC1F cc, offset"},
{"BC1T", &EmulateInstructionMIPS64::Emulate_FP_branch, "BC1T cc, offset"},
@@ -1338,12 +1368,14 @@ bool EmulateInstructionMIPS64::Emulate_BXX_3ops(llvm::MCInst &insn) {
if (!success)
return false;
- if (!strcasecmp(op_name, "BEQ") || !strcasecmp(op_name, "BEQL")) {
+ if (!strcasecmp(op_name, "BEQ") || !strcasecmp(op_name, "BEQL")
+ || !strcasecmp(op_name, "BEQ64") ) {
if (rs_val == rt_val)
target = pc + offset;
else
target = pc + 8;
- } else if (!strcasecmp(op_name, "BNE") || !strcasecmp(op_name, "BNEL")) {
+ } else if (!strcasecmp(op_name, "BNE") || !strcasecmp(op_name, "BNEL")
+ || !strcasecmp(op_name, "BNE64")) {
if (rs_val != rt_val)
target = pc + offset;
else
@@ -1563,22 +1595,26 @@ bool EmulateInstructionMIPS64::Emulate_BXX_2ops(llvm::MCInst &insn) {
if (!success)
return false;
- if (!strcasecmp(op_name, "BLTZL") || !strcasecmp(op_name, "BLTZ")) {
+ if (!strcasecmp(op_name, "BLTZL") || !strcasecmp(op_name, "BLTZ")
+ || !strcasecmp(op_name, "BLTZ64")) {
if (rs_val < 0)
target = pc + offset;
else
target = pc + 8;
- } else if (!strcasecmp(op_name, "BGEZL") || !strcasecmp(op_name, "BGEZ")) {
+ } else if (!strcasecmp(op_name, "BGEZL") || !strcasecmp(op_name, "BGEZ")
+ || !strcasecmp(op_name, "BGEZ64")) {
if (rs_val >= 0)
target = pc + offset;
else
target = pc + 8;
- } else if (!strcasecmp(op_name, "BGTZL") || !strcasecmp(op_name, "BGTZ")) {
+ } else if (!strcasecmp(op_name, "BGTZL") || !strcasecmp(op_name, "BGTZ")
+ || !strcasecmp(op_name, "BGTZ64")) {
if (rs_val > 0)
target = pc + offset;
else
target = pc + 8;
- } else if (!strcasecmp(op_name, "BLEZL") || !strcasecmp(op_name, "BLEZ")) {
+ } else if (!strcasecmp(op_name, "BLEZL") || !strcasecmp(op_name, "BLEZ")
+ || !strcasecmp(op_name, "BLEZ64")) {
if (rs_val <= 0)
target = pc + offset;
else
@@ -1657,32 +1693,32 @@ bool EmulateInstructionMIPS64::Emulate_BXX_3ops_C(llvm::MCInst &insn) {
if (!success)
return false;
- if (!strcasecmp(op_name, "BEQC")) {
+ if (!strcasecmp(op_name, "BEQC") || !strcasecmp(op_name, "BEQC64")) {
if (rs_val == rt_val)
target = pc + offset;
else
target = pc + 4;
- } else if (!strcasecmp(op_name, "BNEC")) {
+ } else if (!strcasecmp(op_name, "BNEC") || !strcasecmp(op_name, "BNEC64")) {
if (rs_val != rt_val)
target = pc + offset;
else
target = pc + 4;
- } else if (!strcasecmp(op_name, "BLTC")) {
+ } else if (!strcasecmp(op_name, "BLTC") || !strcasecmp(op_name, "BLTC64")) {
if (rs_val < rt_val)
target = pc + offset;
else
target = pc + 4;
- } else if (!strcasecmp(op_name, "BGEC")) {
+ } else if (!strcasecmp(op_name, "BGEC64") || !strcasecmp(op_name, "BGEC")) {
if (rs_val >= rt_val)
target = pc + offset;
else
target = pc + 4;
- } else if (!strcasecmp(op_name, "BLTUC")) {
+ } else if (!strcasecmp(op_name, "BLTUC") || !strcasecmp(op_name, "BLTUC64")) {
if (rs_val < rt_val)
target = pc + offset;
else
target = pc + 4;
- } else if (!strcasecmp(op_name, "BGEUC")) {
+ } else if (!strcasecmp(op_name, "BGEUC") || !strcasecmp(op_name, "BGEUC64")) {
if ((uint32_t)rs_val >= (uint32_t)rt_val)
target = pc + offset;
else
@@ -1734,32 +1770,32 @@ bool EmulateInstructionMIPS64::Emulate_BXX_2ops_C(llvm::MCInst &insn) {
if (!success)
return false;
- if (!strcasecmp(op_name, "BLTZC")) {
+ if (!strcasecmp(op_name, "BLTZC") || !strcasecmp(op_name, "BLTZC64")) {
if (rs_val < 0)
target = pc + offset;
else
target = pc + 4;
- } else if (!strcasecmp(op_name, "BLEZC")) {
+ } else if (!strcasecmp(op_name, "BLEZC") || !strcasecmp(op_name, "BLEZC64")) {
if (rs_val <= 0)
target = pc + offset;
else
target = pc + 4;
- } else if (!strcasecmp(op_name, "BGEZC")) {
+ } else if (!strcasecmp(op_name, "BGEZC") || !strcasecmp(op_name, "BGEZC64")) {
if (rs_val >= 0)
target = pc + offset;
else
target = pc + 4;
- } else if (!strcasecmp(op_name, "BGTZC")) {
+ } else if (!strcasecmp(op_name, "BGTZC") || !strcasecmp(op_name, "BGTZC64")) {
if (rs_val > 0)
target = pc + offset;
else
target = pc + 4;
- } else if (!strcasecmp(op_name, "BEQZC")) {
+ } else if (!strcasecmp(op_name, "BEQZC") || !strcasecmp(op_name, "BEQZC64")) {
if (rs_val == 0)
target = pc + offset;
else
target = pc + 4;
- } else if (!strcasecmp(op_name, "BNEZC")) {
+ } else if (!strcasecmp(op_name, "BNEZC") || !strcasecmp(op_name, "BNEZC64")) {
if (rs_val != 0)
target = pc + offset;
else
diff --git a/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/source/Plugins/Language/CPlusPlus/CMakeLists.txt
index 8f769c499987f..180440a244a4a 100644
--- a/source/Plugins/Language/CPlusPlus/CMakeLists.txt
+++ b/source/Plugins/Language/CPlusPlus/CMakeLists.txt
@@ -5,9 +5,12 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN
CxxStringTypes.cpp
LibCxx.cpp
LibCxxAtomic.cpp
+ LibCxxBitset.cpp
LibCxxInitializerList.cpp
LibCxxList.cpp
LibCxxMap.cpp
+ LibCxxQueue.cpp
+ LibCxxTuple.cpp
LibCxxUnorderedMap.cpp
LibCxxVector.cpp
LibStdcpp.cpp
diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 1ae9418e4d9c0..51ed88065c84d 100644
--- a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -422,12 +422,24 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
AddCXXSynthetic(
cpp_category_sp,
+ lldb_private::formatters::LibcxxBitsetSyntheticFrontEndCreator,
+ "libc++ std::bitset synthetic children",
+ ConstString("^std::__(ndk)?1::bitset<.+>(( )?&)?$"), stl_synth_flags,
+ true);
+ AddCXXSynthetic(
+ cpp_category_sp,
lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator,
"libc++ std::vector synthetic children",
ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"), stl_synth_flags,
true);
AddCXXSynthetic(
cpp_category_sp,
+ lldb_private::formatters::LibcxxStdForwardListSyntheticFrontEndCreator,
+ "libc++ std::forward_list synthetic children",
+ ConstString("^std::__(ndk)?1::forward_list<.+>(( )?&)?$"),
+ stl_synth_flags, true);
+ AddCXXSynthetic(
+ cpp_category_sp,
lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator,
"libc++ std::list synthetic children",
ConstString("^std::__(ndk)?1::list<.+>(( )?&)?$"), stl_synth_flags, true);
@@ -467,6 +479,14 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"libc++ std::initializer_list synthetic children",
ConstString("^std::initializer_list<.+>(( )?&)?$"), stl_synth_flags,
true);
+ AddCXXSynthetic(cpp_category_sp, LibcxxQueueFrontEndCreator,
+ "libc++ std::queue synthetic children",
+ ConstString("^std::__(ndk)?1::queue<.+>(( )?&)?$"),
+ stl_synth_flags, true);
+ AddCXXSynthetic(cpp_category_sp, LibcxxTupleFrontEndCreator,
+ "libc++ std::tuple synthetic children",
+ ConstString("^std::__(ndk)?1::tuple<.*>(( )?&)?$"), stl_synth_flags,
+ true);
AddCXXSynthetic(
cpp_category_sp,
lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator,
@@ -497,12 +517,22 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
stl_summary_flags.SetSkipPointers(false);
AddCXXSummary(cpp_category_sp,
lldb_private::formatters::LibcxxContainerSummaryProvider,
+ "libc++ std::bitset summary provider",
+ ConstString("^std::__(ndk)?1::bitset<.+>(( )?&)?$"),
+ stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxContainerSummaryProvider,
"libc++ std::vector summary provider",
ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"),
stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
lldb_private::formatters::LibcxxContainerSummaryProvider,
"libc++ std::list summary provider",
+ ConstString("^std::__(ndk)?1::forward_list<.+>(( )?&)?$"),
+ stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxContainerSummaryProvider,
+ "libc++ std::list summary provider",
ConstString("^std::__(ndk)?1::list<.+>(( )?&)?$"),
stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
@@ -517,6 +547,11 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
lldb_private::formatters::LibcxxContainerSummaryProvider,
+ "libc++ std::queue summary provider",
+ ConstString("^std::__(ndk)?1::queue<.+>(( )?&)?$"),
+ stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxContainerSummaryProvider,
"libc++ std::set summary provider",
ConstString("^std::__(ndk)?1::set<.+>(( )?&)?$"),
stl_summary_flags, true);
@@ -535,6 +570,10 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"libc++ std::unordered containers summary provider",
ConstString("^(std::__(ndk)?1::)unordered_(multi)?(map|set)<.+> >$"),
stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp, LibcxxContainerSummaryProvider,
+ "libc++ std::tuple summary provider",
+ ConstString("^std::__(ndk)?1::tuple<.*>(( )?&)?$"), stl_summary_flags,
+ true);
AddCXXSummary(
cpp_category_sp, lldb_private::formatters::LibCxxAtomicSummaryProvider,
"libc++ std::atomic summary provider",
diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp b/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp
index 88bdd68ff3011..aebea6ae3569b 100644
--- a/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp
+++ b/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp
@@ -628,7 +628,7 @@ static const clang::LangOptions &GetLangOptions() {
g_options.CPlusPlus = true;
g_options.CPlusPlus11 = true;
g_options.CPlusPlus14 = true;
- g_options.CPlusPlus1z = true;
+ g_options.CPlusPlus17 = true;
});
return g_options;
}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index 11245e1310b77..f6d1f18cb596b 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -153,12 +153,11 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() {
.get();
if (m_pair_ptr) {
auto __i_(valobj_sp->GetChildMemberWithName(g___i_, true));
- lldb::TemplateArgumentKind kind;
if (!__i_) {
m_pair_ptr = nullptr;
return false;
}
- CompilerType pair_type(__i_->GetCompilerType().GetTemplateArgument(0, kind));
+ CompilerType pair_type(__i_->GetCompilerType().GetTypeTemplateArgument(0));
std::string name; uint64_t bit_offset_ptr; uint32_t bitfield_bit_size_ptr; bool is_bitfield_ptr;
pair_type = pair_type.GetFieldAtIndex(0, name, &bit_offset_ptr, &bitfield_bit_size_ptr, &is_bitfield_ptr);
if (!pair_type) {
diff --git a/source/Plugins/Language/CPlusPlus/LibCxx.h b/source/Plugins/Language/CPlusPlus/LibCxx.h
index 7610212b4245a..3f6e0d6e14d7f 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxx.h
+++ b/source/Plugins/Language/CPlusPlus/LibCxx.h
@@ -93,6 +93,10 @@ private:
};
SyntheticChildrenFrontEnd *
+LibcxxBitsetSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+SyntheticChildrenFrontEnd *
LibcxxSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
@@ -105,6 +109,10 @@ LibcxxStdListSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
SyntheticChildrenFrontEnd *
+LibcxxStdForwardListSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+SyntheticChildrenFrontEnd *
LibcxxStdMapSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
@@ -119,6 +127,12 @@ LibcxxInitializerListSyntheticFrontEndCreator(CXXSyntheticChildren *,
SyntheticChildrenFrontEnd *LibcxxFunctionFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
+SyntheticChildrenFrontEnd *LibcxxQueueFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+SyntheticChildrenFrontEnd *LibcxxTupleFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
} // namespace formatters
} // namespace lldb_private
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp b/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
new file mode 100644
index 0000000000000..0cdb0b26cf3bd
--- /dev/null
+++ b/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
@@ -0,0 +1,107 @@
+//===-- LibCxxBitset.cpp ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LibCxx.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace {
+
+class BitsetFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ BitsetFrontEnd(ValueObject &valobj);
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override {
+ return formatters::ExtractIndexFromString(name.GetCString());
+ }
+
+ bool MightHaveChildren() override { return true; }
+ bool Update() override;
+ size_t CalculateNumChildren() override { return m_elements.size(); }
+ ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+private:
+ std::vector<ValueObjectSP> m_elements;
+ ValueObjectSP m_first;
+ CompilerType m_bool_type;
+ ByteOrder m_byte_order = eByteOrderInvalid;
+ uint8_t m_byte_size = 0;
+};
+} // namespace
+
+BitsetFrontEnd::BitsetFrontEnd(ValueObject &valobj)
+ : SyntheticChildrenFrontEnd(valobj) {
+ m_bool_type = valobj.GetCompilerType().GetBasicTypeFromAST(eBasicTypeBool);
+ if (auto target_sp = m_backend.GetTargetSP()) {
+ m_byte_order = target_sp->GetArchitecture().GetByteOrder();
+ m_byte_size = target_sp->GetArchitecture().GetAddressByteSize();
+ Update();
+ }
+}
+
+bool BitsetFrontEnd::Update() {
+ m_elements.clear();
+ m_first.reset();
+
+ TargetSP target_sp = m_backend.GetTargetSP();
+ if (!target_sp)
+ return false;
+ size_t capping_size = target_sp->GetMaximumNumberOfChildrenToDisplay();
+
+ size_t size = 0;
+ if (auto arg = m_backend.GetCompilerType().GetIntegralTemplateArgument(0))
+ size = arg->value.getLimitedValue(capping_size);
+
+ m_elements.assign(size, ValueObjectSP());
+
+ m_first = m_backend.GetChildMemberWithName(ConstString("__first_"), true);
+ return false;
+}
+
+ValueObjectSP BitsetFrontEnd::GetChildAtIndex(size_t idx) {
+ if (idx >= m_elements.size() || !m_first)
+ return ValueObjectSP();
+
+ if (m_elements[idx])
+ return m_elements[idx];
+
+ ExecutionContext ctx = m_backend.GetExecutionContextRef().Lock(false);
+ CompilerType type;
+ ValueObjectSP chunk;
+ // For small bitsets __first_ is not an array, but a plain size_t.
+ if (m_first->GetCompilerType().IsArrayType(&type, nullptr, nullptr))
+ chunk = m_first->GetChildAtIndex(
+ idx / type.GetBitSize(ctx.GetBestExecutionContextScope()), true);
+ else {
+ type = m_first->GetCompilerType();
+ chunk = m_first;
+ }
+ if (!type || !chunk)
+ return ValueObjectSP();
+
+ size_t chunk_idx = idx % type.GetBitSize(ctx.GetBestExecutionContextScope());
+ uint8_t value = !!(chunk->GetValueAsUnsigned(0) & (uint64_t(1) << chunk_idx));
+ DataExtractor data(&value, sizeof(value), m_byte_order, m_byte_size);
+
+ m_elements[idx] = CreateValueObjectFromData(llvm::formatv("[{0}]", idx).str(),
+ data, ctx, m_bool_type);
+
+ return m_elements[idx];
+}
+
+SyntheticChildrenFrontEnd *formatters::LibcxxBitsetSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ if (valobj_sp)
+ return new BitsetFrontEnd(*valobj_sp);
+ return nullptr;
+}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp b/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp
index 4e839532afb79..5823f6f3e0382 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp
@@ -94,9 +94,8 @@ bool lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::
m_start = nullptr;
m_num_elements = 0;
- lldb::TemplateArgumentKind kind;
- m_element_type = m_backend.GetCompilerType().GetTemplateArgument(0, kind);
- if (kind != lldb::eTemplateArgumentKindType || !m_element_type.IsValid())
+ m_element_type = m_backend.GetCompilerType().GetTypeTemplateArgument(0);
+ if (!m_element_type.IsValid())
return false;
m_element_size = m_element_type.GetByteSize(nullptr);
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxList.cpp b/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
index 56d8edaba72ac..6407ae129ad7d 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
@@ -114,58 +114,90 @@ private:
ListEntry m_entry;
};
-} // end anonymous namespace
-
-namespace lldb_private {
-namespace formatters {
-class LibcxxStdListSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+class AbstractListFrontEnd : public SyntheticChildrenFrontEnd {
public:
- LibcxxStdListSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+ size_t GetIndexOfChildWithName(const ConstString &name) override {
+ return ExtractIndexFromString(name.GetCString());
+ }
+ bool MightHaveChildren() override { return true; }
+ bool Update() override;
- ~LibcxxStdListSyntheticFrontEnd() override = default;
+protected:
+ AbstractListFrontEnd(ValueObject &valobj)
+ : SyntheticChildrenFrontEnd(valobj) {}
- size_t CalculateNumChildren() override;
+ size_t m_count;
+ ValueObject *m_head;
- lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+ static constexpr bool g_use_loop_detect = true;
+ size_t m_loop_detected; // The number of elements that have had loop detection
+ // run over them.
+ ListEntry m_slow_runner; // Used for loop detection
+ ListEntry m_fast_runner; // Used for loop detection
+
+ size_t m_list_capping_size;
+ CompilerType m_element_type;
+ std::map<size_t, ListIterator> m_iterators;
+
+ bool HasLoop(size_t count);
+ ValueObjectSP GetItem(size_t idx);
+};
+class ForwardListFrontEnd : public AbstractListFrontEnd {
+public:
+ ForwardListFrontEnd(ValueObject &valobj);
+
+ size_t CalculateNumChildren() override;
+ ValueObjectSP GetChildAtIndex(size_t idx) override;
bool Update() override;
+};
- bool MightHaveChildren() override;
+class ListFrontEnd : public AbstractListFrontEnd {
+public:
+ ListFrontEnd(lldb::ValueObjectSP valobj_sp);
- size_t GetIndexOfChildWithName(const ConstString &name) override;
+ ~ListFrontEnd() override = default;
-private:
- bool HasLoop(size_t count);
+ size_t CalculateNumChildren() override;
- size_t m_list_capping_size;
- static const bool g_use_loop_detect = true;
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
- size_t m_loop_detected; // The number of elements that have had loop detection
- // run over them.
- ListEntry m_slow_runner; // Used for loop detection
- ListEntry m_fast_runner; // Used for loop detection
+ bool Update() override;
+private:
lldb::addr_t m_node_address;
- ValueObject *m_head;
ValueObject *m_tail;
- CompilerType m_element_type;
- size_t m_count;
- std::map<size_t, ListIterator> m_iterators;
};
-} // namespace formatters
-} // namespace lldb_private
-
-lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::
- LibcxxStdListSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
- : SyntheticChildrenFrontEnd(*valobj_sp), m_list_capping_size(0),
- m_loop_detected(0), m_node_address(), m_head(nullptr), m_tail(nullptr),
- m_element_type(), m_count(UINT32_MAX), m_iterators() {
- if (valobj_sp)
- Update();
+
+} // end anonymous namespace
+
+bool AbstractListFrontEnd::Update() {
+ m_loop_detected = 0;
+ m_count = UINT32_MAX;
+ m_head = nullptr;
+ m_list_capping_size = 0;
+ m_slow_runner.SetEntry(nullptr);
+ m_fast_runner.SetEntry(nullptr);
+ m_iterators.clear();
+
+ if (m_backend.GetTargetSP())
+ m_list_capping_size =
+ m_backend.GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
+ if (m_list_capping_size == 0)
+ m_list_capping_size = 255;
+
+ CompilerType list_type = m_backend.GetCompilerType();
+ if (list_type.IsReferenceType())
+ list_type = list_type.GetNonReferenceType();
+
+ if (list_type.GetNumTemplateArguments() == 0)
+ return false;
+ m_element_type = list_type.GetTypeTemplateArgument(0);
+
+ return false;
}
-bool lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::HasLoop(
- size_t count) {
+bool AbstractListFrontEnd::HasLoop(size_t count) {
if (!g_use_loop_detect)
return false;
// don't bother checking for a loop if we won't actually need to jump nodes
@@ -201,8 +233,105 @@ bool lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::HasLoop(
return m_slow_runner == m_fast_runner;
}
-size_t lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::
- CalculateNumChildren() {
+ValueObjectSP AbstractListFrontEnd::GetItem(size_t idx) {
+ size_t advance = idx;
+ ListIterator current(m_head);
+ if (idx > 0) {
+ auto cached_iterator = m_iterators.find(idx - 1);
+ if (cached_iterator != m_iterators.end()) {
+ current = cached_iterator->second;
+ advance = 1;
+ }
+ }
+ ValueObjectSP value_sp = current.advance(advance);
+ m_iterators[idx] = current;
+ return value_sp;
+}
+
+ForwardListFrontEnd::ForwardListFrontEnd(ValueObject &valobj)
+ : AbstractListFrontEnd(valobj) {
+ Update();
+}
+
+size_t ForwardListFrontEnd::CalculateNumChildren() {
+ if (m_count != UINT32_MAX)
+ return m_count;
+
+ ListEntry current(m_head);
+ m_count = 0;
+ while (current && m_count < m_list_capping_size) {
+ ++m_count;
+ current = current.next();
+ }
+ return m_count;
+}
+
+ValueObjectSP ForwardListFrontEnd::GetChildAtIndex(size_t idx) {
+ if (idx >= CalculateNumChildren())
+ return nullptr;
+
+ if (!m_head)
+ return nullptr;
+
+ if (HasLoop(idx + 1))
+ return nullptr;
+
+ ValueObjectSP current_sp = GetItem(idx);
+ if (!current_sp)
+ return nullptr;
+
+ current_sp = current_sp->GetChildAtIndex(1, true); // get the __value_ child
+ if (!current_sp)
+ return nullptr;
+
+ // we need to copy current_sp into a new object otherwise we will end up with
+ // all items named __value_
+ DataExtractor data;
+ Status error;
+ current_sp->GetData(data, error);
+ if (error.Fail())
+ return nullptr;
+
+ return CreateValueObjectFromData(llvm::formatv("[{0}]", idx).str(), data,
+ m_backend.GetExecutionContextRef(),
+ m_element_type);
+}
+
+static ValueObjectSP GetValueOfCompressedPair(ValueObject &pair) {
+ ValueObjectSP value = pair.GetChildMemberWithName(ConstString("__value_"), true);
+ if (! value) {
+ // pre-r300140 member name
+ value = pair.GetChildMemberWithName(ConstString("__first_"), true);
+ }
+ return value;
+}
+
+bool ForwardListFrontEnd::Update() {
+ AbstractListFrontEnd::Update();
+
+ Status err;
+ ValueObjectSP backend_addr(m_backend.AddressOf(err));
+ if (err.Fail() || !backend_addr)
+ return false;
+
+ ValueObjectSP impl_sp(
+ m_backend.GetChildMemberWithName(ConstString("__before_begin_"), true));
+ if (!impl_sp)
+ return false;
+ impl_sp = GetValueOfCompressedPair(*impl_sp);
+ if (!impl_sp)
+ return false;
+ m_head = impl_sp->GetChildMemberWithName(ConstString("__next_"), true).get();
+ return false;
+}
+
+ListFrontEnd::ListFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : AbstractListFrontEnd(*valobj_sp), m_node_address(), m_tail(nullptr) {
+ if (valobj_sp)
+ Update();
+}
+
+size_t ListFrontEnd::CalculateNumChildren() {
if (m_count != UINT32_MAX)
return m_count;
if (!m_head || !m_tail || m_node_address == 0)
@@ -210,10 +339,9 @@ size_t lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::
ValueObjectSP size_alloc(
m_backend.GetChildMemberWithName(ConstString("__size_alloc_"), true));
if (size_alloc) {
- ValueObjectSP first(
- size_alloc->GetChildMemberWithName(ConstString("__first_"), true));
- if (first) {
- m_count = first->GetValueAsUnsigned(UINT32_MAX);
+ ValueObjectSP value = GetValueOfCompressedPair(*size_alloc);
+ if (value) {
+ m_count = value->GetValueAsUnsigned(UINT32_MAX);
}
}
if (m_count != UINT32_MAX) {
@@ -239,9 +367,7 @@ size_t lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::
}
}
-lldb::ValueObjectSP
-lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::GetChildAtIndex(
- size_t idx) {
+lldb::ValueObjectSP ListFrontEnd::GetChildAtIndex(size_t idx) {
static ConstString g_value("__value_");
static ConstString g_next("__next_");
@@ -254,23 +380,10 @@ lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::GetChildAtIndex(
if (HasLoop(idx + 1))
return lldb::ValueObjectSP();
- size_t actual_advance = idx;
-
- ListIterator current(m_head);
- if (idx > 0) {
- auto cached_iterator = m_iterators.find(idx - 1);
- if (cached_iterator != m_iterators.end()) {
- current = cached_iterator->second;
- actual_advance = 1;
- }
- }
-
- ValueObjectSP current_sp(current.advance(actual_advance));
+ ValueObjectSP current_sp = GetItem(idx);
if (!current_sp)
return lldb::ValueObjectSP();
- m_iterators[idx] = current;
-
current_sp = current_sp->GetChildAtIndex(1, true); // get the __value_ child
if (!current_sp)
return lldb::ValueObjectSP();
@@ -303,23 +416,13 @@ lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::GetChildAtIndex(
m_element_type);
}
-bool lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::Update() {
- m_iterators.clear();
- m_head = m_tail = nullptr;
+bool ListFrontEnd::Update() {
+ AbstractListFrontEnd::Update();
+ m_tail = nullptr;
m_node_address = 0;
- m_count = UINT32_MAX;
- m_loop_detected = 0;
- m_slow_runner.SetEntry(nullptr);
- m_fast_runner.SetEntry(nullptr);
Status err;
ValueObjectSP backend_addr(m_backend.AddressOf(err));
- m_list_capping_size = 0;
- if (m_backend.GetTargetSP())
- m_list_capping_size =
- m_backend.GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
- if (m_list_capping_size == 0)
- m_list_capping_size = 255;
if (err.Fail() || !backend_addr)
return false;
m_node_address = backend_addr->GetValueAsUnsigned(0);
@@ -329,31 +432,18 @@ bool lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::Update() {
m_backend.GetChildMemberWithName(ConstString("__end_"), true));
if (!impl_sp)
return false;
- CompilerType list_type = m_backend.GetCompilerType();
- if (list_type.IsReferenceType())
- list_type = list_type.GetNonReferenceType();
-
- if (list_type.GetNumTemplateArguments() == 0)
- return false;
- lldb::TemplateArgumentKind kind;
- m_element_type = list_type.GetTemplateArgument(0, kind);
m_head = impl_sp->GetChildMemberWithName(ConstString("__next_"), true).get();
m_tail = impl_sp->GetChildMemberWithName(ConstString("__prev_"), true).get();
return false;
}
-bool lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::
- MightHaveChildren() {
- return true;
-}
-
-size_t lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::
- GetIndexOfChildWithName(const ConstString &name) {
- return ExtractIndexFromString(name.GetCString());
+SyntheticChildrenFrontEnd *formatters::LibcxxStdListSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ return (valobj_sp ? new ListFrontEnd(valobj_sp) : nullptr);
}
SyntheticChildrenFrontEnd *
-lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator(
+formatters::LibcxxStdForwardListSyntheticFrontEndCreator(
CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
- return (valobj_sp ? new LibcxxStdListSyntheticFrontEnd(valobj_sp) : nullptr);
+ return valobj_sp ? new ForwardListFrontEnd(*valobj_sp) : nullptr;
}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
index b7215dbcbb485..be96a6d95bcd5 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
@@ -268,13 +268,12 @@ bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType() {
m_element_type = deref->GetCompilerType();
return true;
}
- lldb::TemplateArgumentKind kind;
deref = m_backend.GetChildAtNamePath({g_tree_, g_pair3});
if (!deref)
return false;
- m_element_type =
- deref->GetCompilerType().GetTemplateArgument(1, kind).GetTemplateArgument(
- 1, kind);
+ m_element_type = deref->GetCompilerType()
+ .GetTypeTemplateArgument(1)
+ .GetTypeTemplateArgument(1);
if (m_element_type) {
std::string name;
uint64_t bit_offset_ptr;
@@ -285,7 +284,7 @@ bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType() {
m_element_type = m_element_type.GetTypedefedType();
return m_element_type.IsValid();
} else {
- m_element_type = m_backend.GetCompilerType().GetTemplateArgument(0, kind);
+ m_element_type = m_backend.GetCompilerType().GetTypeTemplateArgument(0);
return m_element_type.IsValid();
}
}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp b/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp
new file mode 100644
index 0000000000000..c4e0b66d4272e
--- /dev/null
+++ b/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp
@@ -0,0 +1,61 @@
+//===-- LibCxxQueue.cpp -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LibCxx.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace {
+
+class QueueFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ QueueFrontEnd(ValueObject &valobj) : SyntheticChildrenFrontEnd(valobj) {
+ Update();
+ }
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override {
+ return m_container_sp ? m_container_sp->GetIndexOfChildWithName(name)
+ : UINT32_MAX;
+ }
+
+ bool MightHaveChildren() override { return true; }
+ bool Update() override;
+
+ size_t CalculateNumChildren() override {
+ return m_container_sp ? m_container_sp->GetNumChildren() : 0;
+ }
+
+ ValueObjectSP GetChildAtIndex(size_t idx) override {
+ return m_container_sp ? m_container_sp->GetChildAtIndex(idx, true)
+ : nullptr;
+ }
+
+private:
+ ValueObjectSP m_container_sp;
+};
+} // namespace
+
+bool QueueFrontEnd::Update() {
+ m_container_sp.reset();
+ ValueObjectSP c_sp = m_backend.GetChildMemberWithName(ConstString("c"), true);
+ if (!c_sp)
+ return false;
+ m_container_sp = c_sp->GetSyntheticValue();
+ return false;
+}
+
+SyntheticChildrenFrontEnd *
+formatters::LibcxxQueueFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP valobj_sp) {
+ if (valobj_sp)
+ return new QueueFrontEnd(*valobj_sp);
+ return nullptr;
+}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp b/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp
new file mode 100644
index 0000000000000..9b412a12f532f
--- /dev/null
+++ b/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp
@@ -0,0 +1,83 @@
+//===-- LibCxxTuple.cpp -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LibCxx.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace {
+
+class TupleFrontEnd: public SyntheticChildrenFrontEnd {
+public:
+ TupleFrontEnd(ValueObject &valobj) : SyntheticChildrenFrontEnd(valobj) {
+ Update();
+ }
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override {
+ return formatters::ExtractIndexFromString(name.GetCString());
+ }
+
+ bool MightHaveChildren() override { return true; }
+ bool Update() override;
+ size_t CalculateNumChildren() override { return m_elements.size(); }
+ ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+private:
+ std::vector<ValueObjectSP> m_elements;
+ ValueObjectSP m_base_sp;
+};
+}
+
+bool TupleFrontEnd::Update() {
+ m_elements.clear();
+ m_base_sp = m_backend.GetChildMemberWithName(ConstString("__base_"), true);
+ if (! m_base_sp) {
+ // Pre r304382 name of the base element.
+ m_base_sp = m_backend.GetChildMemberWithName(ConstString("base_"), true);
+ }
+ if (! m_base_sp)
+ return false;
+ m_elements.assign(m_base_sp->GetCompilerType().GetNumDirectBaseClasses(),
+ ValueObjectSP());
+ return false;
+}
+
+ValueObjectSP TupleFrontEnd::GetChildAtIndex(size_t idx) {
+ if (idx >= m_elements.size())
+ return ValueObjectSP();
+ if (!m_base_sp)
+ return ValueObjectSP();
+ if (m_elements[idx])
+ return m_elements[idx];
+
+ CompilerType holder_type =
+ m_base_sp->GetCompilerType().GetDirectBaseClassAtIndex(idx, nullptr);
+ if (!holder_type)
+ return ValueObjectSP();
+ ValueObjectSP holder_sp = m_base_sp->GetChildAtIndex(idx, true);
+ if (!holder_sp)
+ return ValueObjectSP();
+
+ ValueObjectSP elem_sp = holder_sp->GetChildAtIndex(0, true);
+ if (elem_sp)
+ m_elements[idx] =
+ elem_sp->Clone(ConstString(llvm::formatv("[{0}]", idx).str()));
+
+ return m_elements[idx];
+}
+
+SyntheticChildrenFrontEnd *
+formatters::LibcxxTupleFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP valobj_sp) {
+ if (valobj_sp)
+ return new TupleFrontEnd(*valobj_sp);
+ return nullptr;
+}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp b/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
index 190b5f64381ea..0f1c2537d651e 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
@@ -121,11 +121,10 @@ lldb::ValueObjectSP lldb_private::formatters::
if (!first_sp)
return nullptr;
m_element_type = first_sp->GetCompilerType();
- lldb::TemplateArgumentKind kind;
- m_element_type = m_element_type.GetTemplateArgument(0, kind);
+ m_element_type = m_element_type.GetTypeTemplateArgument(0);
m_element_type = m_element_type.GetPointeeType();
m_node_type = m_element_type;
- m_element_type = m_element_type.GetTemplateArgument(0, kind);
+ m_element_type = m_element_type.GetTypeTemplateArgument(0);
std::string name;
m_element_type =
m_element_type.GetFieldAtIndex(0, name, nullptr, nullptr, nullptr);
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp b/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp
index 6f601c9f6ccbf..711130639cd2f 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp
@@ -290,8 +290,7 @@ lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator(
CompilerType type = valobj_sp->GetCompilerType();
if (!type.IsValid() || type.GetNumTemplateArguments() == 0)
return nullptr;
- TemplateArgumentKind kind;
- CompilerType arg_type = type.GetTemplateArgument(0, kind);
+ CompilerType arg_type = type.GetTypeTemplateArgument(0);
if (arg_type.GetTypeName() == ConstString("bool"))
return new LibcxxVectorBoolSyntheticFrontEnd(valobj_sp);
return new LibcxxStdVectorSyntheticFrontEnd(valobj_sp);
diff --git a/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
index e3018a1884be1..3e2b7159f8944 100644
--- a/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
@@ -117,11 +117,8 @@ bool LibstdcppMapIteratorSyntheticFrontEnd::Update() {
CompilerType my_type(valobj_sp->GetCompilerType());
if (my_type.GetNumTemplateArguments() >= 1) {
- TemplateArgumentKind kind;
- CompilerType pair_type = my_type.GetTemplateArgument(0, kind);
- if (kind != eTemplateArgumentKindType &&
- kind != eTemplateArgumentKindTemplate &&
- kind != eTemplateArgumentKindTemplateExpansion)
+ CompilerType pair_type = my_type.GetTypeTemplateArgument(0);
+ if (!pair_type)
return false;
m_pair_type = pair_type;
} else
diff --git a/source/Plugins/Language/ObjC/CMakeLists.txt b/source/Plugins/Language/ObjC/CMakeLists.txt
index 7cc93c7b05580..95ace3a3633ab 100644
--- a/source/Plugins/Language/ObjC/CMakeLists.txt
+++ b/source/Plugins/Language/ObjC/CMakeLists.txt
@@ -1,3 +1,13 @@
+set(EXTRA_CXXFLAGS "")
+
+if (CXX_SUPPORTS_NO_GNU_ANONYMOUS_STRUCT)
+ set(EXTRA_CXXFLAGS ${EXTRA_CXXFLAGS} -Wno-gnu-anonymous-struct)
+endif ()
+
+if (CXX_SUPPORTS_NO_NESTED_ANON_TYPES)
+ set(EXTRA_CXXFLAGS ${EXTRA_CXXFLAGS} -Wno-nested-anon-types)
+endif ()
+
add_lldb_library(lldbPluginObjCLanguage PLUGIN
ObjCLanguage.cpp
CF.cpp
@@ -21,4 +31,6 @@ add_lldb_library(lldbPluginObjCLanguage PLUGIN
lldbTarget
lldbUtility
lldbPluginAppleObjCRuntime
+
+ EXTRA_CXXFLAGS ${EXTRA_CXXFLAGS}
)
diff --git a/source/Plugins/Language/ObjC/NSArray.cpp b/source/Plugins/Language/ObjC/NSArray.cpp
index 27cb9558c482d..f6d1592019511 100644
--- a/source/Plugins/Language/ObjC/NSArray.cpp
+++ b/source/Plugins/Language/ObjC/NSArray.cpp
@@ -48,11 +48,11 @@ NSArray_Additionals::GetAdditionalSynthetics() {
return g_map;
}
-class NSArrayMSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+class NSArrayMSyntheticFrontEndBase : public SyntheticChildrenFrontEnd {
public:
- NSArrayMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+ NSArrayMSyntheticFrontEndBase(lldb::ValueObjectSP valobj_sp);
- ~NSArrayMSyntheticFrontEnd() override = default;
+ ~NSArrayMSyntheticFrontEndBase() override = default;
size_t CalculateNumChildren() override;
@@ -78,11 +78,12 @@ protected:
CompilerType m_id_type;
};
-class NSArrayMSyntheticFrontEnd_109 : public NSArrayMSyntheticFrontEnd {
+template <typename D32, typename D64>
+class GenericNSArrayMSyntheticFrontEnd : public NSArrayMSyntheticFrontEndBase {
public:
- NSArrayMSyntheticFrontEnd_109(lldb::ValueObjectSP valobj_sp);
+ GenericNSArrayMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
- ~NSArrayMSyntheticFrontEnd_109() override;
+ ~GenericNSArrayMSyntheticFrontEnd() override;
bool Update() override;
@@ -96,6 +97,11 @@ protected:
uint64_t GetSize() override;
private:
+ D32 *m_data_32;
+ D64 *m_data_64;
+};
+
+namespace Foundation109 {
struct DataDescriptor_32 {
uint32_t _used;
uint32_t _priv1 : 2;
@@ -105,7 +111,7 @@ private:
uint32_t _priv3;
uint32_t _data;
};
-
+
struct DataDescriptor_64 {
uint64_t _used;
uint64_t _priv1 : 2;
@@ -115,29 +121,12 @@ private:
uint32_t _priv3;
uint64_t _data;
};
-
- DataDescriptor_32 *m_data_32;
- DataDescriptor_64 *m_data_64;
-};
-
-class NSArrayMSyntheticFrontEnd_1010 : public NSArrayMSyntheticFrontEnd {
-public:
- NSArrayMSyntheticFrontEnd_1010(lldb::ValueObjectSP valobj_sp);
-
- ~NSArrayMSyntheticFrontEnd_1010() override;
-
- bool Update() override;
-
-protected:
- lldb::addr_t GetDataAddress() override;
-
- uint64_t GetUsedCount() override;
-
- uint64_t GetOffset() override;
-
- uint64_t GetSize() override;
-
-private:
+
+ using NSArrayMSyntheticFrontEnd =
+ GenericNSArrayMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
+}
+
+namespace Foundation1010 {
struct DataDescriptor_32 {
uint32_t _used;
uint32_t _offset;
@@ -146,7 +135,7 @@ private:
uint32_t _priv2;
uint32_t _data;
};
-
+
struct DataDescriptor_64 {
uint64_t _used;
uint64_t _offset;
@@ -155,76 +144,86 @@ private:
uint32_t _priv2;
uint64_t _data;
};
-
- DataDescriptor_32 *m_data_32;
- DataDescriptor_64 *m_data_64;
-};
-
-class NSArrayMSyntheticFrontEnd_1400 : public NSArrayMSyntheticFrontEnd {
-public:
- NSArrayMSyntheticFrontEnd_1400(lldb::ValueObjectSP valobj_sp);
-
- ~NSArrayMSyntheticFrontEnd_1400() override;
-
- bool Update() override;
-
-protected:
- lldb::addr_t GetDataAddress() override;
-
- uint64_t GetUsedCount() override;
-
- uint64_t GetOffset() override;
-
- uint64_t GetSize() override;
-
-private:
+
+ using NSArrayMSyntheticFrontEnd =
+ GenericNSArrayMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
+}
+
+namespace Foundation1428 {
struct DataDescriptor_32 {
- uint32_t used;
- uint32_t offset;
- uint32_t size;
- uint32_t list;
+ uint32_t _used;
+ uint32_t _offset;
+ uint32_t _size;
+ uint32_t _data;
};
-
+
struct DataDescriptor_64 {
- uint64_t used;
- uint64_t offset;
- uint64_t size;
- uint64_t list;
+ uint64_t _used;
+ uint64_t _offset;
+ uint64_t _size;
+ uint64_t _data;
};
+
+ using NSArrayMSyntheticFrontEnd =
+ GenericNSArrayMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
+}
+
+namespace Foundation1437 {
+ template <typename PtrType>
+ struct DataDescriptor {
+ PtrType _cow;
+ // __deque
+ PtrType _data;
+ uint32_t _offset;
+ uint32_t _size;
+ union {
+ PtrType _mutations;
+ struct {
+ uint32_t _muts;
+ uint32_t _used;
+ };
+ };
+ };
+
+ using NSArrayMSyntheticFrontEnd =
+ GenericNSArrayMSyntheticFrontEnd<
+ DataDescriptor<uint32_t>, DataDescriptor<uint64_t>>;
+
+ template <typename DD>
+ uint64_t
+ __NSArrayMSize_Impl(lldb_private::Process &process,
+ lldb::addr_t valobj_addr, Status &error) {
+ const lldb::addr_t start_of_descriptor =
+ valobj_addr + process.GetAddressByteSize();
+ DD descriptor = DD();
+ process.ReadMemory(start_of_descriptor, &descriptor,
+ sizeof(descriptor), error);
+ if (error.Fail()) {
+ return 0;
+ }
+ return descriptor._used;
+ }
+
+ uint64_t
+ __NSArrayMSize(lldb_private::Process &process, lldb::addr_t valobj_addr,
+ Status &error) {
+ if (process.GetAddressByteSize() == 4) {
+ return __NSArrayMSize_Impl<DataDescriptor<uint32_t>>(process, valobj_addr,
+ error);
+ } else {
+ return __NSArrayMSize_Impl<DataDescriptor<uint64_t>>(process, valobj_addr,
+ error);
+ }
+ }
- DataDescriptor_32 *m_data_32;
- DataDescriptor_64 *m_data_64;
-};
-
-class NSArrayISyntheticFrontEnd_1300 : public SyntheticChildrenFrontEnd {
-public:
- NSArrayISyntheticFrontEnd_1300(lldb::ValueObjectSP valobj_sp);
-
- ~NSArrayISyntheticFrontEnd_1300() override = default;
-
- size_t CalculateNumChildren() override;
-
- lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
-
- bool Update() override;
-
- bool MightHaveChildren() override;
-
- size_t GetIndexOfChildWithName(const ConstString &name) override;
-
-private:
- ExecutionContextRef m_exe_ctx_ref;
- uint8_t m_ptr_size;
- uint64_t m_items;
- lldb::addr_t m_data_ptr;
- CompilerType m_id_type;
-};
+}
-class NSArrayISyntheticFrontEnd_1400 : public SyntheticChildrenFrontEnd {
+template <typename D32, typename D64, bool Inline>
+class GenericNSArrayISyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
- NSArrayISyntheticFrontEnd_1400(lldb::ValueObjectSP valobj_sp);
+ GenericNSArrayISyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
- ~NSArrayISyntheticFrontEnd_1400() override;
+ ~GenericNSArrayISyntheticFrontEnd() override;
size_t CalculateNumChildren() override;
@@ -239,25 +238,58 @@ public:
private:
ExecutionContextRef m_exe_ctx_ref;
uint8_t m_ptr_size;
-
- struct DataDescriptor_32 {
- uint32_t used;
- uint32_t offset;
- uint32_t size;
- uint32_t list;
- };
-
- struct DataDescriptor_64 {
- uint64_t used;
- uint64_t offset;
- uint64_t size;
- uint64_t list;
- };
-
- DataDescriptor_32 *m_data_32;
- DataDescriptor_64 *m_data_64;
+
+ D32 *m_data_32;
+ D64 *m_data_64;
CompilerType m_id_type;
};
+
+namespace Foundation1300 {
+ struct IDD32 {
+ uint32_t used;
+ uint32_t list;
+ };
+
+ struct IDD64 {
+ uint64_t used;
+ uint64_t list;
+ };
+
+ using NSArrayISyntheticFrontEnd =
+ GenericNSArrayISyntheticFrontEnd<IDD32, IDD64, true>;
+}
+
+namespace Foundation1430 {
+ using NSArrayISyntheticFrontEnd =
+ Foundation1428::NSArrayMSyntheticFrontEnd;
+}
+
+namespace Foundation1436 {
+ struct IDD32 {
+ uint32_t used;
+ uint32_t list; // in Inline cases, this is the first element
+ };
+
+ struct IDD64 {
+ uint64_t used;
+ uint64_t list; // in Inline cases, this is the first element
+ };
+
+ using NSArrayI_TransferSyntheticFrontEnd =
+ GenericNSArrayISyntheticFrontEnd<IDD32, IDD64, false>;
+
+ using NSArrayISyntheticFrontEnd =
+ GenericNSArrayISyntheticFrontEnd<IDD32, IDD64, true>;
+
+ using NSFrozenArrayMSyntheticFrontEnd =
+ Foundation1437::NSArrayMSyntheticFrontEnd;
+
+ uint64_t
+ __NSFrozenArrayMSize(lldb_private::Process &process, lldb::addr_t valobj_addr,
+ Status &error) {
+ return Foundation1437::__NSArrayMSize(process, valobj_addr, error);
+ }
+}
class NSArray0SyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
@@ -329,6 +361,8 @@ bool lldb_private::formatters::NSArraySummaryProvider(
static const ConstString g_NSArrayI("__NSArrayI");
static const ConstString g_NSArrayM("__NSArrayM");
+ static const ConstString g_NSArrayI_Transfer("__NSArrayI_Transfer");
+ static const ConstString g_NSFrozenArrayM("__NSFrozenArrayM");
static const ConstString g_NSArray0("__NSArray0");
static const ConstString g_NSArray1("__NSSingleObjectArrayI");
static const ConstString g_NSArrayCF("__NSCFArray");
@@ -345,11 +379,28 @@ bool lldb_private::formatters::NSArraySummaryProvider(
if (error.Fail())
return false;
} else if (class_name == g_NSArrayM) {
+ AppleObjCRuntime *apple_runtime =
+ llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
+ Status error;
+ if (apple_runtime && apple_runtime->GetFoundationVersion() >= 1437) {
+ value = Foundation1437::__NSArrayMSize(*process_sp, valobj_addr, error);
+ } else {
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
+ ptr_size, 0, error);
+ }
+ if (error.Fail())
+ return false;
+ } else if (class_name == g_NSArrayI_Transfer) {
Status error;
value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
ptr_size, 0, error);
if (error.Fail())
return false;
+ } else if (class_name == g_NSFrozenArrayM) {
+ Status error;
+ value = Foundation1436::__NSFrozenArrayMSize(*process_sp, valobj_addr, error);
+ if (error.Fail())
+ return false;
} else if (class_name == g_NSArrayMLegacy) {
Status error;
value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
@@ -395,7 +446,7 @@ bool lldb_private::formatters::NSArraySummaryProvider(
return true;
}
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd(
+lldb_private::formatters::NSArrayMSyntheticFrontEndBase::NSArrayMSyntheticFrontEndBase(
lldb::ValueObjectSP valobj_sp)
: SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
m_id_type() {
@@ -411,28 +462,20 @@ lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd(
}
}
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::
- NSArrayMSyntheticFrontEnd_109(lldb::ValueObjectSP valobj_sp)
- : NSArrayMSyntheticFrontEnd(valobj_sp), m_data_32(nullptr),
- m_data_64(nullptr) {}
-
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::
- NSArrayMSyntheticFrontEnd_1010(lldb::ValueObjectSP valobj_sp)
- : NSArrayMSyntheticFrontEnd(valobj_sp), m_data_32(nullptr),
- m_data_64(nullptr) {}
-
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::
- NSArrayMSyntheticFrontEnd_1400(lldb::ValueObjectSP valobj_sp)
- : NSArrayMSyntheticFrontEnd(valobj_sp), m_data_32(nullptr),
+template <typename D32, typename D64>
+lldb_private::formatters::
+ GenericNSArrayMSyntheticFrontEnd<D32, D64>::
+ GenericNSArrayMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : NSArrayMSyntheticFrontEndBase(valobj_sp), m_data_32(nullptr),
m_data_64(nullptr) {}
size_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::CalculateNumChildren() {
+lldb_private::formatters::NSArrayMSyntheticFrontEndBase::CalculateNumChildren() {
return GetUsedCount();
}
lldb::ValueObjectSP
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetChildAtIndex(
+lldb_private::formatters::NSArrayMSyntheticFrontEndBase::GetChildAtIndex(
size_t idx) {
if (idx >= CalculateNumChildren())
return lldb::ValueObjectSP();
@@ -448,69 +491,10 @@ lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetChildAtIndex(
m_exe_ctx_ref, m_id_type);
}
-bool lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::Update() {
- ValueObjectSP valobj_sp = m_backend.GetSP();
- m_ptr_size = 0;
- delete m_data_32;
- m_data_32 = nullptr;
- delete m_data_64;
- m_data_64 = nullptr;
- if (!valobj_sp)
- return false;
- m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
- Status error;
- error.Clear();
- lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
- if (!process_sp)
- return false;
- m_ptr_size = process_sp->GetAddressByteSize();
- uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
- if (m_ptr_size == 4) {
- m_data_32 = new DataDescriptor_32();
- process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
- error);
- } else {
- m_data_64 = new DataDescriptor_64();
- process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
- error);
- }
- if (error.Fail())
- return false;
- return false;
-}
-
-bool lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::Update() {
- ValueObjectSP valobj_sp = m_backend.GetSP();
- m_ptr_size = 0;
- delete m_data_32;
- m_data_32 = nullptr;
- delete m_data_64;
- m_data_64 = nullptr;
- if (!valobj_sp)
- return false;
- m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
- Status error;
- error.Clear();
- lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
- if (!process_sp)
- return false;
- m_ptr_size = process_sp->GetAddressByteSize();
- uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
- if (m_ptr_size == 4) {
- m_data_32 = new DataDescriptor_32();
- process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
- error);
- } else {
- m_data_64 = new DataDescriptor_64();
- process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
- error);
- }
- if (error.Fail())
- return false;
- return false;
-}
-
-bool lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::Update() {
+template <typename D32, typename D64>
+bool
+lldb_private::formatters::
+ GenericNSArrayMSyntheticFrontEnd<D32, D64>::Update() {
ValueObjectSP valobj_sp = m_backend.GetSP();
m_ptr_size = 0;
delete m_data_32;
@@ -528,12 +512,12 @@ bool lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::Update() {
m_ptr_size = process_sp->GetAddressByteSize();
uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
if (m_ptr_size == 4) {
- m_data_32 = new DataDescriptor_32();
- process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
+ m_data_32 = new D32();
+ process_sp->ReadMemory(data_location, m_data_32, sizeof(D32),
error);
} else {
- m_data_64 = new DataDescriptor_64();
- process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
+ m_data_64 = new D64();
+ process_sp->ReadMemory(data_location, m_data_64, sizeof(D64),
error);
}
if (error.Fail())
@@ -541,12 +525,13 @@ bool lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::Update() {
return false;
}
-bool lldb_private::formatters::NSArrayMSyntheticFrontEnd::MightHaveChildren() {
+bool
+lldb_private::formatters::NSArrayMSyntheticFrontEndBase::MightHaveChildren() {
return true;
}
size_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetIndexOfChildWithName(
+lldb_private::formatters::NSArrayMSyntheticFrontEndBase::GetIndexOfChildWithName(
const ConstString &name) {
const char *item_name = name.GetCString();
uint32_t idx = ExtractIndexFromString(item_name);
@@ -555,187 +540,59 @@ lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetIndexOfChildWithName(
return idx;
}
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::
- ~NSArrayMSyntheticFrontEnd_109() {
+template <typename D32, typename D64>
+lldb_private::formatters::
+ GenericNSArrayMSyntheticFrontEnd<D32, D64>::
+ ~GenericNSArrayMSyntheticFrontEnd() {
delete m_data_32;
m_data_32 = nullptr;
delete m_data_64;
m_data_64 = nullptr;
}
+template <typename D32, typename D64>
lldb::addr_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetDataAddress() {
+lldb_private::formatters::
+ GenericNSArrayMSyntheticFrontEnd<D32, D64>::
+ GenericNSArrayMSyntheticFrontEnd::GetDataAddress() {
if (!m_data_32 && !m_data_64)
return LLDB_INVALID_ADDRESS;
return m_data_32 ? m_data_32->_data : m_data_64->_data;
}
+template <typename D32, typename D64>
uint64_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetUsedCount() {
+lldb_private::formatters::
+ GenericNSArrayMSyntheticFrontEnd<D32, D64>::
+ GenericNSArrayMSyntheticFrontEnd::GetUsedCount() {
if (!m_data_32 && !m_data_64)
return 0;
return m_data_32 ? m_data_32->_used : m_data_64->_used;
}
-uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetOffset() {
- if (!m_data_32 && !m_data_64)
- return 0;
- return m_data_32 ? m_data_32->_offset : m_data_64->_offset;
-}
-
-uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetSize() {
- if (!m_data_32 && !m_data_64)
- return 0;
- return m_data_32 ? m_data_32->_size : m_data_64->_size;
-}
-
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::
- ~NSArrayMSyntheticFrontEnd_1010() {
- delete m_data_32;
- m_data_32 = nullptr;
- delete m_data_64;
- m_data_64 = nullptr;
-}
-
-lldb::addr_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetDataAddress() {
- if (!m_data_32 && !m_data_64)
- return LLDB_INVALID_ADDRESS;
- return m_data_32 ? m_data_32->_data : m_data_64->_data;
-}
-
+template <typename D32, typename D64>
uint64_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetUsedCount() {
- if (!m_data_32 && !m_data_64)
- return 0;
- return m_data_32 ? m_data_32->_used : m_data_64->_used;
-}
-
-uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetOffset() {
+lldb_private::formatters::
+ GenericNSArrayMSyntheticFrontEnd<D32, D64>::
+ GenericNSArrayMSyntheticFrontEnd::GetOffset() {
if (!m_data_32 && !m_data_64)
return 0;
return m_data_32 ? m_data_32->_offset : m_data_64->_offset;
}
-uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetSize() {
- if (!m_data_32 && !m_data_64)
- return 0;
- return m_data_32 ? m_data_32->_size : m_data_64->_size;
-}
-
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::
- ~NSArrayMSyntheticFrontEnd_1400() {
- delete m_data_32;
- m_data_32 = nullptr;
- delete m_data_64;
- m_data_64 = nullptr;
-}
-
-lldb::addr_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::GetDataAddress() {
- if (!m_data_32 && !m_data_64)
- return LLDB_INVALID_ADDRESS;
- return m_data_32 ? m_data_32->list : m_data_64->list;
-}
-
+template <typename D32, typename D64>
uint64_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::GetUsedCount() {
+lldb_private::formatters::
+ GenericNSArrayMSyntheticFrontEnd<D32, D64>::
+ GenericNSArrayMSyntheticFrontEnd::GetSize() {
if (!m_data_32 && !m_data_64)
return 0;
- return m_data_32 ? m_data_32->used : m_data_64->used;
-}
-
-uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::GetOffset() {
- if (!m_data_32 && !m_data_64)
- return 0;
- return m_data_32 ? m_data_32->offset : m_data_64->offset;
-}
-
-uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::GetSize() {
- if (!m_data_32 && !m_data_64)
- return 0;
- return m_data_32 ? m_data_32->size : m_data_64->size;
-}
-
-
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::NSArrayISyntheticFrontEnd_1300(
- lldb::ValueObjectSP valobj_sp)
- : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
- m_items(0), m_data_ptr(0) {
- if (valobj_sp) {
- CompilerType type = valobj_sp->GetCompilerType();
- if (type) {
- ClangASTContext *ast = valobj_sp->GetExecutionContextRef()
- .GetTargetSP()
- ->GetScratchClangASTContext();
- if (ast)
- m_id_type = CompilerType(ast->getASTContext(),
- ast->getASTContext()->ObjCBuiltinIdTy);
- }
- }
-}
-
-size_t
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::GetIndexOfChildWithName(
- const ConstString &name) {
- const char *item_name = name.GetCString();
- uint32_t idx = ExtractIndexFromString(item_name);
- if (idx < UINT32_MAX && idx >= CalculateNumChildren())
- return UINT32_MAX;
- return idx;
-}
-
-size_t
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::CalculateNumChildren() {
- return m_items;
-}
-
-bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::Update() {
- m_ptr_size = 0;
- m_items = 0;
- m_data_ptr = 0;
- ValueObjectSP valobj_sp = m_backend.GetSP();
- if (!valobj_sp)
- return false;
- m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
- Status error;
- error.Clear();
- lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
- if (!process_sp)
- return false;
- m_ptr_size = process_sp->GetAddressByteSize();
- uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
- m_items = process_sp->ReadPointerFromMemory(data_location, error);
- if (error.Fail())
- return false;
- m_data_ptr = data_location + m_ptr_size;
- return false;
-}
-
-bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::MightHaveChildren() {
- return true;
-}
-
-lldb::ValueObjectSP
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::GetChildAtIndex(
- size_t idx) {
- if (idx >= CalculateNumChildren())
- return lldb::ValueObjectSP();
- lldb::addr_t object_at_idx = m_data_ptr;
- object_at_idx += (idx * m_ptr_size);
- ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
- if (!process_sp)
- return lldb::ValueObjectSP();
- Status error;
- if (error.Fail())
- return lldb::ValueObjectSP();
- StreamString idx_name;
- idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
- return CreateValueObjectFromAddress(idx_name.GetString(), object_at_idx,
- m_exe_ctx_ref, m_id_type);
+ return m_data_32 ? m_data_32->_size : m_data_64->_size;
}
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::NSArrayISyntheticFrontEnd_1400(
+template <typename D32, typename D64, bool Inline>
+lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
+ GenericNSArrayISyntheticFrontEnd(
lldb::ValueObjectSP valobj_sp)
: SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
m_data_32(nullptr), m_data_64(nullptr) {
@@ -752,16 +609,19 @@ lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::NSArrayISyntheticFront
}
}
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::~NSArrayISyntheticFrontEnd_1400() {
+template <typename D32, typename D64, bool Inline>
+lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
+ ~GenericNSArrayISyntheticFrontEnd() {
delete m_data_32;
m_data_32 = nullptr;
delete m_data_64;
m_data_64 = nullptr;
}
+template <typename D32, typename D64, bool Inline>
size_t
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::GetIndexOfChildWithName(
- const ConstString &name) {
+lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
+ GetIndexOfChildWithName(const ConstString &name) {
const char *item_name = name.GetCString();
uint32_t idx = ExtractIndexFromString(item_name);
if (idx < UINT32_MAX && idx >= CalculateNumChildren())
@@ -769,12 +629,17 @@ lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::GetIndexOfChildWithNam
return idx;
}
+template <typename D32, typename D64, bool Inline>
size_t
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::CalculateNumChildren() {
+lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
+ CalculateNumChildren() {
return m_data_32 ? m_data_32->used : m_data_64->used;
}
-bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::Update() {
+template <typename D32, typename D64, bool Inline>
+bool
+lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
+ Update() {
ValueObjectSP valobj_sp = m_backend.GetSP();
m_ptr_size = 0;
delete m_data_32;
@@ -792,12 +657,12 @@ bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::Update() {
m_ptr_size = process_sp->GetAddressByteSize();
uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
if (m_ptr_size == 4) {
- m_data_32 = new DataDescriptor_32();
- process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
+ m_data_32 = new D32();
+ process_sp->ReadMemory(data_location, m_data_32, sizeof(D32),
error);
} else {
- m_data_64 = new DataDescriptor_64();
- process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
+ m_data_64 = new D64();
+ process_sp->ReadMemory(data_location, m_data_64, sizeof(D64),
error);
}
if (error.Fail())
@@ -805,17 +670,29 @@ bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::Update() {
return false;
}
-bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::MightHaveChildren() {
+template <typename D32, typename D64, bool Inline>
+bool
+lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
+ MightHaveChildren() {
return true;
}
+template <typename D32, typename D64, bool Inline>
lldb::ValueObjectSP
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::GetChildAtIndex(
- size_t idx) {
+lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
+ GetChildAtIndex(size_t idx) {
if (idx >= CalculateNumChildren())
return lldb::ValueObjectSP();
- lldb::addr_t object_at_idx = m_data_32 ? m_data_32->list : m_data_64->list;
+ lldb::addr_t object_at_idx;
+ if (Inline) {
+ object_at_idx = m_backend.GetSP()->GetValueAsUnsigned(0) + m_ptr_size;
+ object_at_idx += m_ptr_size == 4 ? sizeof(D32) : sizeof(D64); // skip the data header
+ object_at_idx -= m_ptr_size; // we treat the last entry in the data header as the first pointer
+ } else {
+ object_at_idx = m_data_32 ? m_data_32->list : m_data_64->list;
+ }
object_at_idx += (idx * m_ptr_size);
+
ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
if (!process_sp)
return lldb::ValueObjectSP();
@@ -933,6 +810,8 @@ lldb_private::formatters::NSArraySyntheticFrontEndCreator(
ConstString class_name(descriptor->GetClassName());
static const ConstString g_NSArrayI("__NSArrayI");
+ static const ConstString g_NSArrayI_Transfer("__NSArrayI_Transfer");
+ static const ConstString g_NSFrozenArrayM("__NSFrozenArrayM");
static const ConstString g_NSArrayM("__NSArrayM");
static const ConstString g_NSArray0("__NSArray0");
static const ConstString g_NSArray1("__NSSingleObjectArrayI");
@@ -943,21 +822,30 @@ lldb_private::formatters::NSArraySyntheticFrontEndCreator(
return nullptr;
if (class_name == g_NSArrayI) {
- if (runtime->GetFoundationVersion() >= 1400)
- return (new NSArrayISyntheticFrontEnd_1400(valobj_sp));
- else
- return (new NSArrayISyntheticFrontEnd_1300(valobj_sp));
+ if (runtime->GetFoundationVersion() >= 1436)
+ return (new Foundation1436::NSArrayISyntheticFrontEnd(valobj_sp));
+ if (runtime->GetFoundationVersion() >= 1430)
+ return (new Foundation1430::NSArrayISyntheticFrontEnd(valobj_sp));
+ else
+ return (new Foundation1300::NSArrayISyntheticFrontEnd(valobj_sp));
+ } else if (class_name == g_NSArrayI_Transfer) {
+ return (new Foundation1436::NSArrayI_TransferSyntheticFrontEnd(valobj_sp));
+ } else if (class_name == g_NSArray0) {
+ } else if (class_name == g_NSFrozenArrayM) {
+ return (new Foundation1436::NSFrozenArrayMSyntheticFrontEnd(valobj_sp));
} else if (class_name == g_NSArray0) {
return (new NSArray0SyntheticFrontEnd(valobj_sp));
} else if (class_name == g_NSArray1) {
return (new NSArray1SyntheticFrontEnd(valobj_sp));
} else if (class_name == g_NSArrayM) {
- if (runtime->GetFoundationVersion() >= 1400)
- return (new NSArrayMSyntheticFrontEnd_1400(valobj_sp));
+ if (runtime->GetFoundationVersion() >= 1437)
+ return (new Foundation1437::NSArrayMSyntheticFrontEnd(valobj_sp));
+ if (runtime->GetFoundationVersion() >= 1428)
+ return (new Foundation1428::NSArrayMSyntheticFrontEnd(valobj_sp));
if (runtime->GetFoundationVersion() >= 1100)
- return (new NSArrayMSyntheticFrontEnd_1010(valobj_sp));
+ return (new Foundation1010::NSArrayMSyntheticFrontEnd(valobj_sp));
else
- return (new NSArrayMSyntheticFrontEnd_109(valobj_sp));
+ return (new Foundation109::NSArrayMSyntheticFrontEnd(valobj_sp));
} else {
auto &map(NSArray_Additionals::GetAdditionalSynthetics());
auto iter = map.find(class_name), end = map.end();
diff --git a/source/Plugins/Language/ObjC/NSDictionary.cpp b/source/Plugins/Language/ObjC/NSDictionary.cpp
index 50febbe397583..c564aa1a85715 100644
--- a/source/Plugins/Language/ObjC/NSDictionary.cpp
+++ b/source/Plugins/Language/ObjC/NSDictionary.cpp
@@ -165,11 +165,12 @@ private:
ValueObjectSP m_pair;
};
-class NSDictionaryMSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+template <typename D32, typename D64>
+class GenericNSDictionaryMSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
- NSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+ GenericNSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
- ~NSDictionaryMSyntheticFrontEnd() override;
+ ~GenericNSDictionaryMSyntheticFrontEnd() override;
size_t CalculateNumChildren() override;
@@ -182,20 +183,6 @@ public:
size_t GetIndexOfChildWithName(const ConstString &name) override;
private:
- struct DataDescriptor_32 {
- uint32_t used : 26;
- uint32_t kvo : 1;
- uint32_t size;
- uint32_t buffer;
- };
-
- struct DataDescriptor_64 {
- uint64_t used : 58;
- uint32_t kvo : 1;
- uint64_t size;
- uint64_t buffer;
- };
-
struct DictionaryItemDescriptor {
lldb::addr_t key_ptr;
lldb::addr_t val_ptr;
@@ -205,61 +192,169 @@ private:
ExecutionContextRef m_exe_ctx_ref;
uint8_t m_ptr_size;
lldb::ByteOrder m_order;
- DataDescriptor_32 *m_data_32;
- DataDescriptor_64 *m_data_64;
+ D32 *m_data_32;
+ D64 *m_data_64;
CompilerType m_pair_type;
std::vector<DictionaryItemDescriptor> m_children;
};
-
-class NSDictionaryMLegacySyntheticFrontEnd : public SyntheticChildrenFrontEnd {
-public:
- NSDictionaryMLegacySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
-
- ~NSDictionaryMLegacySyntheticFrontEnd() override;
-
- size_t CalculateNumChildren() override;
-
- lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
-
- bool Update() override;
-
- bool MightHaveChildren() override;
-
- size_t GetIndexOfChildWithName(const ConstString &name) override;
-
-private:
+
+namespace Foundation1100 {
+ class NSDictionaryMSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+ public:
+ NSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ ~NSDictionaryMSyntheticFrontEnd() override;
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
+
+ private:
+ struct DataDescriptor_32 {
+ uint32_t _used : 26;
+ uint32_t _kvo : 1;
+ uint32_t _size;
+ uint32_t _mutations;
+ uint32_t _objs_addr;
+ uint32_t _keys_addr;
+ };
+
+ struct DataDescriptor_64 {
+ uint64_t _used : 58;
+ uint32_t _kvo : 1;
+ uint64_t _size;
+ uint64_t _mutations;
+ uint64_t _objs_addr;
+ uint64_t _keys_addr;
+ };
+
+ struct DictionaryItemDescriptor {
+ lldb::addr_t key_ptr;
+ lldb::addr_t val_ptr;
+ lldb::ValueObjectSP valobj_sp;
+ };
+
+ ExecutionContextRef m_exe_ctx_ref;
+ uint8_t m_ptr_size;
+ lldb::ByteOrder m_order;
+ DataDescriptor_32 *m_data_32;
+ DataDescriptor_64 *m_data_64;
+ CompilerType m_pair_type;
+ std::vector<DictionaryItemDescriptor> m_children;
+ };
+}
+
+namespace Foundation1428 {
struct DataDescriptor_32 {
uint32_t _used : 26;
uint32_t _kvo : 1;
uint32_t _size;
- uint32_t _mutations;
- uint32_t _objs_addr;
- uint32_t _keys_addr;
+ uint32_t _buffer;
+ uint64_t GetSize() { return _size; }
};
-
+
struct DataDescriptor_64 {
uint64_t _used : 58;
uint32_t _kvo : 1;
uint64_t _size;
- uint64_t _mutations;
- uint64_t _objs_addr;
- uint64_t _keys_addr;
+ uint64_t _buffer;
+ uint64_t GetSize() { return _size; }
};
-
- struct DictionaryItemDescriptor {
- lldb::addr_t key_ptr;
- lldb::addr_t val_ptr;
- lldb::ValueObjectSP valobj_sp;
+
+
+
+ using NSDictionaryMSyntheticFrontEnd =
+ GenericNSDictionaryMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
+}
+
+namespace Foundation1437 {
+ static const uint64_t NSDictionaryCapacities[] = {
+ 0, 3, 7, 13, 23, 41, 71, 127, 191, 251, 383, 631, 1087, 1723,
+ 2803, 4523, 7351, 11959, 19447, 31231, 50683, 81919, 132607,
+ 214519, 346607, 561109, 907759, 1468927, 2376191, 3845119,
+ 6221311, 10066421, 16287743, 26354171, 42641881, 68996069,
+ 111638519, 180634607, 292272623, 472907251
+ };
+
+ static const size_t NSDictionaryNumSizeBuckets = sizeof(NSDictionaryCapacities) / sizeof(uint64_t);
+
+ struct DataDescriptor_32 {
+ uint32_t _buffer;
+ union {
+ struct {
+ uint32_t _mutations;
+ };
+ struct {
+ uint32_t _muts;
+ uint32_t _used:25;
+ uint32_t _kvo:1;
+ uint32_t _szidx:6;
+ };
+ };
+
+ uint64_t GetSize() {
+ return (_szidx) >= NSDictionaryNumSizeBuckets ?
+ 0 : NSDictionaryCapacities[_szidx];
+ }
};
+
+ struct DataDescriptor_64 {
+ uint64_t _buffer;
+ union {
+ struct {
+ uint64_t _mutations;
+ };
+ struct {
+ uint32_t _muts;
+ uint32_t _used:25;
+ uint32_t _kvo:1;
+ uint32_t _szidx:6;
+ };
+ };
+
+ uint64_t GetSize() {
+ return (_szidx) >= NSDictionaryNumSizeBuckets ?
+ 0 : NSDictionaryCapacities[_szidx];
+ }
+ };
+
+ using NSDictionaryMSyntheticFrontEnd =
+ GenericNSDictionaryMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
+
+ template <typename DD>
+ uint64_t
+ __NSDictionaryMSize_Impl(lldb_private::Process &process,
+ lldb::addr_t valobj_addr, Status &error) {
+ const lldb::addr_t start_of_descriptor =
+ valobj_addr + process.GetAddressByteSize();
+ DD descriptor = DD();
+ process.ReadMemory(start_of_descriptor, &descriptor, sizeof(descriptor),
+ error);
+ if (error.Fail()) {
+ return 0;
+ }
+ return descriptor._used;
+ }
+
+ uint64_t
+ __NSDictionaryMSize(lldb_private::Process &process, lldb::addr_t valobj_addr,
+ Status &error) {
+ if (process.GetAddressByteSize() == 4) {
+ return __NSDictionaryMSize_Impl<DataDescriptor_32>(process, valobj_addr,
+ error);
+ } else {
+ return __NSDictionaryMSize_Impl<DataDescriptor_64>(process, valobj_addr,
+ error);
+ }
+ }
- ExecutionContextRef m_exe_ctx_ref;
- uint8_t m_ptr_size;
- lldb::ByteOrder m_order;
- DataDescriptor_32 *m_data_32;
- DataDescriptor_64 *m_data_64;
- CompilerType m_pair_type;
- std::vector<DictionaryItemDescriptor> m_children;
-};
+}
} // namespace formatters
} // namespace lldb_private
@@ -313,12 +408,19 @@ bool lldb_private::formatters::NSDictionarySummaryProvider(
return false;
value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
} else if (class_name == g_DictionaryM || class_name == g_DictionaryMLegacy) {
+ AppleObjCRuntime *apple_runtime =
+ llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
Status error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
- ptr_size, 0, error);
+ if (apple_runtime && apple_runtime->GetFoundationVersion() >= 1437) {
+ value = Foundation1437::__NSDictionaryMSize(*process_sp, valobj_addr,
+ error);
+ } else {
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
+ ptr_size, 0, error);
+ value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
+ }
if (error.Fail())
return false;
- value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
} else if (class_name == g_Dictionary1) {
value = 1;
}
@@ -396,13 +498,15 @@ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator(
if (class_name == g_DictionaryI) {
return (new NSDictionaryISyntheticFrontEnd(valobj_sp));
} else if (class_name == g_DictionaryM) {
- if (runtime->GetFoundationVersion() > 1400) {
- return (new NSDictionaryMSyntheticFrontEnd(valobj_sp));
+ if (runtime->GetFoundationVersion() >= 1437) {
+ return (new Foundation1437::NSDictionaryMSyntheticFrontEnd(valobj_sp));
+ } else if (runtime->GetFoundationVersion() >= 1428) {
+ return (new Foundation1428::NSDictionaryMSyntheticFrontEnd(valobj_sp));
} else {
- return (new NSDictionaryMLegacySyntheticFrontEnd(valobj_sp));
+ return (new Foundation1100::NSDictionaryMSyntheticFrontEnd(valobj_sp));
}
} else if (class_name == g_DictionaryMLegacy) {
- return (new NSDictionaryMLegacySyntheticFrontEnd(valobj_sp));
+ return (new Foundation1100::NSDictionaryMSyntheticFrontEnd(valobj_sp));
} else if (class_name == g_Dictionary1) {
return (new NSDictionary1SyntheticFrontEnd(valobj_sp));
} else {
@@ -641,22 +745,25 @@ lldb_private::formatters::NSDictionary1SyntheticFrontEnd::GetChildAtIndex(
return m_pair;
}
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::
- NSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+template <typename D32, typename D64>
+lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::
+ GenericNSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
: SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
m_order(lldb::eByteOrderInvalid), m_data_32(nullptr), m_data_64(nullptr),
m_pair_type() {}
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::
- ~NSDictionaryMSyntheticFrontEnd() {
+template <typename D32, typename D64>
+lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::
+ ~GenericNSDictionaryMSyntheticFrontEnd() {
delete m_data_32;
m_data_32 = nullptr;
delete m_data_64;
m_data_64 = nullptr;
}
-size_t lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::
- GetIndexOfChildWithName(const ConstString &name) {
+template <typename D32, typename D64>
+size_t
+lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>:: GetIndexOfChildWithName(const ConstString &name) {
const char *item_name = name.GetCString();
uint32_t idx = ExtractIndexFromString(item_name);
if (idx < UINT32_MAX && idx >= CalculateNumChildren())
@@ -664,14 +771,18 @@ size_t lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::
return idx;
}
-size_t lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::
- CalculateNumChildren() {
+template <typename D32, typename D64>
+size_t
+lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::CalculateNumChildren() {
if (!m_data_32 && !m_data_64)
return 0;
- return (m_data_32 ? m_data_32->used : m_data_64->used);
+ return (m_data_32 ? m_data_32->_used : m_data_64->_used);
}
-bool lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::Update() {
+template <typename D32, typename D64>
+bool
+lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::
+ Update() {
m_children.clear();
ValueObjectSP valobj_sp = m_backend.GetSP();
m_ptr_size = 0;
@@ -691,12 +802,12 @@ bool lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::Update() {
m_order = process_sp->GetByteOrder();
uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
if (m_ptr_size == 4) {
- m_data_32 = new DataDescriptor_32();
- process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
+ m_data_32 = new D32();
+ process_sp->ReadMemory(data_location, m_data_32, sizeof(D32),
error);
} else {
- m_data_64 = new DataDescriptor_64();
- process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
+ m_data_64 = new D64();
+ process_sp->ReadMemory(data_location, m_data_64, sizeof(D64),
error);
}
if (error.Fail())
@@ -704,24 +815,28 @@ bool lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::Update() {
return false;
}
-bool lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::
+template <typename D32, typename D64>
+bool
+lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::
MightHaveChildren() {
return true;
}
+template <typename D32, typename D64>
lldb::ValueObjectSP
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetChildAtIndex(
+lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::
+ GetChildAtIndex(
size_t idx) {
lldb::addr_t m_keys_ptr;
lldb::addr_t m_values_ptr;
if (m_data_32) {
- uint32_t size = m_data_32->size;
- m_keys_ptr = m_data_32->buffer;
- m_values_ptr = m_data_32->buffer + (m_ptr_size * size);
+ uint32_t size = m_data_32->GetSize();
+ m_keys_ptr = m_data_32->_buffer;
+ m_values_ptr = m_data_32->_buffer + (m_ptr_size * size);
} else {
- uint32_t size = m_data_64->size;
- m_keys_ptr = m_data_64->buffer;
- m_values_ptr = m_data_64->buffer + (m_ptr_size * size);
+ uint32_t size = m_data_64->GetSize();
+ m_keys_ptr = m_data_64->_buffer;
+ m_values_ptr = m_data_64->_buffer + (m_ptr_size * size);
}
uint32_t num_children = CalculateNumChildren();
@@ -800,22 +915,24 @@ lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetChildAtIndex(
}
-lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::
- NSDictionaryMLegacySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+lldb_private::formatters::Foundation1100::
+ NSDictionaryMSyntheticFrontEnd::
+ NSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
: SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
m_order(lldb::eByteOrderInvalid), m_data_32(nullptr), m_data_64(nullptr),
m_pair_type() {}
-lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::
- ~NSDictionaryMLegacySyntheticFrontEnd() {
+lldb_private::formatters::Foundation1100::
+ NSDictionaryMSyntheticFrontEnd::~NSDictionaryMSyntheticFrontEnd() {
delete m_data_32;
m_data_32 = nullptr;
delete m_data_64;
m_data_64 = nullptr;
}
-size_t lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::
- GetIndexOfChildWithName(const ConstString &name) {
+size_t
+lldb_private::formatters::Foundation1100::
+ NSDictionaryMSyntheticFrontEnd::GetIndexOfChildWithName(const ConstString &name) {
const char *item_name = name.GetCString();
uint32_t idx = ExtractIndexFromString(item_name);
if (idx < UINT32_MAX && idx >= CalculateNumChildren())
@@ -823,14 +940,17 @@ size_t lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::
return idx;
}
-size_t lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::
- CalculateNumChildren() {
+size_t
+lldb_private::formatters::Foundation1100::
+ NSDictionaryMSyntheticFrontEnd::CalculateNumChildren() {
if (!m_data_32 && !m_data_64)
return 0;
return (m_data_32 ? m_data_32->_used : m_data_64->_used);
}
-bool lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::Update() {
+bool
+lldb_private::formatters::Foundation1100::
+ NSDictionaryMSyntheticFrontEnd::Update() {
m_children.clear();
ValueObjectSP valobj_sp = m_backend.GetSP();
m_ptr_size = 0;
@@ -863,14 +983,15 @@ bool lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::Update() {
return false;
}
-bool lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::
- MightHaveChildren() {
+bool
+lldb_private::formatters::Foundation1100::
+ NSDictionaryMSyntheticFrontEnd::MightHaveChildren() {
return true;
}
lldb::ValueObjectSP
-lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::GetChildAtIndex(
- size_t idx) {
+lldb_private::formatters::Foundation1100::
+ NSDictionaryMSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
lldb::addr_t m_keys_ptr =
(m_data_32 ? m_data_32->_keys_addr : m_data_64->_keys_addr);
lldb::addr_t m_values_ptr =
diff --git a/source/Plugins/Language/ObjC/NSSet.cpp b/source/Plugins/Language/ObjC/NSSet.cpp
index 2f33987751699..fa2483ecc0947 100644
--- a/source/Plugins/Language/ObjC/NSSet.cpp
+++ b/source/Plugins/Language/ObjC/NSSet.cpp
@@ -135,7 +135,7 @@ namespace Foundation1300 {
GenericNSSetMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
}
-namespace Foundation1400 {
+namespace Foundation1428 {
struct DataDescriptor_32 {
uint32_t _used : 26;
uint32_t _size;
@@ -154,6 +154,64 @@ namespace Foundation1400 {
GenericNSSetMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
}
+namespace Foundation1437 {
+ struct DataDescriptor_32 {
+ uint32_t _cow;
+ // __table storage
+ uint32_t _objs_addr;
+ union {
+ uint32_t _mutations;
+ struct {
+ uint32_t _muts;
+ uint32_t _used : 26;
+ uint32_t _szidx : 6;
+ };
+ };
+ };
+
+ struct DataDescriptor_64 {
+ uint64_t _cow;
+ // __Table storage
+ uint64_t _objs_addr;
+ union {
+ uint64_t _mutations;
+ struct {
+ uint32_t _muts;
+ uint32_t _used : 26;
+ uint32_t _szidx : 6;
+ };
+ };
+ };
+
+ using NSSetMSyntheticFrontEnd =
+ GenericNSSetMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
+
+ template <typename DD>
+ uint64_t
+ __NSSetMSize_Impl(lldb_private::Process &process, lldb::addr_t valobj_addr,
+ Status &error) {
+ const lldb::addr_t start_of_descriptor =
+ valobj_addr + process.GetAddressByteSize();
+ DD descriptor = DD();
+ process.ReadMemory(start_of_descriptor, &descriptor, sizeof(descriptor),
+ error);
+ if (error.Fail()) {
+ return 0;
+ }
+ return descriptor._used;
+ }
+
+ uint64_t
+ __NSSetMSize(lldb_private::Process &process, lldb::addr_t valobj_addr,
+ Status &error) {
+ if (process.GetAddressByteSize() == 4) {
+ return __NSSetMSize_Impl<DataDescriptor_32>(process, valobj_addr, error);
+ } else {
+ return __NSSetMSize_Impl<DataDescriptor_64>(process, valobj_addr, error);
+ }
+ }
+}
+
class NSSetCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
NSSetCodeRunningSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
@@ -219,12 +277,18 @@ bool lldb_private::formatters::NSSetSummaryProvider(
return false;
value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
} else if (!strcmp(class_name, "__NSSetM")) {
+ AppleObjCRuntime *apple_runtime =
+ llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
Status error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
- ptr_size, 0, error);
+ if (apple_runtime && apple_runtime->GetFoundationVersion() >= 1437) {
+ value = Foundation1437::__NSSetMSize(*process_sp, valobj_addr, error);
+ } else {
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
+ ptr_size, 0, error);
+ value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
+ }
if (error.Fail())
return false;
- value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
}
/*else if (!strcmp(class_name,"__NSCFSet"))
{
@@ -312,10 +376,16 @@ lldb_private::formatters::NSSetSyntheticFrontEndCreator(
} else if (!strcmp(class_name, "__NSSetM")) {
AppleObjCRuntime *apple_runtime =
llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
- if (apple_runtime && apple_runtime->GetFoundationVersion() >= 1400)
- return (new Foundation1400::NSSetMSyntheticFrontEnd(valobj_sp));
- else
+ if (apple_runtime) {
+ if (apple_runtime->GetFoundationVersion() >= 1437)
+ return (new Foundation1437::NSSetMSyntheticFrontEnd(valobj_sp));
+ else if (apple_runtime->GetFoundationVersion() >= 1428)
+ return (new Foundation1428::NSSetMSyntheticFrontEnd(valobj_sp));
+ else
+ return (new Foundation1300::NSSetMSyntheticFrontEnd(valobj_sp));
+ } else {
return (new Foundation1300::NSSetMSyntheticFrontEnd(valobj_sp));
+ }
} else {
auto &map(NSSet_Additionals::GetAdditionalSynthetics());
auto iter = map.find(class_name_cs), end = map.end();
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
index e99fd74a352f4..105c088b9e913 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
@@ -324,8 +324,6 @@ public:
clang::ASTContext &ast_ctx(interface_decl->getASTContext());
- clang::QualType return_qual_type;
-
const bool isInstance = instance;
const bool isVariadic = false;
const bool isSynthesized = false;
@@ -653,3 +651,11 @@ AppleObjCDeclVendor::FindDecls(const ConstString &name, bool append,
return ret;
}
+
+clang::ExternalASTMerger::ImporterSource
+AppleObjCDeclVendor::GetImporterSource() {
+ return {*m_ast_ctx.getASTContext(),
+ *m_ast_ctx.getFileManager(),
+ m_ast_ctx.GetOriginMap()
+ };
+}
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
index 26824079d945e..2f087da16bc18 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
@@ -30,6 +30,8 @@ public:
uint32_t FindDecls(const ConstString &name, bool append, uint32_t max_matches,
std::vector<clang::NamedDecl *> &decls) override;
+ clang::ExternalASTMerger::ImporterSource GetImporterSource() override;
+
friend class AppleObjCExternalASTSource;
private:
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
index 57d98fbd72834..1b22ee4c3be17 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
@@ -95,6 +95,8 @@ public:
virtual void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true,
lldb::addr_t &cf_false);
+
+ virtual bool IsTaggedPointer (lldb::addr_t addr) { return false; }
protected:
// Call CreateInstance instead.
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index 2a7735959a910..bdf79f7b82bd1 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -62,6 +62,11 @@
#include "AppleObjCTrampolineHandler.h"
#include "AppleObjCTypeEncodingParser.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
+
+#include <vector>
+
using namespace lldb;
using namespace lldb_private;
@@ -394,7 +399,7 @@ AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process,
}
bool AppleObjCRuntimeV2::GetDynamicTypeAndAddress(
- ValueObject &in_value, DynamicValueType use_dynamic,
+ ValueObject &in_value, lldb::DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name, Address &address,
Value::ValueType &value_type) {
// We should never get here with a null process...
@@ -811,85 +816,43 @@ UtilityFunction *AppleObjCRuntimeV2::CreateObjectChecker(const char *name) {
int len = 0;
if (m_has_object_getClass) {
- len = ::snprintf(check_function_code, sizeof(check_function_code),
- "extern \"C\" void *gdb_object_getClass(void *); "
- " \n"
- "extern \"C\" int printf(const char *format, ...); "
- " \n"
- "extern \"C\" void "
- " \n"
- "%s(void *$__lldb_arg_obj, void *$__lldb_arg_selector) "
- " \n"
- "{ "
- " \n"
- " if ($__lldb_arg_obj == (void *)0) "
- " \n"
- " return; // nil is ok "
- " \n"
- " if (!gdb_object_getClass($__lldb_arg_obj)) "
- " \n"
- " *((volatile int *)0) = 'ocgc'; "
- " \n"
- " else if ($__lldb_arg_selector != (void *)0) "
- " \n"
- " { "
- " \n"
- " signed char responds = (signed char) [(id) "
- "$__lldb_arg_obj \n"
- " "
- "respondsToSelector: \n"
- " (struct "
- "objc_selector *) $__lldb_arg_selector]; \n"
- " if (responds == (signed char) 0) "
- " \n"
- " *((volatile int *)0) = 'ocgc'; "
- " \n"
- " } "
- " \n"
- "} "
- " \n",
- name);
+ len = ::snprintf(check_function_code, sizeof(check_function_code), R"(
+ extern "C" void *gdb_object_getClass(void *);
+ extern "C" int printf(const char *format, ...);
+ extern "C" void
+ %s(void *$__lldb_arg_obj, void *$__lldb_arg_selector) {
+ if ($__lldb_arg_obj == (void *)0)
+ return; // nil is ok
+ if (!gdb_object_getClass($__lldb_arg_obj)) {
+ *((volatile int *)0) = 'ocgc';
+ } else if ($__lldb_arg_selector != (void *)0) {
+ signed char $responds = (signed char)
+ [(id)$__lldb_arg_obj respondsToSelector:
+ (void *) $__lldb_arg_selector];
+ if ($responds == (signed char) 0)
+ *((volatile int *)0) = 'ocgc';
+ }
+ })", name);
} else {
- len = ::snprintf(check_function_code, sizeof(check_function_code),
- "extern \"C\" void *gdb_class_getClass(void *); "
- " \n"
- "extern \"C\" int printf(const char *format, ...); "
- " \n"
- "extern \"C\" void "
- " \n"
- "%s(void *$__lldb_arg_obj, void *$__lldb_arg_selector) "
- " \n"
- "{ "
- " \n"
- " if ($__lldb_arg_obj == (void *)0) "
- " \n"
- " return; // nil is ok "
- " \n"
- " void **$isa_ptr = (void **)$__lldb_arg_obj; "
- " \n"
- " if (*$isa_ptr == (void *)0 || "
- "!gdb_class_getClass(*$isa_ptr)) \n"
- " *((volatile int *)0) = 'ocgc'; "
- " \n"
- " else if ($__lldb_arg_selector != (void *)0) "
- " \n"
- " { "
- " \n"
- " signed char responds = (signed char) [(id) "
- "$__lldb_arg_obj \n"
- " "
- "respondsToSelector: \n"
- " (struct "
- "objc_selector *) $__lldb_arg_selector]; \n"
- " if (responds == (signed char) 0) "
- " \n"
- " *((volatile int *)0) = 'ocgc'; "
- " \n"
- " } "
- " \n"
- "} "
- " \n",
- name);
+ len = ::snprintf(check_function_code, sizeof(check_function_code), R"(
+ extern "C" void *gdb_class_getClass(void *);
+ extern "C" int printf(const char *format, ...);
+ extern "C" void
+ %s(void *$__lldb_arg_obj, void *$__lldb_arg_selector) {
+ if ($__lldb_arg_obj == (void *)0)
+ return; // nil is ok
+ void **$isa_ptr = (void **)$__lldb_arg_obj;
+ if (*$isa_ptr == (void *)0 ||
+ !gdb_class_getClass(*$isa_ptr))
+ *((volatile int *)0) = 'ocgc';
+ else if ($__lldb_arg_selector != (void *)0) {
+ signed char $responds = (signed char)
+ [(id)$__lldb_arg_obj respondsToSelector:
+ (void *) $__lldb_arg_selector];
+ if ($responds == (signed char) 0)
+ *((volatile int *)0) = 'ocgc';
+ }
+ })", name);
}
assert(len < (int)sizeof(check_function_code));
@@ -2022,6 +1985,8 @@ AppleObjCRuntimeV2::NonPointerISACache::CreateInstance(
Status error;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES));
+
auto objc_debug_isa_magic_mask = ExtractRuntimeGlobalSymbol(
process, ConstString("objc_debug_isa_magic_mask"), objc_module_sp, error);
if (error.Fail())
@@ -2038,12 +2003,47 @@ AppleObjCRuntimeV2::NonPointerISACache::CreateInstance(
if (error.Fail())
return NULL;
+ if (log)
+ log->PutCString("AOCRT::NPI: Found all the non-indexed ISA masks");
+
+ bool foundError = false;
+ auto objc_debug_indexed_isa_magic_mask = ExtractRuntimeGlobalSymbol(
+ process, ConstString("objc_debug_indexed_isa_magic_mask"), objc_module_sp,
+ error);
+ foundError |= error.Fail();
+
+ auto objc_debug_indexed_isa_magic_value = ExtractRuntimeGlobalSymbol(
+ process, ConstString("objc_debug_indexed_isa_magic_value"),
+ objc_module_sp, error);
+ foundError |= error.Fail();
+
+ auto objc_debug_indexed_isa_index_mask = ExtractRuntimeGlobalSymbol(
+ process, ConstString("objc_debug_indexed_isa_index_mask"), objc_module_sp,
+ error);
+ foundError |= error.Fail();
+
+ auto objc_debug_indexed_isa_index_shift = ExtractRuntimeGlobalSymbol(
+ process, ConstString("objc_debug_indexed_isa_index_shift"),
+ objc_module_sp, error);
+ foundError |= error.Fail();
+
+ auto objc_indexed_classes =
+ ExtractRuntimeGlobalSymbol(process, ConstString("objc_indexed_classes"),
+ objc_module_sp, error, false);
+ foundError |= error.Fail();
+
+ if (log)
+ log->PutCString("AOCRT::NPI: Found all the indexed ISA masks");
+
// we might want to have some rules to outlaw these other values (e.g if the
// mask is zero but the value is non-zero, ...)
- return new NonPointerISACache(runtime, objc_debug_isa_class_mask,
- objc_debug_isa_magic_mask,
- objc_debug_isa_magic_value);
+ return new NonPointerISACache(
+ runtime, objc_module_sp, objc_debug_isa_class_mask,
+ objc_debug_isa_magic_mask, objc_debug_isa_magic_value,
+ objc_debug_indexed_isa_magic_mask, objc_debug_indexed_isa_magic_value,
+ objc_debug_indexed_isa_index_mask, objc_debug_indexed_isa_index_shift,
+ foundError ? 0 : objc_indexed_classes);
}
AppleObjCRuntimeV2::TaggedPointerVendorV2 *
@@ -2371,12 +2371,23 @@ AppleObjCRuntimeV2::TaggedPointerVendorExtended::GetClassDescriptor(
}
AppleObjCRuntimeV2::NonPointerISACache::NonPointerISACache(
- AppleObjCRuntimeV2 &runtime, uint64_t objc_debug_isa_class_mask,
- uint64_t objc_debug_isa_magic_mask, uint64_t objc_debug_isa_magic_value)
- : m_runtime(runtime), m_cache(),
+ AppleObjCRuntimeV2 &runtime, const ModuleSP &objc_module_sp,
+ uint64_t objc_debug_isa_class_mask, uint64_t objc_debug_isa_magic_mask,
+ uint64_t objc_debug_isa_magic_value,
+ uint64_t objc_debug_indexed_isa_magic_mask,
+ uint64_t objc_debug_indexed_isa_magic_value,
+ uint64_t objc_debug_indexed_isa_index_mask,
+ uint64_t objc_debug_indexed_isa_index_shift,
+ lldb::addr_t objc_indexed_classes)
+ : m_runtime(runtime), m_cache(), m_objc_module_wp(objc_module_sp),
m_objc_debug_isa_class_mask(objc_debug_isa_class_mask),
m_objc_debug_isa_magic_mask(objc_debug_isa_magic_mask),
- m_objc_debug_isa_magic_value(objc_debug_isa_magic_value) {}
+ m_objc_debug_isa_magic_value(objc_debug_isa_magic_value),
+ m_objc_debug_indexed_isa_magic_mask(objc_debug_indexed_isa_magic_mask),
+ m_objc_debug_indexed_isa_magic_value(objc_debug_indexed_isa_magic_value),
+ m_objc_debug_indexed_isa_index_mask(objc_debug_indexed_isa_index_mask),
+ m_objc_debug_indexed_isa_index_shift(objc_debug_indexed_isa_index_shift),
+ m_objc_indexed_classes(objc_indexed_classes), m_indexed_isa_cache() {}
ObjCLanguageRuntime::ClassDescriptorSP
AppleObjCRuntimeV2::NonPointerISACache::GetClassDescriptor(ObjCISA isa) {
@@ -2395,8 +2406,106 @@ AppleObjCRuntimeV2::NonPointerISACache::GetClassDescriptor(ObjCISA isa) {
bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA(
ObjCISA isa, ObjCISA &ret_isa) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES));
+
+ if (log)
+ log->Printf("AOCRT::NPI Evalulate(isa = 0x%" PRIx64 ")", (uint64_t)isa);
+
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 (m_objc_debug_indexed_isa_magic_mask &&
+ m_objc_debug_indexed_isa_magic_value &&
+ m_objc_debug_indexed_isa_index_mask &&
+ m_objc_debug_indexed_isa_index_shift && m_objc_indexed_classes) {
+ if ((isa & ~m_objc_debug_indexed_isa_index_mask) == 0)
+ return false;
+
+ if ((isa & m_objc_debug_indexed_isa_magic_mask) ==
+ m_objc_debug_indexed_isa_magic_value) {
+ // 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 (index > m_indexed_isa_cache.size()) {
+ if (log)
+ log->Printf("AOCRT::NPI (index = %" PRIu64
+ ") exceeds cache (size = %" PRIu64 ")",
+ (uint64_t)index, (uint64_t)m_indexed_isa_cache.size());
+
+ Process *process(m_runtime.GetProcess());
+
+ ModuleSP objc_module_sp(m_objc_module_wp.lock());
+ if (!objc_module_sp)
+ return false;
+
+ Status error;
+ auto objc_indexed_classes_count = ExtractRuntimeGlobalSymbol(
+ process, ConstString("objc_indexed_classes_count"), objc_module_sp,
+ error);
+ if (error.Fail())
+ return false;
+
+ if (log)
+ log->Printf("AOCRT::NPI (new class count = %" PRIu64 ")",
+ (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.
+ auto num_new_classes =
+ objc_indexed_classes_count - m_indexed_isa_cache.size();
+ const uint32_t addr_size = process->GetAddressByteSize();
+ DataBufferHeap buffer(num_new_classes * addr_size, 0);
+
+ lldb::addr_t last_read_class =
+ m_objc_indexed_classes + (m_indexed_isa_cache.size() * addr_size);
+ size_t bytes_read = process->ReadMemory(
+ last_read_class, buffer.GetBytes(), buffer.GetByteSize(), error);
+ if (error.Fail() || bytes_read != buffer.GetByteSize())
+ return false;
+
+ if (log)
+ log->Printf("AOCRT::NPI (read new classes count = %" PRIu64 ")",
+ (uint64_t)num_new_classes);
+
+ // Append the new entries to the existing cache.
+ DataExtractor data(buffer.GetBytes(), buffer.GetByteSize(),
+ process->GetByteOrder(),
+ process->GetAddressByteSize());
+
+ lldb::offset_t offset = 0;
+ for (unsigned i = 0; i != num_new_classes; ++i)
+ m_indexed_isa_cache.push_back(data.GetPointer(&offset));
+ }
+ }
+
+ // If the index is still out of range then this isn't a pointer.
+ if (index > m_indexed_isa_cache.size())
+ return false;
+
+ if (log)
+ log->Printf("AOCRT::NPI Evalulate(ret_isa = 0x%" PRIx64 ")",
+ (uint64_t)m_indexed_isa_cache[index]);
+
+ ret_isa = m_indexed_isa_cache[index];
+ return (ret_isa != 0); // this is a pointer so 0 is not a valid value
+ }
+
+ return false;
+ }
+
+ // 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
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
index 7180730904062..89e81d5b181e1 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
@@ -88,6 +88,8 @@ public:
EncodingToTypeSP GetEncodingToType() override;
+ bool IsTaggedPointer(lldb::addr_t ptr) override;
+
TaggedPointerVendor *GetTaggedPointerVendor() override {
return m_tagged_pointer_vendor_ap.get();
}
@@ -138,18 +140,33 @@ private:
private:
NonPointerISACache(AppleObjCRuntimeV2 &runtime,
+ const lldb::ModuleSP &objc_module_sp,
uint64_t objc_debug_isa_class_mask,
uint64_t objc_debug_isa_magic_mask,
- uint64_t objc_debug_isa_magic_value);
+ uint64_t objc_debug_isa_magic_value,
+ uint64_t objc_debug_indexed_isa_magic_mask,
+ uint64_t objc_debug_indexed_isa_magic_value,
+ uint64_t objc_debug_indexed_isa_index_mask,
+ uint64_t objc_debug_indexed_isa_index_shift,
+ lldb::addr_t objc_indexed_classes);
bool EvaluateNonPointerISA(ObjCISA isa, ObjCISA &ret_isa);
AppleObjCRuntimeV2 &m_runtime;
std::map<ObjCISA, ObjCLanguageRuntime::ClassDescriptorSP> m_cache;
+ lldb::ModuleWP m_objc_module_wp;
uint64_t m_objc_debug_isa_class_mask;
uint64_t m_objc_debug_isa_magic_mask;
uint64_t m_objc_debug_isa_magic_value;
+ uint64_t m_objc_debug_indexed_isa_magic_mask;
+ uint64_t m_objc_debug_indexed_isa_magic_value;
+ uint64_t m_objc_debug_indexed_isa_index_mask;
+ uint64_t m_objc_debug_indexed_isa_index_shift;
+ lldb::addr_t m_objc_indexed_classes;
+
+ std::vector<lldb::addr_t> m_indexed_isa_cache;
+
friend class AppleObjCRuntimeV2;
DISALLOW_COPY_AND_ASSIGN(NonPointerISACache);
@@ -279,8 +296,6 @@ private:
ObjCISA GetPointerISA(ObjCISA isa);
- bool IsTaggedPointer(lldb::addr_t ptr);
-
lldb::addr_t GetISAHashTablePointer();
bool UpdateISAToDescriptorMapFromMemory(RemoteNXMapTable &hash_table);
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
index 7e46afcccdab3..ad1083be02850 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
@@ -3615,13 +3615,15 @@ RenderScriptRuntime::CreateKernelBreakpoint(const ConstString &name) {
}
BreakpointResolverSP resolver_sp(new RSBreakpointResolver(nullptr, name));
- BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(
+ Target &target = GetProcess()->GetTarget();
+ BreakpointSP bp = target.CreateBreakpoint(
m_filtersp, resolver_sp, false, false, false);
// Give RS breakpoints a specific name, so the user can manipulate them as a
// group.
Status err;
- if (!bp->AddName("RenderScriptKernel", err))
+ target.AddNameToBreakpoint(bp, "RenderScriptKernel", err);
+ if (err.Fail() && log)
if (log)
log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
err.AsCString());
@@ -3643,14 +3645,15 @@ RenderScriptRuntime::CreateReductionBreakpoint(const ConstString &name,
BreakpointResolverSP resolver_sp(new RSReduceBreakpointResolver(
nullptr, name, &m_rsmodules, kernel_types));
- BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(
+ Target &target = GetProcess()->GetTarget();
+ BreakpointSP bp = target.CreateBreakpoint(
m_filtersp, resolver_sp, false, false, false);
// Give RS breakpoints a specific name, so the user can manipulate them as a
// group.
Status err;
- if (!bp->AddName("RenderScriptReduction", err))
- if (log)
+ target.AddNameToBreakpoint(bp, "RenderScriptReduction", err);
+ if (err.Fail() && log)
log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
err.AsCString());
@@ -3885,15 +3888,16 @@ RenderScriptRuntime::CreateScriptGroupBreakpoint(const ConstString &name,
BreakpointResolverSP resolver_sp(new RSScriptGroupBreakpointResolver(
nullptr, name, m_scriptGroups, stop_on_all));
- BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(
+ Target &target = GetProcess()->GetTarget();
+ BreakpointSP bp = target.CreateBreakpoint(
m_filtersp, resolver_sp, false, false, false);
// Give RS breakpoints a specific name, so the user can manipulate them as a
// group.
Status err;
- if (!bp->AddName(name.AsCString(), err))
- if (log)
- log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
- err.AsCString());
+ target.AddNameToBreakpoint(bp, name.GetCString(), err);
+ if (err.Fail() && log)
+ log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
+ err.AsCString());
// ask the breakpoint to resolve itself
bp->ResolveBreakpoint();
return bp;
diff --git a/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp b/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
index 25bfce7a2b835..d7bef836d9d87 100644
--- a/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
+++ b/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
@@ -27,12 +27,12 @@ typedef struct ar_hdr {
#include <ar.h>
#endif
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBufferLLVM.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/Timer.h"
diff --git a/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h b/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
index 0e10d47f2ce46..cb63eccff65e5 100644
--- a/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
+++ b/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
@@ -10,10 +10,9 @@
#ifndef liblldb_ObjectContainerBSDArchive_h_
#define liblldb_ObjectContainerBSDArchive_h_
-// Project includes
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Symbol/ObjectContainer.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/FileSpec.h"
diff --git a/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp b/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
index 31eb17873f3e4..0266bbe27e7d7 100644
--- a/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
+++ b/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
@@ -8,12 +8,12 @@
//===----------------------------------------------------------------------===//
#include "ObjectContainerUniversalMachO.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/Stream.h"
diff --git a/source/Plugins/ObjectFile/ELF/CMakeLists.txt b/source/Plugins/ObjectFile/ELF/CMakeLists.txt
index e0680b07efc55..45a4edcbb1c9e 100644
--- a/source/Plugins/ObjectFile/ELF/CMakeLists.txt
+++ b/source/Plugins/ObjectFile/ELF/CMakeLists.txt
@@ -9,5 +9,6 @@ add_lldb_library(lldbPluginObjectFileELF PLUGIN
lldbTarget
LINK_COMPONENTS
BinaryFormat
+ Object
Support
)
diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 3b33cf1601fb7..17d892450e4de 100644
--- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -13,7 +13,6 @@
#include <cassert>
#include <unordered_map>
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/FileSpecList.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
@@ -23,6 +22,8 @@
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataBufferLLVM.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
@@ -31,6 +32,7 @@
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Object/Decompressor.h"
#include "llvm/Support/ARMBuildAttributes.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -405,7 +407,7 @@ ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp,
lldb::offset_t length) {
if (!data_sp) {
data_sp =
- DataBufferLLVM::CreateSliceFromPath(file->GetPath(), length, file_offset);
+ DataBufferLLVM::CreateSliceFromPath(file->GetPath(), length, file_offset, true);
if (!data_sp)
return nullptr;
data_offset = 0;
@@ -423,7 +425,7 @@ ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp,
// Update the data to contain the entire file if it doesn't already
if (data_sp->GetByteSize() < length) {
data_sp =
- DataBufferLLVM::CreateSliceFromPath(file->GetPath(), length, file_offset);
+ DataBufferLLVM::CreateSliceFromPath(file->GetPath(), length, file_offset, true);
if (!data_sp)
return nullptr;
data_offset = 0;
@@ -451,7 +453,7 @@ ObjectFile *ObjectFileELF::CreateMemoryInstance(
if (ELFHeader::MagicBytesMatch(magic)) {
unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
if (address_size == 4 || address_size == 8) {
- std::auto_ptr<ObjectFileELF> objfile_ap(
+ std::unique_ptr<ObjectFileELF> objfile_ap(
new ObjectFileELF(module_sp, data_sp, process_sp, header_addr));
ArchSpec spec;
if (objfile_ap->GetArchitecture(spec) &&
@@ -1818,6 +1820,12 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
if (!m_sections_ap.get() && ParseSectionHeaders()) {
m_sections_ap.reset(new SectionList());
+ // Object files frequently have 0 for every section address, meaning we
+ // need to compute synthetic addresses in order for "file addresses" from
+ // different sections to not overlap
+ bool synthaddrs = (CalculateType() == ObjectFile::Type::eTypeObjectFile);
+ uint64_t nextaddr = 0;
+
for (SectionHeaderCollIter I = m_section_headers.begin();
I != m_section_headers.end(); ++I) {
const ELFSectionHeaderInfo &header = *I;
@@ -1835,6 +1843,7 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
static ConstString g_sect_name_dwarf_debug_abbrev(".debug_abbrev");
static ConstString g_sect_name_dwarf_debug_addr(".debug_addr");
static ConstString g_sect_name_dwarf_debug_aranges(".debug_aranges");
+ static ConstString g_sect_name_dwarf_debug_cu_index(".debug_cu_index");
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");
@@ -1904,6 +1913,8 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
sect_type = eSectionTypeDWARFDebugAddr;
else if (name == g_sect_name_dwarf_debug_aranges)
sect_type = eSectionTypeDWARFDebugAranges;
+ else if (name == g_sect_name_dwarf_debug_cu_index)
+ sect_type = eSectionTypeDWARFDebugCuIndex;
else if (name == g_sect_name_dwarf_debug_frame)
sect_type = eSectionTypeDWARFDebugFrame;
else if (name == g_sect_name_dwarf_debug_info)
@@ -1987,9 +1998,18 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
? m_arch_spec.GetDataByteSize()
: eSectionTypeCode == sect_type ? m_arch_spec.GetCodeByteSize()
: 1;
-
elf::elf_xword log2align =
(header.sh_addralign == 0) ? 0 : llvm::Log2_64(header.sh_addralign);
+
+ uint64_t addr = header.sh_addr;
+
+ if ((header.sh_flags & SHF_ALLOC) && synthaddrs) {
+ nextaddr =
+ (nextaddr + header.sh_addralign - 1) & ~(header.sh_addralign - 1);
+ addr = nextaddr;
+ nextaddr += vm_size;
+ }
+
SectionSP section_sp(new Section(
GetModule(), // Module to which this section belongs.
this, // ObjectFile to which this section belongs and should read
@@ -1997,7 +2017,7 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
SectionIndex(I), // Section ID.
name, // Section name.
sect_type, // Section type.
- header.sh_addr, // VM address.
+ addr, // VM address.
vm_size, // VM size in bytes of this section.
header.sh_offset, // Offset of this section in the file.
file_size, // Size of the section as found in the file.
@@ -2015,13 +2035,14 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
if (m_sections_ap.get()) {
if (GetType() == eTypeDebugInfo) {
static const SectionType g_sections[] = {
- eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr,
- eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugFrame,
- eSectionTypeDWARFDebugInfo, eSectionTypeDWARFDebugLine,
- eSectionTypeDWARFDebugLoc, eSectionTypeDWARFDebugMacInfo,
- eSectionTypeDWARFDebugPubNames, eSectionTypeDWARFDebugPubTypes,
- eSectionTypeDWARFDebugRanges, eSectionTypeDWARFDebugStr,
- eSectionTypeDWARFDebugStrOffsets, eSectionTypeELFSymbolTable,
+ 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]);
@@ -2714,7 +2735,7 @@ ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, user_id_t start_id,
rel_data, symtab_data, strtab_data);
}
-unsigned ObjectFileELF::RelocateSection(
+unsigned ObjectFileELF::ApplyRelocations(
Symtab *symtab, const ELFHeader *hdr, const ELFSectionHeader *rel_hdr,
const ELFSectionHeader *symtab_hdr, const ELFSectionHeader *debug_hdr,
DataExtractor &rel_data, DataExtractor &symtab_data,
@@ -2745,6 +2766,14 @@ unsigned ObjectFileELF::RelocateSection(
case R_386_32:
case R_386_PC32:
default:
+ // FIXME: This asserts with this input:
+ //
+ // foo.cpp
+ // int main(int argc, char **argv) { return 0; }
+ //
+ // clang++.exe --target=i686-unknown-linux-gnu -g -c foo.cpp -o foo.o
+ //
+ // and running this on the foo.o module.
assert(false && "unexpected relocation type");
}
} else {
@@ -2791,7 +2820,8 @@ unsigned ObjectFileELF::RelocateSection(
}
unsigned ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr,
- user_id_t rel_id) {
+ user_id_t rel_id,
+ lldb_private::Symtab *thetab) {
assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
// Parse in the section list if needed.
@@ -2827,10 +2857,11 @@ unsigned ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr,
DataExtractor symtab_data;
DataExtractor debug_data;
- if (ReadSectionData(rel, rel_data) && ReadSectionData(symtab, symtab_data) &&
- ReadSectionData(debug, debug_data)) {
- RelocateSection(m_symtab_ap.get(), &m_header, rel_hdr, symtab_hdr,
- debug_hdr, rel_data, symtab_data, debug_data, debug);
+ if (GetData(rel->GetFileOffset(), rel->GetFileSize(), rel_data) &&
+ GetData(symtab->GetFileOffset(), symtab->GetFileSize(), symtab_data) &&
+ GetData(debug->GetFileOffset(), debug->GetFileSize(), debug_data)) {
+ ApplyRelocations(thetab, &m_header, rel_hdr, symtab_hdr, debug_hdr,
+ rel_data, symtab_data, debug_data, debug);
}
return 0;
@@ -2924,21 +2955,48 @@ Symtab *ObjectFileELF::GetSymtab() {
m_symtab_ap->CalculateSymbolSizes();
}
+ return m_symtab_ap.get();
+}
+
+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.
+ section->SetIsRelocated(true);
+
+ // We only relocate in ELF relocatable files
+ if (CalculateType() != eTypeObjectFile)
+ return;
+
+ const char *section_name = section->GetName().GetCString();
+ // Can't relocate that which can't be named
+ if (section_name == nullptr)
+ return;
+
+ // We don't relocate non-debug sections at the moment
+ if (strncmp(section_name, debug_prefix, strlen(debug_prefix)))
+ return;
+
+ // Relocation section names to look for
+ std::string needle = std::string(".rel") + section_name;
+ std::string needlea = std::string(".rela") + section_name;
+
for (SectionHeaderCollIter I = m_section_headers.begin();
I != m_section_headers.end(); ++I) {
if (I->sh_type == SHT_RELA || I->sh_type == SHT_REL) {
- if (CalculateType() == eTypeObjectFile) {
- const char *section_name = I->section_name.AsCString("");
- if (strstr(section_name, ".rela.debug") ||
- strstr(section_name, ".rel.debug")) {
- const ELFSectionHeader &reloc_header = *I;
- user_id_t reloc_id = SectionIndex(I);
- RelocateDebugSections(&reloc_header, reloc_id);
- }
+ const char *hay_name = I->section_name.GetCString();
+ if (hay_name == nullptr)
+ continue;
+ if (needle == hay_name || needlea == hay_name) {
+ const ELFSectionHeader &reloc_header = *I;
+ user_id_t reloc_id = SectionIndex(I);
+ RelocateDebugSections(&reloc_header, reloc_id, GetSymtab());
+ break;
}
}
}
- return m_symtab_ap.get();
}
void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table,
@@ -3404,3 +3462,56 @@ ObjectFile::Strata ObjectFileELF::CalculateStrata() {
}
return eStrataUnknown;
}
+
+size_t ObjectFileELF::ReadSectionData(Section *section,
+ lldb::offset_t section_offset, void *dst,
+ size_t dst_len) {
+ // If some other objectfile owns this data, pass this to them.
+ if (section->GetObjectFile() != this)
+ return section->GetObjectFile()->ReadSectionData(section, section_offset,
+ dst, dst_len);
+
+ if (!section->Test(SHF_COMPRESSED))
+ return ObjectFile::ReadSectionData(section, section_offset, dst, dst_len);
+
+ // For compressed sections we need to read to full data to be able to
+ // decompress.
+ DataExtractor data;
+ ReadSectionData(section, data);
+ return data.CopyData(section_offset, dst_len, dst);
+}
+
+size_t ObjectFileELF::ReadSectionData(Section *section,
+ DataExtractor &section_data) {
+ // If some other objectfile owns this data, pass this to them.
+ if (section->GetObjectFile() != this)
+ return section->GetObjectFile()->ReadSectionData(section, section_data);
+
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES);
+
+ size_t result = ObjectFile::ReadSectionData(section, section_data);
+ if (result == 0 || !section->Test(SHF_COMPRESSED))
+ return result;
+
+ auto Decompressor = llvm::object::Decompressor::create(
+ section->GetName().GetStringRef(),
+ {reinterpret_cast<const char *>(section_data.GetDataStart()),
+ 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()));
+ return result;
+ }
+ auto buffer_sp =
+ std::make_shared<DataBufferHeap>(Decompressor->getDecompressedSize(), 0);
+ 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)));
+ return result;
+ }
+ section_data.SetData(buffer_sp);
+ return buffer_sp->GetByteSize();
+}
diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
index 6d8717b0ef25e..2909f4e52e4aa 100644
--- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -16,10 +16,8 @@
// C++ Includes
#include <vector>
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/UUID.h"
#include "lldb/lldb-private.h"
@@ -142,6 +140,13 @@ public:
ObjectFile::Strata CalculateStrata() override;
+ size_t ReadSectionData(lldb_private::Section *section,
+ lldb::offset_t section_offset, void *dst,
+ size_t dst_len) override;
+
+ size_t ReadSectionData(lldb_private::Section *section,
+ lldb_private::DataExtractor &section_data) override;
+
// Returns number of program headers found in the ELF file.
size_t GetProgramHeaderCount();
@@ -154,6 +159,8 @@ public:
llvm::StringRef
StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const override;
+ void RelocateSection(lldb_private::Section *section) override;
+
private:
ObjectFileELF(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
lldb::offset_t data_offset, const lldb_private::FileSpec *file,
@@ -296,17 +303,18 @@ private:
/// Relocates debug sections
unsigned RelocateDebugSections(const elf::ELFSectionHeader *rel_hdr,
- lldb::user_id_t rel_id);
-
- unsigned RelocateSection(lldb_private::Symtab *symtab,
- const elf::ELFHeader *hdr,
- const elf::ELFSectionHeader *rel_hdr,
- const elf::ELFSectionHeader *symtab_hdr,
- const elf::ELFSectionHeader *debug_hdr,
- lldb_private::DataExtractor &rel_data,
- lldb_private::DataExtractor &symtab_data,
- lldb_private::DataExtractor &debug_data,
- lldb_private::Section *rel_section);
+ lldb::user_id_t rel_id,
+ lldb_private::Symtab *thetab);
+
+ unsigned ApplyRelocations(lldb_private::Symtab *symtab,
+ const elf::ELFHeader *hdr,
+ const elf::ELFSectionHeader *rel_hdr,
+ const elf::ELFSectionHeader *symtab_hdr,
+ const elf::ELFSectionHeader *debug_hdr,
+ lldb_private::DataExtractor &rel_data,
+ lldb_private::DataExtractor &symtab_data,
+ lldb_private::DataExtractor &debug_data,
+ lldb_private::Section *rel_section);
/// Loads the section name string table into m_shstr_data. Returns the
/// number of bytes constituting the table.
diff --git a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
index 06406c6f16556..a9ab366fbf53e 100644
--- a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
+++ b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
@@ -10,8 +10,6 @@
#include "llvm/ADT/StringRef.h"
#include "ObjectFileJIT.h"
-
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/FileSpecList.h"
#include "lldb/Core/Module.h"
@@ -26,6 +24,7 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/FileSpec.h"
@@ -230,9 +229,9 @@ bool ObjectFileJIT::SetLoadAddress(Target &target, lldb::addr_t value,
return num_loaded_sections > 0;
}
-size_t ObjectFileJIT::ReadSectionData(const lldb_private::Section *section,
+size_t ObjectFileJIT::ReadSectionData(lldb_private::Section *section,
lldb::offset_t section_offset, void *dst,
- size_t dst_len) const {
+ size_t dst_len) {
lldb::offset_t file_size = section->GetFileSize();
if (section_offset < file_size) {
size_t src_len = file_size - section_offset;
@@ -248,8 +247,8 @@ size_t ObjectFileJIT::ReadSectionData(const lldb_private::Section *section,
}
size_t ObjectFileJIT::ReadSectionData(
- const lldb_private::Section *section,
- lldb_private::DataExtractor &section_data) const {
+ lldb_private::Section *section,
+ lldb_private::DataExtractor &section_data) {
if (section->GetFileSize()) {
const void *src = (void *)(uintptr_t)section->GetFileOffset();
diff --git a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
index a211645d5d8b3..c964906a5e8e7 100644
--- a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
+++ b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
@@ -83,13 +83,13 @@ public:
uint32_t GetDependentModules(lldb_private::FileSpecList &files) override;
- size_t ReadSectionData(const lldb_private::Section *section,
+ size_t ReadSectionData(lldb_private::Section *section,
lldb::offset_t section_offset, void *dst,
- size_t dst_len) const override;
+ size_t dst_len) override;
size_t
- ReadSectionData(const lldb_private::Section *section,
- lldb_private::DataExtractor &section_data) const override;
+ ReadSectionData(lldb_private::Section *section,
+ lldb_private::DataExtractor &section_data) override;
lldb_private::Address GetEntryPointAddress() override;
diff --git a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 9bc171e454c98..df334f88ee3b4 100644
--- a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -17,7 +17,6 @@
#include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h"
#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/FileSpecList.h"
#include "lldb/Core/Module.h"
@@ -38,6 +37,7 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadList.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBufferLLVM.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
@@ -686,7 +686,7 @@ public:
case FPURegSet: {
uint8_t *fpu_reg_buf = (uint8_t *)&fpu.v[0];
const int fpu_reg_buf_size = sizeof(fpu);
- if (fpu_reg_buf_size == count &&
+ if (fpu_reg_buf_size == count * sizeof(uint32_t) &&
data.ExtractBytes(offset, fpu_reg_buf_size, eByteOrderLittle,
fpu_reg_buf) == fpu_reg_buf_size) {
SetError(FPURegSet, Read, 0);
@@ -1200,6 +1200,7 @@ AddressClass ObjectFileMachO::GetAddressClass(lldb::addr_t file_addr) {
case eSectionTypeDWARFDebugAbbrev:
case eSectionTypeDWARFDebugAddr:
case eSectionTypeDWARFDebugAranges:
+ case eSectionTypeDWARFDebugCuIndex:
case eSectionTypeDWARFDebugFrame:
case eSectionTypeDWARFDebugInfo:
case eSectionTypeDWARFDebugLine:
diff --git a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
index 5607a71ad5aab..72b1b15f08f86 100644
--- a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -10,9 +10,6 @@
#include "ObjectFilePECOFF.h"
#include "WindowsMiniDump.h"
-#include "llvm/BinaryFormat/COFF.h"
-
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/FileSpecList.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
@@ -23,12 +20,14 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataBufferLLVM.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
#include "lldb/Utility/UUID.h"
+#include "llvm/BinaryFormat/COFF.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -136,6 +135,11 @@ size_t ObjectFilePECOFF::GetModuleSpecifications(
spec.SetTriple("i686-pc-windows");
specs.Append(ModuleSpec(file, spec));
}
+ else if (coff_header.machine == MachineArmNt)
+ {
+ spec.SetTriple("arm-pc-windows");
+ specs.Append(ModuleSpec(file, spec));
+ }
}
}
}
@@ -537,7 +541,8 @@ Symtab *ObjectFilePECOFF::GetSymtab() {
// First 4 bytes should be zeroed after strtab_size has been read,
// because it is used as offset 0 to encode a NULL string.
- uint32_t *strtab_data_start = (uint32_t *)strtab_data.GetDataStart();
+ uint32_t *strtab_data_start = const_cast<uint32_t *>(
+ reinterpret_cast<const uint32_t *>(strtab_data.GetDataStart()));
strtab_data_start[0] = 0;
offset = 0;
diff --git a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
index 588f3f7aec645..b71f3cf04c33f 100644
--- a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
+++ b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
@@ -17,7 +17,6 @@
#include "Plugins/Process/Utility/RegisterContextDummy.h"
#include "Plugins/Process/Utility/RegisterContextMemory.h"
#include "Plugins/Process/Utility/ThreadMemory.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
diff --git a/source/Plugins/Platform/Android/AdbClient.cpp b/source/Plugins/Platform/Android/AdbClient.cpp
index d3bcee6f487d7..6e15eb2b1dcb6 100644
--- a/source/Plugins/Platform/Android/AdbClient.cpp
+++ b/source/Plugins/Platform/Android/AdbClient.cpp
@@ -46,7 +46,7 @@ using namespace std::chrono;
namespace {
-const seconds kReadTimeout(12);
+const seconds kReadTimeout(20);
const char *kOKAY = "OKAY";
const char *kFAIL = "FAIL";
const char *kDATA = "DATA";
diff --git a/source/Plugins/Platform/Android/PlatformAndroid.cpp b/source/Plugins/Platform/Android/PlatformAndroid.cpp
index 0f37da60d5d61..5b85bcdf7fdd1 100644
--- a/source/Plugins/Platform/Android/PlatformAndroid.cpp
+++ b/source/Plugins/Platform/Android/PlatformAndroid.cpp
@@ -21,6 +21,7 @@
#include "AdbClient.h"
#include "PlatformAndroid.h"
#include "PlatformAndroidRemoteGDBServer.h"
+#include "lldb/Target/Target.h"
using namespace lldb;
using namespace lldb_private;
@@ -366,9 +367,22 @@ bool PlatformAndroid::GetRemoteOSVersion() {
return m_major_os_version != 0;
}
-llvm::StringRef PlatformAndroid::GetLibdlFunctionDeclarations() {
+llvm::StringRef
+PlatformAndroid::GetLibdlFunctionDeclarations(lldb_private::Process *process) {
+ SymbolContextList matching_symbols;
+ std::vector<const char *> dl_open_names = { "__dl_dlopen", "dlopen" };
+ const char *dl_open_name = nullptr;
+ Target &target = process->GetTarget();
+ for (auto name: dl_open_names) {
+ if (target.GetImages().FindFunctionSymbols(ConstString(name),
+ eFunctionNameTypeFull,
+ matching_symbols)) {
+ dl_open_name = name;
+ break;
+ }
+ }
// Older platform versions have the dl function symbols mangled
- if (GetSdkVersion() < 26)
+ if (dl_open_name == dl_open_names[0])
return R"(
extern "C" void* dlopen(const char*, int) asm("__dl_dlopen");
extern "C" void* dlsym(void*, const char*) asm("__dl_dlsym");
@@ -376,7 +390,7 @@ llvm::StringRef PlatformAndroid::GetLibdlFunctionDeclarations() {
extern "C" char* dlerror(void) asm("__dl_dlerror");
)";
- return PlatformPOSIX::GetLibdlFunctionDeclarations();
+ return PlatformPOSIX::GetLibdlFunctionDeclarations(process);
}
AdbClient::SyncService *PlatformAndroid::GetSyncService(Status &error) {
diff --git a/source/Plugins/Platform/Android/PlatformAndroid.h b/source/Plugins/Platform/Android/PlatformAndroid.h
index 638dba9733698..4c12eb8c016da 100644
--- a/source/Plugins/Platform/Android/PlatformAndroid.h
+++ b/source/Plugins/Platform/Android/PlatformAndroid.h
@@ -76,7 +76,8 @@ protected:
Status DownloadSymbolFile(const lldb::ModuleSP &module_sp,
const FileSpec &dst_file_spec) override;
- llvm::StringRef GetLibdlFunctionDeclarations() override;
+ llvm::StringRef
+ GetLibdlFunctionDeclarations(lldb_private::Process *process) override;
private:
AdbClient::SyncService *GetSyncService(Status &error);
diff --git a/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp b/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
index 53cec45f986e6..73c7d21f0a069 100644
--- a/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
+++ b/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
@@ -314,13 +314,19 @@ void PlatformFreeBSD::CalculateTrapHandlerSymbolNames() {
m_trap_handlers.push_back(ConstString("_sigtramp"));
}
-uint64_t PlatformFreeBSD::ConvertMmapFlagsToPlatform(const ArchSpec &arch,
- unsigned flags) {
+MmapArgList PlatformFreeBSD::GetMmapArgumentList(const ArchSpec &arch,
+ addr_t addr, addr_t length,
+ unsigned prot, unsigned flags,
+ addr_t fd, addr_t offset) {
uint64_t flags_platform = 0;
if (flags & eMmapFlagsPrivate)
flags_platform |= MAP_PRIVATE;
if (flags & eMmapFlagsAnon)
flags_platform |= MAP_ANON;
- return flags_platform;
+
+ MmapArgList args({addr, length, prot, flags_platform, fd, offset});
+ if (arch.GetTriple().getArch() == llvm::Triple::x86)
+ args.push_back(0);
+ return args;
}
diff --git a/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h b/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
index 4bde2148a4d41..274304834290b 100644
--- a/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
+++ b/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
@@ -61,8 +61,10 @@ public:
void CalculateTrapHandlerSymbolNames() override;
- uint64_t ConvertMmapFlagsToPlatform(const ArchSpec &arch,
- unsigned flags) override;
+ MmapArgList GetMmapArgumentList(const ArchSpec &arch, lldb::addr_t addr,
+ lldb::addr_t length, unsigned prot,
+ unsigned flags, lldb::addr_t fd,
+ lldb::addr_t offset) override;
private:
DISALLOW_COPY_AND_ASSIGN(PlatformFreeBSD);
diff --git a/source/Plugins/Platform/Linux/PlatformLinux.cpp b/source/Plugins/Platform/Linux/PlatformLinux.cpp
index 0bf00ea307984..8186eae0e8c41 100644
--- a/source/Plugins/Platform/Linux/PlatformLinux.cpp
+++ b/source/Plugins/Platform/Linux/PlatformLinux.cpp
@@ -372,7 +372,7 @@ PlatformLinux::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
// Hook up process PTY if we have one (which we should for local debugging
// with llgs).
int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
- if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd) {
+ if (pty_fd != PseudoTerminal::invalid_fd) {
process_sp->SetSTDIOFileDescriptor(pty_fd);
LLDB_LOG(log, "hooked up STDIO pty to process");
} else
@@ -390,8 +390,10 @@ void PlatformLinux::CalculateTrapHandlerSymbolNames() {
m_trap_handlers.push_back(ConstString("_sigtramp"));
}
-uint64_t PlatformLinux::ConvertMmapFlagsToPlatform(const ArchSpec &arch,
- unsigned flags) {
+MmapArgList PlatformLinux::GetMmapArgumentList(const ArchSpec &arch,
+ addr_t addr, addr_t length,
+ unsigned prot, unsigned flags,
+ addr_t fd, addr_t offset) {
uint64_t flags_platform = 0;
uint64_t map_anon = MAP_ANON;
@@ -406,6 +408,8 @@ uint64_t PlatformLinux::ConvertMmapFlagsToPlatform(const ArchSpec &arch,
flags_platform |= MAP_PRIVATE;
if (flags & eMmapFlagsAnon)
flags_platform |= map_anon;
- return flags_platform;
+
+ MmapArgList args({addr, length, prot, flags_platform, fd, offset});
+ return args;
}
diff --git a/source/Plugins/Platform/Linux/PlatformLinux.h b/source/Plugins/Platform/Linux/PlatformLinux.h
index bc7b723427f8d..50d721f7c0723 100644
--- a/source/Plugins/Platform/Linux/PlatformLinux.h
+++ b/source/Plugins/Platform/Linux/PlatformLinux.h
@@ -59,8 +59,10 @@ public:
void CalculateTrapHandlerSymbolNames() override;
- uint64_t ConvertMmapFlagsToPlatform(const ArchSpec &arch,
- unsigned flags) override;
+ MmapArgList GetMmapArgumentList(const ArchSpec &arch, lldb::addr_t addr,
+ lldb::addr_t length, unsigned prot,
+ unsigned flags, lldb::addr_t fd,
+ lldb::addr_t offset) override;
private:
DISALLOW_COPY_AND_ASSIGN(PlatformLinux);
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
index 0197d27e76ef7..a216e3839dd9c 100644
--- a/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
@@ -206,7 +206,7 @@ lldb::ProcessSP PlatformAppleSimulator::DebugProcess(
// 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 != lldb_utility::PseudoTerminal::invalid_fd) {
+ if (pty_fd != PseudoTerminal::invalid_fd) {
process_sp->SetSTDIOFileDescriptor(pty_fd);
}
}
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp
index 52188eefb3661..e0558f8b200e7 100644
--- a/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp
@@ -14,7 +14,6 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
@@ -23,6 +22,7 @@
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp
index b9f493294a037..9b2608f68625c 100644
--- a/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp
@@ -14,7 +14,6 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
@@ -23,6 +22,7 @@
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index f87852ed7f440..b39aa103f1dbd 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -1132,28 +1132,33 @@ bool PlatformDarwin::ARMGetSupportedArchitectureAtIndex(uint32_t idx,
return false;
}
+// Return a directory path like /Applications/Xcode.app/Contents/Developer
const char *PlatformDarwin::GetDeveloperDirectory() {
std::lock_guard<std::mutex> guard(m_mutex);
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)) {
if (temp_file_spec.GetPath(developer_dir_path,
sizeof(developer_dir_path))) {
+ // e.g. /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework
char *shared_frameworks =
strstr(developer_dir_path, "/SharedFrameworks/LLDB.framework");
if (shared_frameworks) {
- ::snprintf(shared_frameworks,
- sizeof(developer_dir_path) -
- (shared_frameworks - developer_dir_path),
- "/Developer");
+ shared_frameworks[0] = '\0'; // truncate developer_dir_path at this point
+ strncat (developer_dir_path, "/Developer", sizeof (developer_dir_path) - 1); // add /Developer on
developer_dir_path_valid = true;
} else {
- char *lib_priv_frameworks = strstr(
- developer_dir_path, "/Library/PrivateFrameworks/LLDB.framework");
- if (lib_priv_frameworks) {
- *lib_priv_frameworks = '\0';
+ // 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) {
+ developer_toolchains += sizeof ("/Contents/Developer") - 1;
+ developer_toolchains[0] = '\0'; // truncate developer_dir_path at this point
developer_dir_path_valid = true;
}
}
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp b/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
index f168fb6fda5e8..e5d27fc289496 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
@@ -18,7 +18,6 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
@@ -31,6 +30,7 @@
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
@@ -694,7 +694,16 @@ Status PlatformDarwinKernel::GetSharedModule(
}
}
- // Second look through the kext binarys without dSYMs
+ // 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);
+ if (error.Success() && module_sp.get()) {
+ return error;
+ }
+
+ // Lastly, look through the kext binarys without dSYMs
if (m_name_to_kext_path_map_without_dsyms.count(kext_bundle_cs) > 0) {
for (BundleIDToKextIterator it =
m_name_to_kext_path_map_without_dsyms.begin();
@@ -739,7 +748,17 @@ Status PlatformDarwinKernel::GetSharedModule(
}
}
}
- // Second try all kernel binaries that don't have a dSYM
+
+ // 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);
+ if (error.Success() && module_sp.get()) {
+ return error;
+ }
+
+ // Next try all kernel binaries that don't have a dSYM
for (auto possible_kernel : m_kernel_binaries_without_dsyms) {
if (possible_kernel.Exists()) {
ModuleSpec kern_spec(possible_kernel);
@@ -767,11 +786,7 @@ Status PlatformDarwinKernel::GetSharedModule(
}
}
- // Else fall back to treating the file's path as an actual file path - defer
- // to PlatformDarwin's GetSharedModule.
- return PlatformDarwin::GetSharedModule(module_spec, process, module_sp,
- module_search_paths_ptr,
- old_module_sp_ptr, did_create_ptr);
+ return error;
}
Status PlatformDarwinKernel::ExamineKextForMatchingUUID(
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp
index 38facc4aa124c..1eef643d39046 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp
@@ -17,7 +17,6 @@
#include "PlatformRemoteAppleTV.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
@@ -25,6 +24,7 @@
#include "lldb/Host/Host.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp
index bbd8f16989370..17ae67bc28deb 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp
@@ -17,7 +17,6 @@
#include "PlatformRemoteAppleWatch.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
@@ -25,6 +24,7 @@
#include "lldb/Host/Host.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp
index ea44714a916e4..cb064aad6155b 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp
@@ -14,7 +14,6 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
index c52b636c8496f..5bff792525bcc 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
@@ -14,7 +14,6 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
@@ -22,6 +21,7 @@
#include "lldb/Host/Host.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
diff --git a/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
index 3037dd854be70..ee1f90311e7ea 100644
--- a/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
@@ -15,7 +15,6 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
@@ -24,6 +23,7 @@
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
diff --git a/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm b/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm
index 6a49b645c1e17..7bd37683d2fd4 100644
--- a/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm
+++ b/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm
@@ -22,7 +22,6 @@
#include "llvm/ADT/StringRef.h"
using namespace lldb_private;
-using namespace lldb_utility;
// CoreSimulator lives as part of Xcode, which means we can't really link
// against it, so we dlopen()
// it at runtime, and error out nicely if that fails
diff --git a/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp b/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
index 9df5b9fac3805..38bdf60c1ced6 100644
--- a/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
+++ b/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
@@ -393,7 +393,7 @@ lldb::ProcessSP PlatformNetBSD::DebugProcess(
// Hook up process PTY if we have one (which we should for local debugging
// with llgs).
int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
- if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd) {
+ if (pty_fd != PseudoTerminal::invalid_fd) {
process_sp->SetSTDIOFileDescriptor(pty_fd);
if (log)
log->Printf("PlatformNetBSD::%s pid %" PRIu64
@@ -420,13 +420,17 @@ void PlatformNetBSD::CalculateTrapHandlerSymbolNames() {
m_trap_handlers.push_back(ConstString("_sigtramp"));
}
-uint64_t PlatformNetBSD::ConvertMmapFlagsToPlatform(const ArchSpec &arch,
- unsigned flags) {
+MmapArgList PlatformNetBSD::GetMmapArgumentList(const ArchSpec &arch,
+ addr_t addr, addr_t length,
+ unsigned prot, unsigned flags,
+ addr_t fd, addr_t offset) {
uint64_t flags_platform = 0;
if (flags & eMmapFlagsPrivate)
flags_platform |= MAP_PRIVATE;
if (flags & eMmapFlagsAnon)
flags_platform |= MAP_ANON;
- return flags_platform;
+
+ MmapArgList args({addr, length, prot, flags_platform, fd, offset});
+ return args;
}
diff --git a/source/Plugins/Platform/NetBSD/PlatformNetBSD.h b/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
index b1aaa4ab5f59c..28a5d6713dd95 100644
--- a/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
+++ b/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
@@ -59,8 +59,10 @@ public:
void CalculateTrapHandlerSymbolNames() override;
- uint64_t ConvertMmapFlagsToPlatform(const ArchSpec &arch,
- unsigned flags) override;
+ MmapArgList GetMmapArgumentList(const ArchSpec &arch, lldb::addr_t addr,
+ lldb::addr_t length, unsigned prot,
+ unsigned flags, lldb::addr_t fd,
+ lldb::addr_t offset) override;
private:
DISALLOW_COPY_AND_ASSIGN(PlatformNetBSD);
diff --git a/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp b/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
index edb8ec951d374..050639aba7cc5 100644
--- a/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
+++ b/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
@@ -133,7 +133,7 @@ PlatformOpenBSD::PlatformOpenBSD(bool is_host)
PlatformOpenBSD::~PlatformOpenBSD() = default;
bool PlatformOpenBSD::GetSupportedArchitectureAtIndex(uint32_t idx,
- ArchSpec &arch) {
+ ArchSpec &arch) {
if (IsHost()) {
ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
if (hostArch.GetTriple().isOSOpenBSD()) {
@@ -211,13 +211,17 @@ void PlatformOpenBSD::CalculateTrapHandlerSymbolNames() {
m_trap_handlers.push_back(ConstString("_sigtramp"));
}
-uint64_t PlatformOpenBSD::ConvertMmapFlagsToPlatform(const ArchSpec &arch,
- unsigned flags) {
+MmapArgList PlatformOpenBSD::GetMmapArgumentList(const ArchSpec &arch,
+ addr_t addr, addr_t length,
+ unsigned prot, unsigned flags,
+ addr_t fd, addr_t offset) {
uint64_t flags_platform = 0;
if (flags & eMmapFlagsPrivate)
flags_platform |= MAP_PRIVATE;
if (flags & eMmapFlagsAnon)
flags_platform |= MAP_ANON;
- return flags_platform;
+
+ MmapArgList args({addr, length, prot, flags_platform, fd, offset});
+ return args;
}
diff --git a/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h b/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h
index 55f6451e236ef..cb5e9bfe63926 100644
--- a/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h
+++ b/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h
@@ -53,8 +53,10 @@ public:
void CalculateTrapHandlerSymbolNames() override;
- uint64_t ConvertMmapFlagsToPlatform(const ArchSpec &arch,
- unsigned flags) override;
+ MmapArgList GetMmapArgumentList(const ArchSpec &arch, lldb::addr_t addr,
+ lldb::addr_t length, unsigned prot,
+ unsigned flags, lldb::addr_t fd,
+ lldb::addr_t offset) override;
private:
DISALLOW_COPY_AND_ASSIGN(PlatformOpenBSD);
diff --git a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
index 013c33def13b9..d45a54ee24994 100644
--- a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -944,7 +944,7 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process,
the_result;
)",
path);
- llvm::StringRef prefix = GetLibdlFunctionDeclarations();
+ llvm::StringRef prefix = GetLibdlFunctionDeclarations(process);
lldb::ValueObjectSP result_valobj_sp;
error = EvaluateLibdlExpression(process, expr.GetData(), prefix,
result_valobj_sp);
@@ -992,7 +992,7 @@ Status PlatformPOSIX::UnloadImage(lldb_private::Process *process,
StreamString expr;
expr.Printf("dlclose((void *)0x%" PRIx64 ")", image_addr);
- llvm::StringRef prefix = GetLibdlFunctionDeclarations();
+ llvm::StringRef prefix = GetLibdlFunctionDeclarations(process);
lldb::ValueObjectSP result_valobj_sp;
Status error = EvaluateLibdlExpression(process, expr.GetData(), prefix,
result_valobj_sp);
@@ -1024,7 +1024,8 @@ lldb::ProcessSP PlatformPOSIX::ConnectProcess(llvm::StringRef connect_url,
error);
}
-llvm::StringRef PlatformPOSIX::GetLibdlFunctionDeclarations() {
+llvm::StringRef
+PlatformPOSIX::GetLibdlFunctionDeclarations(lldb_private::Process *process) {
return R"(
extern "C" void* dlopen(const char*, int);
extern "C" void* dlsym(void*, const char*);
diff --git a/source/Plugins/Platform/POSIX/PlatformPOSIX.h b/source/Plugins/Platform/POSIX/PlatformPOSIX.h
index ebc36c2461db1..93bebeb332cac 100644
--- a/source/Plugins/Platform/POSIX/PlatformPOSIX.h
+++ b/source/Plugins/Platform/POSIX/PlatformPOSIX.h
@@ -201,7 +201,8 @@ protected:
llvm::StringRef expr_prefix,
lldb::ValueObjectSP &result_valobj_sp);
- virtual llvm::StringRef GetLibdlFunctionDeclarations();
+ virtual
+ llvm::StringRef GetLibdlFunctionDeclarations(lldb_private::Process *process);
private:
DISALLOW_COPY_AND_ASSIGN(PlatformPOSIX);
diff --git a/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp b/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp
index c6daf6ccea6e3..6b3d5f6c117fe 100644
--- a/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp
+++ b/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp
@@ -144,7 +144,7 @@ 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.
- lldb_utility::PseudoTerminal pty;
+ PseudoTerminal pty;
char fork_error[256];
memset(fork_error, 0, sizeof(fork_error));
*pid = static_cast<::pid_t>(pty.Fork(fork_error, sizeof(fork_error)));
diff --git a/source/Plugins/Process/Darwin/MachException.cpp b/source/Plugins/Process/Darwin/MachException.cpp
index 7d956dfc65060..9f5920753d68d 100644
--- a/source/Plugins/Process/Darwin/MachException.cpp
+++ b/source/Plugins/Process/Darwin/MachException.cpp
@@ -57,11 +57,6 @@ extern "C" kern_return_t catch_mach_exception_raise_state_identity(
extern "C" boolean_t mach_exc_server(mach_msg_header_t *InHeadP,
mach_msg_header_t *OutHeadP);
-// Any access to the g_message variable should be done by locking the
-// g_message_mutex first, using the g_message variable, then unlocking
-// the g_message_mutex. See MachException::Message::CatchExceptionRaise()
-// for sample code.
-
static MachException::Data *g_message = NULL;
extern "C" kern_return_t catch_mach_exception_raise_state(
@@ -131,33 +126,6 @@ catch_mach_exception_raise(mach_port_t exc_port, mach_port_t thread_port,
return KERN_FAILURE;
}
-#if 0
-void
-MachException::Message::Dump(Stream &stream) const
-{
- stream.Printf("exc_msg { bits = 0x%8.8x size = 0x%8.8x remote-port = "
- "0x%8.8x local-port = 0x%8.8x reserved = 0x%8.8x "
- "id = 0x%8.8x }\n",
- exc_msg.hdr.msgh_bits,
- exc_msg.hdr.msgh_size,
- exc_msg.hdr.msgh_remote_port,
- exc_msg.hdr.msgh_local_port,
- exc_msg.hdr.msgh_reserved,
- exc_msg.hdr.msgh_id);
-
- stream.Printf("reply_msg { bits = 0x%8.8x size = 0x%8.8x remote-port "
- "= 0x%8.8x local-port = 0x%8.8x reserved = 0x%8.8x "
- "id = 0x%8.8x }",
- reply_msg.hdr.msgh_bits,
- reply_msg.hdr.msgh_size,
- reply_msg.hdr.msgh_remote_port,
- reply_msg.hdr.msgh_local_port,
- reply_msg.hdr.msgh_reserved,
- reply_msg.hdr.msgh_id);
- stream.Flush();
-}
-#endif
-
bool MachException::Data::GetStopInfo(struct ThreadStopInfo *stop_info,
const UnixSignals &signals,
Stream &stream) const {
@@ -279,9 +247,6 @@ void MachException::Message::Dump(Stream &stream) const {
bool MachException::Message::CatchExceptionRaise(task_t task) {
bool success = false;
- // locker will keep a mutex locked until it goes out of scope
- // PThreadMutex::Locker locker(&g_message_mutex);
- // DNBLogThreaded("calling mach_exc_server");
state.task_port = task;
g_message = &state;
// The exc_server function is the MIG generated server handling function
diff --git a/source/Plugins/Process/Darwin/NativeProcessDarwin.h b/source/Plugins/Process/Darwin/NativeProcessDarwin.h
index 2214bbc52ca45..649280c17a8f3 100644
--- a/source/Plugins/Process/Darwin/NativeProcessDarwin.h
+++ b/source/Plugins/Process/Darwin/NativeProcessDarwin.h
@@ -22,12 +22,12 @@
#include <unordered_set>
// Other libraries and framework includes
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Host/Debug.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Host/Pipe.h"
#include "lldb/Host/common/NativeProcessProtocol.h"
#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/lldb-types.h"
@@ -197,20 +197,6 @@ private:
// waitpid reader callback handle.
MainLoop::ReadHandleUP m_waitpid_reader_handle;
-#if 0
- ArchSpec m_arch;
-
- LazyBool m_supports_mem_region;
- std::vector<MemoryRegionInfo> m_mem_region_cache;
-
- lldb::tid_t m_pending_notification_tid;
-
- // List of thread ids stepping with a breakpoint with the address of
- // the relevan breakpoint
- std::map<lldb::tid_t, lldb::addr_t>
- m_threads_stepping_with_breakpoint;
-#endif
-
// -----------------------------------------------------------------
// Private Instance Methods
// -----------------------------------------------------------------
@@ -322,20 +308,6 @@ private:
Status SetupSoftwareSingleStepping(NativeThreadDarwin &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/FreeBSD/FreeBSDThread.cpp b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
index bd8e5abe2255f..e6557c2d58e03 100644
--- a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
+++ b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
@@ -375,6 +375,7 @@ void FreeBSDThread::Notify(const ProcessMessage &message) {
LimboNotify(message);
break;
+ case ProcessMessage::eCrashMessage:
case ProcessMessage::eSignalMessage:
SignalNotify(message);
break;
@@ -395,10 +396,6 @@ void FreeBSDThread::Notify(const ProcessMessage &message) {
WatchNotify(message);
break;
- case ProcessMessage::eCrashMessage:
- CrashNotify(message);
- break;
-
case ProcessMessage::eExecMessage:
ExecNotify(message);
break;
@@ -577,7 +574,14 @@ void FreeBSDThread::LimboNotify(const ProcessMessage &message) {
void FreeBSDThread::SignalNotify(const ProcessMessage &message) {
int signo = message.GetSignal();
- SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, signo));
+ if (message.GetKind() == ProcessMessage::eCrashMessage) {
+ std::string stop_description = GetCrashReasonString(
+ message.GetCrashReason(), message.GetFaultAddress());
+ SetStopInfo(StopInfo::CreateStopReasonWithSignal(
+ *this, signo, stop_description.c_str()));
+ } else {
+ SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, signo));
+ }
}
void FreeBSDThread::SignalDeliveredNotify(const ProcessMessage &message) {
@@ -585,21 +589,6 @@ void FreeBSDThread::SignalDeliveredNotify(const ProcessMessage &message) {
SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, signo));
}
-void FreeBSDThread::CrashNotify(const ProcessMessage &message) {
- // FIXME: Update stop reason as per bugzilla 14598
- int signo = message.GetSignal();
-
- assert(message.GetKind() == ProcessMessage::eCrashMessage);
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
- if (log)
- log->Printf("FreeBSDThread::%s () signo = %i, reason = '%s'", __FUNCTION__,
- signo, message.PrintCrashReason());
-
- SetStopInfo(lldb::StopInfoSP(new POSIXCrashStopInfo(
- *this, signo, message.GetCrashReason(), message.GetFaultAddress())));
-}
-
unsigned FreeBSDThread::GetRegisterIndexFromOffset(unsigned offset) {
unsigned reg = LLDB_INVALID_REGNUM;
ArchSpec arch = HostInfo::GetArchitecture();
diff --git a/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp b/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp
index dfbd695899ffb..9c75c26e379b5 100644
--- a/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp
+++ b/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp
@@ -28,22 +28,6 @@ bool POSIXLimboStopInfo::ShouldStop(Event *event_ptr) { return false; }
bool POSIXLimboStopInfo::ShouldNotify(Event *event_ptr) { return false; }
//===----------------------------------------------------------------------===//
-// POSIXCrashStopInfo
-
-POSIXCrashStopInfo::POSIXCrashStopInfo(FreeBSDThread &thread, uint32_t status,
- CrashReason reason,
- lldb::addr_t fault_addr)
- : POSIXStopInfo(thread, status) {
- m_description = ::GetCrashReasonString(reason, fault_addr);
-}
-
-POSIXCrashStopInfo::~POSIXCrashStopInfo() {}
-
-lldb::StopReason POSIXCrashStopInfo::GetStopReason() const {
- return lldb::eStopReasonException;
-}
-
-//===----------------------------------------------------------------------===//
// POSIXNewThreadStopInfo
POSIXNewThreadStopInfo::~POSIXNewThreadStopInfo() {}
diff --git a/source/Plugins/Process/FreeBSD/POSIXStopInfo.h b/source/Plugins/Process/FreeBSD/POSIXStopInfo.h
index e51fc08d74cc7..96861852b38eb 100644
--- a/source/Plugins/Process/FreeBSD/POSIXStopInfo.h
+++ b/source/Plugins/Process/FreeBSD/POSIXStopInfo.h
@@ -45,19 +45,6 @@ public:
};
//===----------------------------------------------------------------------===//
-/// @class POSIXCrashStopInfo
-/// @brief Represents the stop state of process that is ready to crash.
-///
-class POSIXCrashStopInfo : public POSIXStopInfo {
-public:
- POSIXCrashStopInfo(FreeBSDThread &thread, uint32_t status, CrashReason reason,
- lldb::addr_t fault_addr);
- ~POSIXCrashStopInfo();
-
- lldb::StopReason GetStopReason() const;
-};
-
-//===----------------------------------------------------------------------===//
/// @class POSIXNewThreadStopInfo
/// @brief Represents the stop state of process when a new thread is spawned.
///
diff --git a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
index 3046150e3246a..7a937db49be0c 100644
--- a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
+++ b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
@@ -825,32 +825,6 @@ uint32_t ProcessFreeBSD::UpdateThreadListIfNeeded() {
return m_thread_list.GetSize(false);
}
-#if 0
-bool
-ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
- if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
- log->Printf ("ProcessFreeBSD::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID());
-
- bool has_updated = false;
- // Update the process thread list with this new thread.
- // FIXME: We should be using tid, not pid.
- assert(m_monitor);
- ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
- if (!thread_sp) {
- thread_sp.reset(CreateNewFreeBSDThread(*this, GetID()));
- has_updated = true;
- }
-
- if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
- log->Printf ("ProcessFreeBSD::%s() updated pid = %" PRIi64, __FUNCTION__, GetID());
- new_thread_list.AddThread(thread_sp);
-
- return has_updated; // the list has been updated
-}
-#endif
-
ByteOrder ProcessFreeBSD::GetByteOrder() const {
// FIXME: We should be able to extract this value directly. See comment in
// ProcessFreeBSD().
diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
index a4f5f02dde62e..bd06fa25f0a01 100644
--- a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
+++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
@@ -843,7 +843,7 @@ bool ProcessMonitor::Launch(LaunchArgs *args) {
const FileSpec &stderr_file_spec = args->m_stderr_file_spec;
const FileSpec &working_dir = args->m_working_dir;
- lldb_utility::PseudoTerminal terminal;
+ PseudoTerminal terminal;
const size_t err_len = 1024;
char err_str[err_len];
::pid_t pid;
@@ -1192,7 +1192,9 @@ ProcessMessage ProcessMonitor::MonitorSignal(ProcessMonitor *monitor,
case SIGBUS:
lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
const auto reason = GetCrashReason(*info);
- return ProcessMessage::Crash(tid, reason, signo, fault_addr);
+ if (reason != CrashReason::eInvalidCrashReason) {
+ return ProcessMessage::Crash(tid, reason, signo, fault_addr);
+ } // else; Use atleast si_signo info for other si_code
}
// Everything else is "normal" and does not require any special action on
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h b/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h
index c0b9b2f4a2d3c..4ff5121bac130 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h
@@ -14,8 +14,8 @@
// C++ Includes
// Other libraries and framework includes
#include "RegisterInfoInterface.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/Utility/ArchSpec.h"
//------------------------------------------------------------------------------
/// @class POSIXBreakpointProtocol
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
index 1cd8f1aafa6e3..4608520dba409 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
@@ -58,6 +58,9 @@ RegisterContextPOSIXProcessMonitor_x86_64::
// Store byte offset of fctrl (i.e. first register of FPR) wrt 'UserArea'
const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl");
m_fctrl_offset_in_userarea = reg_info_fctrl->byte_offset;
+
+ m_iovec.iov_base = &m_fpr.xsave;
+ m_iovec.iov_len = sizeof(m_fpr.xsave);
}
ProcessMonitor &RegisterContextPOSIXProcessMonitor_x86_64::GetMonitor() {
@@ -74,12 +77,12 @@ bool RegisterContextPOSIXProcessMonitor_x86_64::ReadGPR() {
bool RegisterContextPOSIXProcessMonitor_x86_64::ReadFPR() {
ProcessMonitor &monitor = GetMonitor();
if (GetFPRType() == eFXSAVE)
- return monitor.ReadFPR(m_thread.GetID(), &m_fpr.xstate.fxsave,
- sizeof(m_fpr.xstate.fxsave));
+ return monitor.ReadFPR(m_thread.GetID(), &m_fpr.fxsave,
+ sizeof(m_fpr.fxsave));
if (GetFPRType() == eXSAVE)
return monitor.ReadRegisterSet(m_thread.GetID(), &m_iovec,
- sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
+ sizeof(m_fpr.xsave), NT_X86_XSTATE);
return false;
}
@@ -91,12 +94,12 @@ bool RegisterContextPOSIXProcessMonitor_x86_64::WriteGPR() {
bool RegisterContextPOSIXProcessMonitor_x86_64::WriteFPR() {
ProcessMonitor &monitor = GetMonitor();
if (GetFPRType() == eFXSAVE)
- return monitor.WriteFPR(m_thread.GetID(), &m_fpr.xstate.fxsave,
- sizeof(m_fpr.xstate.fxsave));
+ return monitor.WriteFPR(m_thread.GetID(), &m_fpr.fxsave,
+ sizeof(m_fpr.fxsave));
if (GetFPRType() == eXSAVE)
return monitor.WriteRegisterSet(m_thread.GetID(), &m_iovec,
- sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
+ sizeof(m_fpr.xsave), NT_X86_XSTATE);
return false;
}
@@ -209,17 +212,14 @@ bool RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(
if (byte_order != ByteOrder::eByteOrderInvalid) {
if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
- value.SetBytes(
- m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes,
- reg_info->byte_size, byte_order);
+ value.SetBytes(m_fpr.fxsave.stmm[reg - m_reg_info.first_st].bytes,
+ reg_info->byte_size, byte_order);
if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
- value.SetBytes(
- m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes,
- reg_info->byte_size, byte_order);
+ value.SetBytes(m_fpr.fxsave.stmm[reg - m_reg_info.first_mm].bytes,
+ reg_info->byte_size, byte_order);
if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
- value.SetBytes(
- m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
- reg_info->byte_size, byte_order);
+ value.SetBytes(m_fpr.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
+ reg_info->byte_size, byte_order);
if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
// Concatenate ymm using the register halves in xmm.bytes and ymmh.bytes
if (GetFPRType() == eXSAVE && CopyXSTATEtoYMM(reg, byte_order))
@@ -233,7 +233,7 @@ bool RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(
return false;
}
- // Get pointer to m_fpr.xstate.fxsave variable and set the data from it.
+ // 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
@@ -276,15 +276,15 @@ bool RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(
if (IsFPR(reg, GetFPRType())) {
if (reg_info->encoding == eEncodingVector) {
if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
- ::memcpy(m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes,
+ ::memcpy(m_fpr.fxsave.stmm[reg - m_reg_info.first_st].bytes,
value.GetBytes(), value.GetByteSize());
if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
- ::memcpy(m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes,
+ ::memcpy(m_fpr.fxsave.stmm[reg - m_reg_info.first_mm].bytes,
value.GetBytes(), value.GetByteSize());
if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
- ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
+ ::memcpy(m_fpr.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
value.GetBytes(), value.GetByteSize());
if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
@@ -299,7 +299,7 @@ bool RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(
return false;
}
} else {
- // Get pointer to m_fpr.xstate.fxsave variable and set the data to it.
+ // 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
@@ -353,7 +353,7 @@ bool RegisterContextPOSIXProcessMonitor_x86_64::ReadAllRegisterValues(
::memcpy(dst, &m_gpr_x86_64, GetGPRSize());
dst += GetGPRSize();
if (GetFPRType() == eFXSAVE)
- ::memcpy(dst, &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
+ ::memcpy(dst, &m_fpr.fxsave, sizeof(m_fpr.fxsave));
}
if (GetFPRType() == eXSAVE) {
@@ -385,9 +385,9 @@ bool RegisterContextPOSIXProcessMonitor_x86_64::WriteAllRegisterValues(
if (WriteGPR()) {
src += GetGPRSize();
if (GetFPRType() == eFXSAVE)
- ::memcpy(&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave));
+ ::memcpy(&m_fpr.fxsave, src, sizeof(m_fpr.fxsave));
if (GetFPRType() == eXSAVE)
- ::memcpy(&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave));
+ ::memcpy(&m_fpr.xsave, src, sizeof(m_fpr.xsave));
success = WriteFPR();
if (success) {
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h
index 57e2d00e668fd..8c654f97dcd9f 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h
@@ -12,6 +12,7 @@
#include "Plugins/Process/Utility/RegisterContextPOSIX_x86.h"
#include "RegisterContextPOSIX.h"
+#include <sys/uio.h>
class RegisterContextPOSIXProcessMonitor_x86_64
: public RegisterContextPOSIX_x86,
@@ -75,6 +76,7 @@ private:
ProcessMonitor &GetMonitor();
uint32_t
m_fctrl_offset_in_userarea; // Offset of 'fctrl' in 'UserArea' Structure
+ struct iovec m_iovec;
};
#endif
diff --git a/source/Plugins/Process/Linux/CMakeLists.txt b/source/Plugins/Process/Linux/CMakeLists.txt
index 8330cac160e6a..390dbd9ff8bf6 100644
--- a/source/Plugins/Process/Linux/CMakeLists.txt
+++ b/source/Plugins/Process/Linux/CMakeLists.txt
@@ -7,9 +7,10 @@ add_lldb_library(lldbPluginProcessLinux PLUGIN
NativeRegisterContextLinux.cpp
NativeRegisterContextLinux_arm.cpp
NativeRegisterContextLinux_arm64.cpp
- NativeRegisterContextLinux_x86_64.cpp
NativeRegisterContextLinux_mips64.cpp
+ NativeRegisterContextLinux_ppc64le.cpp
NativeRegisterContextLinux_s390x.cpp
+ NativeRegisterContextLinux_x86_64.cpp
NativeThreadLinux.cpp
ProcessorTrace.cpp
SingleStepCheck.cpp
diff --git a/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index 170d3b1000641..136af361af296 100644
--- a/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -177,7 +177,7 @@ void PtraceDisplayBytes(int &req, void *data, size_t data_size) {
break;
}
case PTRACE_SETREGSET: {
- // Extract iov_base from data, which is a pointer to the struct IOVEC
+ // Extract iov_base from data, which is a pointer to the struct iovec
DisplayBytes(buf, *(void **)data, data_size);
LLDB_LOGV(log, "PTRACE_SETREGSET {0}", buf.GetData());
break;
@@ -305,10 +305,9 @@ NativeProcessLinux::NativeProcessLinux(::pid_t pid, int terminal_fd,
assert(m_sigchld_handle && status.Success());
for (const auto &tid : tids) {
- NativeThreadLinuxSP thread_sp = AddThread(tid);
- assert(thread_sp && "AddThread() returned a nullptr thread");
- thread_sp->SetStoppedBySignal(SIGSTOP);
- ThreadWasCreated(*thread_sp);
+ NativeThreadLinux &thread = AddThread(tid);
+ thread.SetStoppedBySignal(SIGSTOP);
+ ThreadWasCreated(thread);
}
// Let our process instance know the thread has stopped.
@@ -413,46 +412,20 @@ void NativeProcessLinux::MonitorCallback(lldb::pid_t pid, bool exited,
// Handle when the thread exits.
if (exited) {
- LLDB_LOG(log, "got exit signal({0}) , tid = {1} ({2} main thread)", signal,
- pid, is_main_thread ? "is" : "is not");
+ LLDB_LOG(log,
+ "got exit signal({0}) , tid = {1} ({2} main thread), process "
+ "state = {3}",
+ signal, pid, is_main_thread ? "is" : "is not", GetState());
// This is a thread that exited. Ensure we're not tracking it anymore.
- const bool thread_found = StopTrackingThread(pid);
+ StopTrackingThread(pid);
if (is_main_thread) {
- // We only set the exit status and notify the delegate if we haven't
- // already set the process
- // state to an exited state. We normally should have received a SIGTRAP |
- // (PTRACE_EVENT_EXIT << 8)
- // for the main thread.
- const bool already_notified = (GetState() == StateType::eStateExited) ||
- (GetState() == StateType::eStateCrashed);
- if (!already_notified) {
- LLDB_LOG(
- log,
- "tid = {0} handling main thread exit ({1}), expected exit state "
- "already set but state was {2} instead, setting exit state now",
- pid,
- thread_found ? "stopped tracking thread metadata"
- : "thread metadata not found",
- GetState());
- // The main thread exited. We're done monitoring. Report to delegate.
- SetExitStatus(status, true);
+ // The main thread exited. We're done monitoring. Report to delegate.
+ SetExitStatus(status, true);
- // Notify delegate that our process has exited.
- SetState(StateType::eStateExited, true);
- } else
- LLDB_LOG(log, "tid = {0} main thread now exited (%s)", pid,
- thread_found ? "stopped tracking thread metadata"
- : "thread metadata not found");
- } else {
- // Do we want to report to the delegate in this case? I think not. If
- // this was an orderly thread exit, we would already have received the
- // SIGTRAP | (PTRACE_EVENT_EXIT << 8) signal, and we would have done an
- // all-stop then.
- LLDB_LOG(log, "tid = {0} handling non-main thread exit (%s)", pid,
- thread_found ? "stopped tracking thread metadata"
- : "thread metadata not found");
+ // Notify delegate that our process has exited.
+ SetState(StateType::eStateExited, true);
}
return;
}
@@ -478,11 +451,11 @@ void NativeProcessLinux::MonitorCallback(lldb::pid_t pid, bool exited,
LLDB_LOG(log, "tid {0}, si_code: {1}, si_pid: {2}", pid, info.si_code,
info.si_pid);
- auto thread_sp = AddThread(pid);
+ NativeThreadLinux &thread = AddThread(pid);
// Resume the newly created thread.
- ResumeThread(*thread_sp, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
- ThreadWasCreated(*thread_sp);
+ ResumeThread(thread, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
+ ThreadWasCreated(thread);
return;
}
@@ -549,12 +522,9 @@ void NativeProcessLinux::MonitorCallback(lldb::pid_t pid, bool exited,
void NativeProcessLinux::WaitForNewThread(::pid_t tid) {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- NativeThreadLinuxSP new_thread_sp = GetThreadByID(tid);
-
- if (new_thread_sp) {
+ if (GetThreadByID(tid)) {
// We are already tracking the thread - we got the event on the new thread
- // (see
- // MonitorSignal) before this one. We are done.
+ // (see MonitorSignal) before this one. We are done.
return;
}
@@ -587,10 +557,10 @@ void NativeProcessLinux::WaitForNewThread(::pid_t tid) {
}
LLDB_LOG(log, "pid = {0}: tracking new thread tid {1}", GetID(), tid);
- new_thread_sp = AddThread(tid);
+ NativeThreadLinux &new_thread = AddThread(tid);
- ResumeThread(*new_thread_sp, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
- ThreadWasCreated(*new_thread_sp);
+ ResumeThread(new_thread, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
+ ThreadWasCreated(new_thread);
}
void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
@@ -630,7 +600,6 @@ void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
}
case (SIGTRAP | (PTRACE_EVENT_EXEC << 8)): {
- NativeThreadLinuxSP main_thread_sp;
LLDB_LOG(log, "received exec event, code = {0}", info.si_code ^ SIGTRAP);
// Exec clears any pending notifications.
@@ -640,44 +609,26 @@ void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
// which only copies the main thread.
LLDB_LOG(log, "exec received, stop tracking all but main thread");
- for (auto thread_sp : m_threads) {
- const bool is_main_thread = thread_sp && thread_sp->GetID() == GetID();
- if (is_main_thread) {
- main_thread_sp = std::static_pointer_cast<NativeThreadLinux>(thread_sp);
- LLDB_LOG(log, "found main thread with tid {0}, keeping",
- main_thread_sp->GetID());
- } else {
- LLDB_LOG(log, "discarding non-main-thread tid {0} due to exec",
- thread_sp->GetID());
- }
+ for (auto i = m_threads.begin(); i != m_threads.end();) {
+ if ((*i)->GetID() == GetID())
+ i = m_threads.erase(i);
+ else
+ ++i;
}
+ assert(m_threads.size() == 1);
+ auto *main_thread = static_cast<NativeThreadLinux *>(m_threads[0].get());
- m_threads.clear();
-
- if (main_thread_sp) {
- m_threads.push_back(main_thread_sp);
- SetCurrentThreadID(main_thread_sp->GetID());
- main_thread_sp->SetStoppedByExec();
- } else {
- SetCurrentThreadID(LLDB_INVALID_THREAD_ID);
- LLDB_LOG(log,
- "pid {0} no main thread found, discarded all threads, "
- "we're in a no-thread state!",
- GetID());
- }
+ SetCurrentThreadID(main_thread->GetID());
+ main_thread->SetStoppedByExec();
// Tell coordinator about about the "new" (since exec) stopped main thread.
- ThreadWasCreated(*main_thread_sp);
+ ThreadWasCreated(*main_thread);
// Let our delegate know we have just exec'd.
NotifyDidExec();
- // If we have a main thread, indicate we are stopped.
- assert(main_thread_sp && "exec called during ptraced process but no main "
- "thread metadata tracked");
-
// Let the process know we're stopped.
- StopRunningThreads(main_thread_sp->GetID());
+ StopRunningThreads(main_thread->GetID());
break;
}
@@ -685,10 +636,8 @@ 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.
+ // 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())
@@ -700,18 +649,14 @@ void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
data, WIFEXITED(data), WIFSIGNALED(data), thread.GetID(),
is_main_thread);
- if (is_main_thread)
- SetExitStatus(WaitStatus::Decode(data), true);
StateType state = thread.GetState();
if (!StateIsRunningState(state)) {
// 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.
+ // 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.
state = eStateRunning;
}
ResumeThread(thread, state, LLDB_INVALID_SIGNAL_NUMBER);
@@ -725,7 +670,7 @@ void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
{
// If a watchpoint was hit, report it
uint32_t wp_index;
- Status error = thread.GetRegisterContext()->GetWatchpointHitIndex(
+ Status error = thread.GetRegisterContext().GetWatchpointHitIndex(
wp_index, (uintptr_t)info.si_addr);
if (error.Fail())
LLDB_LOG(log,
@@ -739,7 +684,7 @@ void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
// If a breakpoint was hit, report it
uint32_t bp_index;
- error = thread.GetRegisterContext()->GetHardwareBreakHitIndex(
+ error = thread.GetRegisterContext().GetHardwareBreakHitIndex(
bp_index, (uintptr_t)info.si_addr);
if (error.Fail())
LLDB_LOG(log, "received error while checking for hardware "
@@ -762,7 +707,7 @@ void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
{
// If a watchpoint was hit, report it
uint32_t wp_index;
- Status error = thread.GetRegisterContext()->GetWatchpointHitIndex(
+ Status error = thread.GetRegisterContext().GetWatchpointHitIndex(
wp_index, LLDB_INVALID_ADDRESS);
if (error.Fail())
LLDB_LOG(log,
@@ -933,13 +878,13 @@ void NativeProcessLinux::MonitorSignal(const siginfo_t &info,
namespace {
struct EmulatorBaton {
- NativeProcessLinux *m_process;
- NativeRegisterContext *m_reg_context;
+ NativeProcessLinux &m_process;
+ NativeRegisterContext &m_reg_context;
// eRegisterKindDWARF -> RegsiterValue
std::unordered_map<uint32_t, RegisterValue> m_register_values;
- EmulatorBaton(NativeProcessLinux *process, NativeRegisterContext *reg_context)
+ EmulatorBaton(NativeProcessLinux &process, NativeRegisterContext &reg_context)
: m_process(process), m_reg_context(reg_context) {}
};
@@ -951,7 +896,7 @@ static size_t ReadMemoryCallback(EmulateInstruction *instruction, void *baton,
EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
size_t bytes_read;
- emulator_baton->m_process->ReadMemory(addr, dst, length, bytes_read);
+ emulator_baton->m_process.ReadMemory(addr, dst, length, bytes_read);
return bytes_read;
}
@@ -971,11 +916,11 @@ static bool ReadRegisterCallback(EmulateInstruction *instruction, void *baton,
// 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(
+ emulator_baton->m_reg_context.GetRegisterInfo(
eRegisterKindDWARF, reg_info->kinds[eRegisterKindDWARF]);
Status error =
- emulator_baton->m_reg_context->ReadRegister(full_reg_info, reg_value);
+ emulator_baton->m_reg_context.ReadRegister(full_reg_info, reg_value);
if (error.Success())
return true;
@@ -999,17 +944,17 @@ static size_t WriteMemoryCallback(EmulateInstruction *instruction, void *baton,
return length;
}
-static lldb::addr_t ReadFlags(NativeRegisterContext *regsiter_context) {
- const RegisterInfo *flags_info = regsiter_context->GetRegisterInfo(
+static lldb::addr_t ReadFlags(NativeRegisterContext &regsiter_context) {
+ const RegisterInfo *flags_info = regsiter_context.GetRegisterInfo(
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
- return regsiter_context->ReadRegisterAsUnsigned(flags_info,
- LLDB_INVALID_ADDRESS);
+ return regsiter_context.ReadRegisterAsUnsigned(flags_info,
+ LLDB_INVALID_ADDRESS);
}
Status
NativeProcessLinux::SetupSoftwareSingleStepping(NativeThreadLinux &thread) {
Status error;
- NativeRegisterContextSP register_context_sp = thread.GetRegisterContext();
+ NativeRegisterContext& register_context = thread.GetRegisterContext();
std::unique_ptr<EmulateInstruction> emulator_ap(
EmulateInstruction::FindPlugin(m_arch, eInstructionTypePCModifying,
@@ -1018,7 +963,7 @@ NativeProcessLinux::SetupSoftwareSingleStepping(NativeThreadLinux &thread) {
if (emulator_ap == nullptr)
return Status("Instruction emulator not found!");
- EmulatorBaton baton(this, register_context_sp.get());
+ EmulatorBaton baton(*this, register_context);
emulator_ap->SetBaton(&baton);
emulator_ap->SetReadMemCallback(&ReadMemoryCallback);
emulator_ap->SetReadRegCallback(&ReadRegisterCallback);
@@ -1031,9 +976,9 @@ NativeProcessLinux::SetupSoftwareSingleStepping(NativeThreadLinux &thread) {
bool emulation_result =
emulator_ap->EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
- const RegisterInfo *reg_info_pc = register_context_sp->GetRegisterInfo(
+ const RegisterInfo *reg_info_pc = register_context.GetRegisterInfo(
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- const RegisterInfo *reg_info_flags = register_context_sp->GetRegisterInfo(
+ const RegisterInfo *reg_info_flags = register_context.GetRegisterInfo(
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
auto pc_it =
@@ -1051,15 +996,14 @@ NativeProcessLinux::SetupSoftwareSingleStepping(NativeThreadLinux &thread) {
if (flags_it != baton.m_register_values.end())
next_flags = flags_it->second.GetAsUInt64();
else
- next_flags = ReadFlags(register_context_sp.get());
+ next_flags = ReadFlags(register_context);
} else if (pc_it == baton.m_register_values.end()) {
// Emulate instruction failed and it haven't changed PC. Advance PC
// with the size of the current opcode because the emulation of all
// PC modifying instruction should be successful. The failure most
// likely caused by a not supported instruction which don't modify PC.
- next_pc =
- register_context_sp->GetPC() + emulator_ap->GetOpcode().GetByteSize();
- next_flags = ReadFlags(register_context_sp.get());
+ next_pc = register_context.GetPC() + emulator_ap->GetOpcode().GetByteSize();
+ next_flags = ReadFlags(register_context);
} else {
// The instruction emulation failed after it modified the PC. It is an
// unknown error where we can't continue because the next instruction is
@@ -1078,7 +1022,8 @@ NativeProcessLinux::SetupSoftwareSingleStepping(NativeThreadLinux &thread) {
} else if (m_arch.GetMachine() == llvm::Triple::mips64 ||
m_arch.GetMachine() == llvm::Triple::mips64el ||
m_arch.GetMachine() == llvm::Triple::mips ||
- m_arch.GetMachine() == llvm::Triple::mipsel)
+ m_arch.GetMachine() == llvm::Triple::mipsel ||
+ m_arch.GetMachine() == llvm::Triple::ppc64le)
error = SetSoftwareBreakpoint(next_pc, 4);
else {
// No size hint is given for the next breakpoint
@@ -1114,44 +1059,44 @@ Status NativeProcessLinux::Resume(const ResumeActionList &resume_actions) {
bool software_single_step = !SupportHardwareSingleStepping();
if (software_single_step) {
- for (auto thread_sp : m_threads) {
- assert(thread_sp && "thread list should not contain NULL threads");
+ for (const auto &thread : m_threads) {
+ assert(thread && "thread list should not contain NULL threads");
const ResumeAction *const action =
- resume_actions.GetActionForThread(thread_sp->GetID(), true);
+ resume_actions.GetActionForThread(thread->GetID(), true);
if (action == nullptr)
continue;
if (action->state == eStateStepping) {
Status error = SetupSoftwareSingleStepping(
- static_cast<NativeThreadLinux &>(*thread_sp));
+ static_cast<NativeThreadLinux &>(*thread));
if (error.Fail())
return error;
}
}
}
- for (auto thread_sp : m_threads) {
- assert(thread_sp && "thread list should not contain NULL threads");
+ for (const auto &thread : m_threads) {
+ assert(thread && "thread list should not contain NULL threads");
const ResumeAction *const action =
- resume_actions.GetActionForThread(thread_sp->GetID(), true);
+ resume_actions.GetActionForThread(thread->GetID(), true);
if (action == nullptr) {
LLDB_LOG(log, "no action specified for pid {0} tid {1}", GetID(),
- thread_sp->GetID());
+ thread->GetID());
continue;
}
LLDB_LOG(log, "processing resume action state {0} for pid {1} tid {2}",
- action->state, GetID(), thread_sp->GetID());
+ action->state, GetID(), thread->GetID());
switch (action->state) {
case eStateRunning:
case eStateStepping: {
// Run the thread, possibly feeding it the signal.
const int signo = action->signal;
- ResumeThread(static_cast<NativeThreadLinux &>(*thread_sp), action->state,
+ ResumeThread(static_cast<NativeThreadLinux &>(*thread), action->state,
signo);
break;
}
@@ -1164,7 +1109,7 @@ Status NativeProcessLinux::Resume(const ResumeActionList &resume_actions) {
return Status("NativeProcessLinux::%s (): unexpected state %s specified "
"for pid %" PRIu64 ", tid %" PRIu64,
__FUNCTION__, StateAsCString(action->state), GetID(),
- thread_sp->GetID());
+ thread->GetID());
}
}
@@ -1190,8 +1135,8 @@ Status NativeProcessLinux::Detach() {
if (GetID() == LLDB_INVALID_PROCESS_ID)
return error;
- for (auto thread_sp : m_threads) {
- Status e = Detach(thread_sp->GetID());
+ for (const auto &thread : m_threads) {
+ Status e = Detach(thread->GetID());
if (e.Fail())
error =
e; // Save the error, but still attempt to detach from other threads.
@@ -1221,29 +1166,25 @@ Status NativeProcessLinux::Interrupt() {
// the chosen thread that will be the stop-reason thread.
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- NativeThreadProtocolSP running_thread_sp;
- NativeThreadProtocolSP stopped_thread_sp;
+ NativeThreadProtocol *running_thread = nullptr;
+ NativeThreadProtocol *stopped_thread = nullptr;
LLDB_LOG(log, "selecting running thread for interrupt target");
- for (auto thread_sp : m_threads) {
- // The thread shouldn't be null but lets just cover that here.
- if (!thread_sp)
- continue;
-
+ for (const auto &thread : m_threads) {
// If we have a running or stepping thread, we'll call that the
// target of the interrupt.
- const auto thread_state = thread_sp->GetState();
+ const auto thread_state = thread->GetState();
if (thread_state == eStateRunning || thread_state == eStateStepping) {
- running_thread_sp = thread_sp;
+ running_thread = thread.get();
break;
- } else if (!stopped_thread_sp && StateIsStoppedState(thread_state, true)) {
+ } 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.
- stopped_thread_sp = thread_sp;
+ stopped_thread = thread.get();
}
}
- if (!running_thread_sp && !stopped_thread_sp) {
+ if (!running_thread && !stopped_thread) {
Status error("found no running/stepping or live stopped threads as target "
"for interrupt");
LLDB_LOG(log, "skipping due to error: {0}", error);
@@ -1251,14 +1192,14 @@ Status NativeProcessLinux::Interrupt() {
return error;
}
- NativeThreadProtocolSP deferred_signal_thread_sp =
- running_thread_sp ? running_thread_sp : stopped_thread_sp;
+ NativeThreadProtocol *deferred_signal_thread =
+ running_thread ? running_thread : stopped_thread;
LLDB_LOG(log, "pid {0} {1} tid {2} chosen for interrupt target", GetID(),
- running_thread_sp ? "running" : "stopped",
- deferred_signal_thread_sp->GetID());
+ running_thread ? "running" : "stopped",
+ deferred_signal_thread->GetID());
- StopRunningThreads(deferred_signal_thread_sp->GetID());
+ StopRunningThreads(deferred_signal_thread->GetID());
return Status();
}
@@ -1568,17 +1509,13 @@ size_t NativeProcessLinux::UpdateThreads() {
return m_threads.size();
}
-bool NativeProcessLinux::GetArchitecture(ArchSpec &arch) const {
- arch = m_arch;
- return true;
-}
-
Status NativeProcessLinux::GetSoftwareBreakpointPCOffset(
uint32_t &actual_opcode_size) {
// FIXME put this behind a breakpoint protocol class that can be
// set per architecture. Need ARM, MIPS support here.
static const uint8_t g_i386_opcode[] = {0xCC};
static const uint8_t g_s390x_opcode[] = {0x00, 0x01};
+ static const uint8_t g_ppc64le_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap
switch (m_arch.GetMachine()) {
case llvm::Triple::x86:
@@ -1590,6 +1527,10 @@ 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:
@@ -1635,6 +1576,7 @@ Status NativeProcessLinux::GetSoftwareBreakpointTrapOpcode(
static const uint8_t g_mips64el_opcode[] = {0x0d, 0x00, 0x00, 0x00};
static const uint8_t g_s390x_opcode[] = {0x00, 0x01};
static const uint8_t g_thumb_breakpoint_opcode[] = {0x01, 0xde};
+ static const uint8_t g_ppc64le_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap
switch (m_arch.GetMachine()) {
case llvm::Triple::aarch64:
@@ -1680,6 +1622,11 @@ Status NativeProcessLinux::GetSoftwareBreakpointTrapOpcode(
actual_opcode_size = sizeof(g_s390x_opcode);
return Status();
+ case llvm::Triple::ppc64le:
+ trap_opcode_bytes = g_ppc64le_opcode;
+ actual_opcode_size = sizeof(g_ppc64le_opcode);
+ return Status();
+
default:
assert(false && "CPU type not supported!");
return Status("CPU type not supported");
@@ -1963,9 +1910,9 @@ Status NativeProcessLinux::Detach(lldb::tid_t tid) {
}
bool NativeProcessLinux::HasThreadNoLock(lldb::tid_t thread_id) {
- for (auto thread_sp : m_threads) {
- assert(thread_sp && "thread list should not contain NULL threads");
- if (thread_sp->GetID() == thread_id) {
+ for (const auto &thread : m_threads) {
+ assert(thread && "thread list should not contain NULL threads");
+ if (thread->GetID() == thread_id) {
// We have this thread.
return true;
}
@@ -1994,7 +1941,7 @@ bool NativeProcessLinux::StopTrackingThread(lldb::tid_t thread_id) {
return found;
}
-NativeThreadLinuxSP NativeProcessLinux::AddThread(lldb::tid_t thread_id) {
+NativeThreadLinux &NativeProcessLinux::AddThread(lldb::tid_t thread_id) {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
LLDB_LOG(log, "pid {0} adding thread with tid {1}", GetID(), thread_id);
@@ -2005,8 +1952,7 @@ NativeThreadLinuxSP NativeProcessLinux::AddThread(lldb::tid_t thread_id) {
if (m_threads.empty())
SetCurrentThreadID(thread_id);
- auto thread_sp = std::make_shared<NativeThreadLinux>(*this, thread_id);
- m_threads.push_back(thread_sp);
+ m_threads.push_back(llvm::make_unique<NativeThreadLinux>(*this, thread_id));
if (m_pt_proces_trace_id != LLDB_INVALID_UID) {
auto traceMonitor = ProcessorTraceMonitor::Create(
@@ -2022,7 +1968,7 @@ NativeThreadLinuxSP NativeProcessLinux::AddThread(lldb::tid_t thread_id) {
}
}
- return thread_sp;
+ return static_cast<NativeThreadLinux &>(*m_threads.back());
}
Status
@@ -2033,12 +1979,7 @@ NativeProcessLinux::FixupBreakpointPCAsNeeded(NativeThreadLinux &thread) {
// Find out the size of a breakpoint (might depend on where we are in the
// code).
- NativeRegisterContextSP context_sp = thread.GetRegisterContext();
- if (!context_sp) {
- error.SetErrorString("cannot get a NativeRegisterContext for the thread");
- LLDB_LOG(log, "failed: {0}", error);
- return error;
- }
+ NativeRegisterContext &context = thread.GetRegisterContext();
uint32_t breakpoint_size = 0;
error = GetSoftwareBreakpointPCOffset(breakpoint_size);
@@ -2050,8 +1991,7 @@ NativeProcessLinux::FixupBreakpointPCAsNeeded(NativeThreadLinux &thread) {
// First try probing for a breakpoint at a software breakpoint location: PC -
// breakpoint size.
- const lldb::addr_t initial_pc_addr =
- context_sp->GetPCfromBreakpointLocation();
+ const lldb::addr_t initial_pc_addr = context.GetPCfromBreakpointLocation();
lldb::addr_t breakpoint_addr = initial_pc_addr;
if (breakpoint_size > 0) {
// Do not allow breakpoint probe to wrap around.
@@ -2098,7 +2038,7 @@ NativeProcessLinux::FixupBreakpointPCAsNeeded(NativeThreadLinux &thread) {
LLDB_LOG(log, "pid {0} tid {1}: changing PC from {2:x} to {3:x}", GetID(),
thread.GetID(), initial_pc_addr, breakpoint_addr);
- error = context_sp->SetPC(breakpoint_addr);
+ error = context.SetPC(breakpoint_addr);
if (error.Fail()) {
LLDB_LOG(log, "pid {0} tid {1}: failed to set PC: {2}", GetID(),
thread.GetID(), error);
@@ -2144,8 +2084,8 @@ Status NativeProcessLinux::GetFileLoadAddress(const llvm::StringRef &file_name,
return Status("No load address found for specified file.");
}
-NativeThreadLinuxSP NativeProcessLinux::GetThreadByID(lldb::tid_t tid) {
- return std::static_pointer_cast<NativeThreadLinux>(
+NativeThreadLinux *NativeProcessLinux::GetThreadByID(lldb::tid_t tid) {
+ return static_cast<NativeThreadLinux *>(
NativeProcessProtocol::GetThreadByID(tid));
}
@@ -2200,9 +2140,9 @@ void NativeProcessLinux::StopRunningThreads(const lldb::tid_t triggering_tid) {
// 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_sp : m_threads) {
- if (StateIsRunningState(thread_sp->GetState()))
- static_pointer_cast<NativeThreadLinux>(thread_sp)->RequestStop();
+ for (const auto &thread : m_threads) {
+ if (StateIsRunningState(thread->GetState()))
+ static_cast<NativeThreadLinux *>(thread.get())->RequestStop();
}
SignalIfAllThreadsStopped();
diff --git a/source/Plugins/Process/Linux/NativeProcessLinux.h b/source/Plugins/Process/Linux/NativeProcessLinux.h
index c9ec002760f88..f078c1ac30e2a 100644
--- a/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ b/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -13,12 +13,11 @@
#include <csignal>
#include <unordered_set>
-// Other libraries and framework includes
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Host/Debug.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Host/linux/Support.h"
#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/lldb-types.h"
@@ -87,7 +86,7 @@ public:
size_t UpdateThreads() override;
- bool GetArchitecture(ArchSpec &arch) const override;
+ const ArchSpec &GetArchitecture() const override { return m_arch; }
Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
bool hardware) override;
@@ -102,7 +101,7 @@ public:
Status GetFileLoadAddress(const llvm::StringRef &file_name,
lldb::addr_t &load_addr) override;
- NativeThreadLinuxSP GetThreadByID(lldb::tid_t id);
+ NativeThreadLinux *GetThreadByID(lldb::tid_t id);
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
GetAuxvData() const override {
@@ -203,7 +202,7 @@ private:
bool StopTrackingThread(lldb::tid_t thread_id);
- NativeThreadLinuxSP AddThread(lldb::tid_t thread_id);
+ NativeThreadLinux &AddThread(lldb::tid_t thread_id);
Status GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size);
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
index 30f09f0c3a3f5..c8a8355f9cb99 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
@@ -14,27 +14,19 @@
#include "lldb/Host/common/NativeThreadProtocol.h"
#include "lldb/Host/linux/Ptrace.h"
+#include "Plugins/Process/Linux/NativeProcessLinux.h"
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
using namespace lldb_private;
using namespace lldb_private::process_linux;
NativeRegisterContextLinux::NativeRegisterContextLinux(
- NativeThreadProtocol &native_thread, uint32_t concrete_frame_idx,
+ NativeThreadProtocol &native_thread,
RegisterInfoInterface *reg_info_interface_p)
- : NativeRegisterContextRegisterInfo(native_thread, concrete_frame_idx,
- reg_info_interface_p) {}
+ : NativeRegisterContextRegisterInfo(native_thread, reg_info_interface_p) {}
lldb::ByteOrder NativeRegisterContextLinux::GetByteOrder() const {
- // Get the target process whose privileged thread was used for the register
- // read.
- lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
-
- if (!m_thread.GetProcess().GetByteOrder(byte_order)) {
- // FIXME log here
- }
-
- return byte_order;
+ return m_thread.GetProcess().GetByteOrder();
}
Status NativeRegisterContextLinux::ReadRegisterRaw(uint32_t reg_index,
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
index 26074a6ce0e33..2cea497b53bcd 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
@@ -10,10 +10,8 @@
#ifndef lldb_NativeRegisterContextLinux_h
#define lldb_NativeRegisterContextLinux_h
-#include "lldb/Host/common/NativeThreadProtocol.h"
-
-#include "Plugins/Process/Linux/NativeProcessLinux.h"
#include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h"
+#include "lldb/Host/common/NativeThreadProtocol.h"
namespace lldb_private {
namespace process_linux {
@@ -21,20 +19,15 @@ namespace process_linux {
class NativeRegisterContextLinux : public NativeRegisterContextRegisterInfo {
public:
NativeRegisterContextLinux(NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx,
RegisterInfoInterface *reg_info_interface_p);
// This function is implemented in the NativeRegisterContextLinux_* subclasses
- // to create a new
- // instance of the host specific NativeRegisterContextLinux. The
- // implementations can't collide
- // as only one NativeRegisterContextLinux_* variant should be compiled into
- // the final
- // executable.
- static NativeRegisterContextLinux *
+ // to create a new instance of the host specific NativeRegisterContextLinux.
+ // The implementations can't collide as only one NativeRegisterContextLinux_*
+ // variant should be compiled into the final executable.
+ static std::unique_ptr<NativeRegisterContextLinux>
CreateHostNativeRegisterContextLinux(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+ NativeThreadProtocol &native_thread);
protected:
lldb::ByteOrder GetByteOrder() const;
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
index 22b7d10869fe0..cb05416cb6c33 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
@@ -11,15 +11,15 @@
#include "NativeRegisterContextLinux_arm.h"
+#include "Plugins/Process/Linux/NativeProcessLinux.h"
+#include "Plugins/Process/Linux/Procfs.h"
+#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
-#include "Plugins/Process/Linux/Procfs.h"
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
-
#include <elf.h>
#include <sys/socket.h>
@@ -95,20 +95,18 @@ static const RegisterSet g_reg_sets_arm[k_num_register_sets] = {
#if defined(__arm__)
-NativeRegisterContextLinux *
+std::unique_ptr<NativeRegisterContextLinux>
NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx) {
- return new NativeRegisterContextLinux_arm(target_arch, native_thread,
- concrete_frame_idx);
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ return llvm::make_unique<NativeRegisterContextLinux_arm>(target_arch,
+ native_thread);
}
#endif // defined(__arm__)
NativeRegisterContextLinux_arm::NativeRegisterContextLinux_arm(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx)
- : NativeRegisterContextLinux(native_thread, concrete_frame_idx,
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ : NativeRegisterContextLinux(native_thread,
new RegisterInfoPOSIX_arm(target_arch)) {
switch (target_arch.GetMachine()) {
case llvm::Triple::arm:
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
index ec99c05e16444..40e3b80eda743 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
@@ -23,8 +23,7 @@ class NativeProcessLinux;
class NativeRegisterContextLinux_arm : public NativeRegisterContextLinux {
public:
NativeRegisterContextLinux_arm(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+ NativeThreadProtocol &native_thread);
uint32_t GetRegisterSetCount() const override;
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
index 7aad062e3f93d..c483260a5b2c8 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
@@ -112,26 +112,24 @@ static const RegisterSet g_reg_sets_arm64[k_num_register_sets] = {
{"Floating Point Registers", "fpu", k_num_fpr_registers_arm64,
g_fpu_regnums_arm64}};
-NativeRegisterContextLinux *
+std::unique_ptr<NativeRegisterContextLinux>
NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx) {
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
switch (target_arch.GetMachine()) {
case llvm::Triple::arm:
- return new NativeRegisterContextLinux_arm(target_arch, native_thread,
- concrete_frame_idx);
+ return llvm::make_unique<NativeRegisterContextLinux_arm>(target_arch,
+ native_thread);
case llvm::Triple::aarch64:
- return new NativeRegisterContextLinux_arm64(target_arch, native_thread,
- concrete_frame_idx);
+ return llvm::make_unique<NativeRegisterContextLinux_arm64>(target_arch,
+ native_thread);
default:
llvm_unreachable("have no register context for architecture");
}
}
NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx)
- : NativeRegisterContextLinux(native_thread, concrete_frame_idx,
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ : NativeRegisterContextLinux(native_thread,
new RegisterInfoPOSIX_arm64(target_arch)) {
switch (target_arch.GetMachine()) {
case llvm::Triple::aarch64:
@@ -872,12 +870,8 @@ Status NativeRegisterContextLinux_arm64::DoReadRegisterValue(
error = NativeProcessLinux::PtraceWrapper(
PTRACE_GETREGSET, m_thread.GetID(), &regset, &ioVec, sizeof regs);
if (error.Success()) {
- ArchSpec arch;
- if (m_thread.GetProcess().GetArchitecture(arch))
- value.SetBytes((void *)(((unsigned char *)(&regs)) + offset), 16,
- arch.GetByteOrder());
- else
- error.SetErrorString("failed to get architecture");
+ value.SetBytes((void *)(((unsigned char *)(&regs)) + offset), 16,
+ m_thread.GetProcess().GetByteOrder());
}
} else {
elf_gregset_t regs;
@@ -889,12 +883,8 @@ Status NativeRegisterContextLinux_arm64::DoReadRegisterValue(
error = NativeProcessLinux::PtraceWrapper(
PTRACE_GETREGSET, m_thread.GetID(), &regset, &ioVec, sizeof regs);
if (error.Success()) {
- ArchSpec arch;
- if (m_thread.GetProcess().GetArchitecture(arch))
- value.SetBytes((void *)(((unsigned char *)(regs)) + offset), 8,
- arch.GetByteOrder());
- else
- error.SetErrorString("failed to get architecture");
+ value.SetBytes((void *)(((unsigned char *)(regs)) + offset), 8,
+ m_thread.GetProcess().GetByteOrder());
}
}
return error;
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
index 9877dec37c48e..ab3c881ead598 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
@@ -23,8 +23,7 @@ class NativeProcessLinux;
class NativeRegisterContextLinux_arm64 : public NativeRegisterContextLinux {
public:
NativeRegisterContextLinux_arm64(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+ NativeThreadProtocol &native_thread);
uint32_t GetRegisterSetCount() const override;
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
index f35ff2be0d94d..32c04a4374e62 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
@@ -80,12 +80,11 @@ struct pt_watch_regs default_watch_regs;
using namespace lldb_private;
using namespace lldb_private::process_linux;
-NativeRegisterContextLinux *
+std::unique_ptr<NativeRegisterContextLinux>
NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx) {
- return new NativeRegisterContextLinux_mips64(target_arch, native_thread,
- concrete_frame_idx);
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ return llvm::make_unique<NativeRegisterContextLinux_mips64>(target_arch,
+ native_thread);
}
#define REG_CONTEXT_SIZE \
@@ -110,9 +109,8 @@ CreateRegisterInfoInterface(const ArchSpec &target_arch) {
}
NativeRegisterContextLinux_mips64::NativeRegisterContextLinux_mips64(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx)
- : NativeRegisterContextLinux(native_thread, concrete_frame_idx,
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ : NativeRegisterContextLinux(native_thread,
CreateRegisterInfoInterface(target_arch)) {
switch (target_arch.GetMachine()) {
case llvm::Triple::mips:
@@ -1033,13 +1031,11 @@ Status NativeRegisterContextLinux_mips64::Read_SR_Config(uint32_t offset,
Status error = NativeProcessLinux::PtraceWrapper(
PTRACE_GETREGS, m_thread.GetID(), NULL, &regs, sizeof regs);
if (error.Success()) {
- lldb_private::ArchSpec arch;
- if (m_thread.GetProcess().GetArchitecture(arch)) {
- void *target_address = ((uint8_t *)&regs) + offset +
- 4 * (arch.GetMachine() == llvm::Triple::mips);
- value.SetUInt(*(uint32_t *)target_address, size);
- } else
- error.SetErrorString("failed to get architecture");
+ const lldb_private::ArchSpec &arch =
+ m_thread.GetProcess().GetArchitecture();
+ void *target_address = ((uint8_t *)&regs) + offset +
+ 4 * (arch.GetMachine() == llvm::Triple::mips);
+ value.SetUInt(*(uint32_t *)target_address, size);
}
return error;
}
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
index 3e14da5a27257..c4e984a545bc6 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
@@ -15,6 +15,7 @@
#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
#include "Plugins/Process/Utility/RegisterContext_mips.h"
#include "Plugins/Process/Utility/lldb-mips-linux-register-enums.h"
+#include <sys/uio.h>
#define MAX_NUM_WP 8
@@ -26,8 +27,7 @@ class NativeProcessLinux;
class NativeRegisterContextLinux_mips64 : public NativeRegisterContextLinux {
public:
NativeRegisterContextLinux_mips64(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+ NativeThreadProtocol &native_thread);
uint32_t GetRegisterSetCount() const override;
@@ -129,7 +129,7 @@ private:
lldb::addr_t hw_addr_map[MAX_NUM_WP];
- IOVEC_mips m_iovec;
+ struct iovec m_iovec;
};
} // namespace process_linux
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp
new file mode 100644
index 0000000000000..ea854dfa1dc6d
--- /dev/null
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp
@@ -0,0 +1,801 @@
+//===-- NativeRegisterContextLinux_ppc64le.cpp ------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// This implementation is related to the OpenPOWER ABI for Power Architecture
+// 64-bit ELF V2 ABI
+
+#if defined(__powerpc64__)
+
+#include "NativeRegisterContextLinux_ppc64le.h"
+
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Status.h"
+
+#include "Plugins/Process/Linux/NativeProcessLinux.h"
+#include "Plugins/Process/Linux/Procfs.h"
+#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+#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
+#include <sys/socket.h>
+#include <elf.h>
+#include <asm/ptrace.h>
+
+#define REG_CONTEXT_SIZE \
+ (GetGPRSize() + GetFPRSize() + sizeof(m_vmx_ppc64le) + sizeof(m_vsx_ppc64le))
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_linux;
+
+static const uint32_t g_gpr_regnums_ppc64le[] = {
+ gpr_r0_ppc64le, gpr_r1_ppc64le, gpr_r2_ppc64le, gpr_r3_ppc64le,
+ gpr_r4_ppc64le, gpr_r5_ppc64le, gpr_r6_ppc64le, gpr_r7_ppc64le,
+ gpr_r8_ppc64le, gpr_r9_ppc64le, gpr_r10_ppc64le, gpr_r11_ppc64le,
+ gpr_r12_ppc64le, gpr_r13_ppc64le, gpr_r14_ppc64le, gpr_r15_ppc64le,
+ gpr_r16_ppc64le, gpr_r17_ppc64le, gpr_r18_ppc64le, gpr_r19_ppc64le,
+ gpr_r20_ppc64le, gpr_r21_ppc64le, gpr_r22_ppc64le, gpr_r23_ppc64le,
+ gpr_r24_ppc64le, gpr_r25_ppc64le, gpr_r26_ppc64le, gpr_r27_ppc64le,
+ gpr_r28_ppc64le, gpr_r29_ppc64le, gpr_r30_ppc64le, gpr_r31_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,
+};
+
+static const uint32_t g_fpr_regnums_ppc64le[] = {
+ fpr_f0_ppc64le, fpr_f1_ppc64le, fpr_f2_ppc64le, fpr_f3_ppc64le,
+ fpr_f4_ppc64le, fpr_f5_ppc64le, fpr_f6_ppc64le, fpr_f7_ppc64le,
+ fpr_f8_ppc64le, fpr_f9_ppc64le, fpr_f10_ppc64le, fpr_f11_ppc64le,
+ fpr_f12_ppc64le, fpr_f13_ppc64le, fpr_f14_ppc64le, fpr_f15_ppc64le,
+ fpr_f16_ppc64le, fpr_f17_ppc64le, fpr_f18_ppc64le, fpr_f19_ppc64le,
+ fpr_f20_ppc64le, fpr_f21_ppc64le, fpr_f22_ppc64le, fpr_f23_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,
+};
+
+static const uint32_t g_vmx_regnums_ppc64le[] = {
+ vmx_vr0_ppc64le, vmx_vr1_ppc64le, vmx_vr2_ppc64le, vmx_vr3_ppc64le,
+ vmx_vr4_ppc64le, vmx_vr5_ppc64le, vmx_vr6_ppc64le, vmx_vr7_ppc64le,
+ vmx_vr8_ppc64le, vmx_vr9_ppc64le, vmx_vr10_ppc64le, vmx_vr11_ppc64le,
+ vmx_vr12_ppc64le, vmx_vr13_ppc64le, vmx_vr14_ppc64le, vmx_vr15_ppc64le,
+ vmx_vr16_ppc64le, vmx_vr17_ppc64le, vmx_vr18_ppc64le, vmx_vr19_ppc64le,
+ vmx_vr20_ppc64le, vmx_vr21_ppc64le, vmx_vr22_ppc64le, vmx_vr23_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,
+};
+
+static const uint32_t g_vsx_regnums_ppc64le[] = {
+ vsx_vs0_ppc64le, vsx_vs1_ppc64le, vsx_vs2_ppc64le, vsx_vs3_ppc64le,
+ vsx_vs4_ppc64le, vsx_vs5_ppc64le, vsx_vs6_ppc64le, vsx_vs7_ppc64le,
+ vsx_vs8_ppc64le, vsx_vs9_ppc64le, vsx_vs10_ppc64le, vsx_vs11_ppc64le,
+ vsx_vs12_ppc64le, vsx_vs13_ppc64le, vsx_vs14_ppc64le, vsx_vs15_ppc64le,
+ vsx_vs16_ppc64le, vsx_vs17_ppc64le, vsx_vs18_ppc64le, vsx_vs19_ppc64le,
+ vsx_vs20_ppc64le, vsx_vs21_ppc64le, vsx_vs22_ppc64le, vsx_vs23_ppc64le,
+ vsx_vs24_ppc64le, vsx_vs25_ppc64le, vsx_vs26_ppc64le, vsx_vs27_ppc64le,
+ vsx_vs28_ppc64le, vsx_vs29_ppc64le, vsx_vs30_ppc64le, vsx_vs31_ppc64le,
+ vsx_vs32_ppc64le, vsx_vs33_ppc64le, vsx_vs34_ppc64le, vsx_vs35_ppc64le,
+ vsx_vs36_ppc64le, vsx_vs37_ppc64le, vsx_vs38_ppc64le, vsx_vs39_ppc64le,
+ vsx_vs40_ppc64le, vsx_vs41_ppc64le, vsx_vs42_ppc64le, vsx_vs43_ppc64le,
+ vsx_vs44_ppc64le, vsx_vs45_ppc64le, vsx_vs46_ppc64le, vsx_vs47_ppc64le,
+ vsx_vs48_ppc64le, vsx_vs49_ppc64le, vsx_vs50_ppc64le, vsx_vs51_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,
+};
+
+namespace {
+// Number of register sets provided by this context.
+enum { k_num_register_sets = 4 };
+}
+
+static const RegisterSet g_reg_sets_ppc64le[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_ppc64le,
+ g_gpr_regnums_ppc64le},
+ {"Floating Point Registers", "fpr", k_num_fpr_registers_ppc64le,
+ g_fpr_regnums_ppc64le},
+ {"AltiVec/VMX Registers", "vmx", k_num_vmx_registers_ppc64le,
+ g_vmx_regnums_ppc64le},
+ {"VSX Registers", "vsx", k_num_vsx_registers_ppc64le,
+ g_vsx_regnums_ppc64le},
+};
+
+std::unique_ptr<NativeRegisterContextLinux>
+NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::ppc64le:
+ return llvm::make_unique<NativeRegisterContextLinux_ppc64le>(target_arch,
+ native_thread);
+ default:
+ llvm_unreachable("have no register context for architecture");
+ }
+}
+
+NativeRegisterContextLinux_ppc64le::NativeRegisterContextLinux_ppc64le(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ : NativeRegisterContextLinux(native_thread,
+ new RegisterInfoPOSIX_ppc64le(target_arch)) {
+ if (target_arch.GetMachine() != llvm::Triple::ppc64le) {
+ llvm_unreachable("Unhandled target architecture.");
+ }
+
+ ::memset(&m_gpr_ppc64le, 0, sizeof(m_gpr_ppc64le));
+ ::memset(&m_fpr_ppc64le, 0, sizeof(m_fpr_ppc64le));
+ ::memset(&m_vmx_ppc64le, 0, sizeof(m_vmx_ppc64le));
+ ::memset(&m_vsx_ppc64le, 0, sizeof(m_vsx_ppc64le));
+ ::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs));
+}
+
+uint32_t NativeRegisterContextLinux_ppc64le::GetRegisterSetCount() const {
+ return k_num_register_sets;
+}
+
+const RegisterSet *
+NativeRegisterContextLinux_ppc64le::GetRegisterSet(uint32_t set_index) const {
+ if (set_index < k_num_register_sets)
+ return &g_reg_sets_ppc64le[set_index];
+
+ return nullptr;
+}
+
+uint32_t NativeRegisterContextLinux_ppc64le::GetUserRegisterCount() const {
+ uint32_t count = 0;
+ for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
+ count += g_reg_sets_ppc64le[set_index].num_registers;
+ return count;
+}
+
+Status NativeRegisterContextLinux_ppc64le::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &reg_value) {
+ Status error;
+
+ if (!reg_info) {
+ error.SetErrorString("reg_info NULL");
+ return error;
+ }
+
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+
+ if (IsFPR(reg)) {
+ error = ReadFPR();
+ if (error.Fail())
+ return error;
+
+ // Get pointer to m_fpr_ppc64le variable and set the data from it.
+ uint32_t fpr_offset = CalculateFprOffset(reg_info);
+ assert(fpr_offset < sizeof m_fpr_ppc64le);
+ uint8_t *src = (uint8_t *)&m_fpr_ppc64le + fpr_offset;
+ reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size,
+ eByteOrderLittle, error);
+ } else if (IsVSX(reg)) {
+ uint32_t vsx_offset = CalculateVsxOffset(reg_info);
+ assert(vsx_offset < sizeof(m_vsx_ppc64le));
+
+ if (vsx_offset < sizeof(m_vsx_ppc64le) / 2) {
+ error = ReadVSX();
+ if (error.Fail())
+ return error;
+
+ error = ReadFPR();
+ if (error.Fail())
+ return error;
+
+ uint64_t value[2];
+ uint8_t *dst, *src;
+ dst = (uint8_t *)&value;
+ src = (uint8_t *)&m_vsx_ppc64le + vsx_offset / 2;
+ ::memcpy(dst, src, 8);
+ dst += 8;
+ src = (uint8_t *)&m_fpr_ppc64le + vsx_offset / 2;
+ ::memcpy(dst, src, 8);
+ reg_value.SetFromMemoryData(reg_info, &value, reg_info->byte_size,
+ eByteOrderLittle, error);
+ } else {
+ error = ReadVMX();
+ if (error.Fail())
+ return error;
+
+ // Get pointer to m_vmx_ppc64le variable and set the data from it.
+ uint32_t vmx_offset = vsx_offset - sizeof(m_vsx_ppc64le) / 2;
+ uint8_t *src = (uint8_t *)&m_vmx_ppc64le + vmx_offset;
+ reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size,
+ eByteOrderLittle, error);
+ }
+ } else if (IsVMX(reg)) {
+ error = ReadVMX();
+ if (error.Fail())
+ return error;
+
+ // Get pointer to m_vmx_ppc64le variable and set the data from it.
+ uint32_t vmx_offset = CalculateVmxOffset(reg_info);
+ assert(vmx_offset < sizeof m_vmx_ppc64le);
+ uint8_t *src = (uint8_t *)&m_vmx_ppc64le + vmx_offset;
+ reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size,
+ eByteOrderLittle, error);
+ } else if (IsGPR(reg)) {
+ error = ReadGPR();
+ if (error.Fail())
+ return error;
+
+ uint8_t *src = (uint8_t *) &m_gpr_ppc64le + reg_info->byte_offset;
+ reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size,
+ eByteOrderLittle, error);
+ } else {
+ return Status("failed - register wasn't recognized to be a GPR, FPR, VSX "
+ "or VMX, read strategy unknown");
+ }
+
+ return error;
+}
+
+Status NativeRegisterContextLinux_ppc64le::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+ Status error;
+ if (!reg_info)
+ return Status("reg_info NULL");
+
+ const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg_index == LLDB_INVALID_REGNUM)
+ return Status("no lldb regnum for %s", reg_info && reg_info->name
+ ? reg_info->name
+ : "<unknown register>");
+
+ if (IsGPR(reg_index)) {
+ error = ReadGPR();
+ if (error.Fail())
+ return error;
+
+ uint8_t *dst = (uint8_t *)&m_gpr_ppc64le + reg_info->byte_offset;
+ ::memcpy(dst, reg_value.GetBytes(), reg_value.GetByteSize());
+
+ error = WriteGPR();
+ if (error.Fail())
+ return error;
+
+ return Status();
+ }
+
+ if (IsFPR(reg_index)) {
+ error = ReadFPR();
+ if (error.Fail())
+ return error;
+
+ // Get pointer to m_fpr_ppc64le variable and set the data to it.
+ uint32_t fpr_offset = CalculateFprOffset(reg_info);
+ assert(fpr_offset < GetFPRSize());
+ uint8_t *dst = (uint8_t *)&m_fpr_ppc64le + fpr_offset;
+ ::memcpy(dst, reg_value.GetBytes(), reg_value.GetByteSize());
+
+ error = WriteFPR();
+ if (error.Fail())
+ return error;
+
+ return Status();
+ }
+
+ if (IsVMX(reg_index)) {
+ error = ReadVMX();
+ if (error.Fail())
+ return error;
+
+ // Get pointer to m_vmx_ppc64le variable and set the data to it.
+ uint32_t vmx_offset = CalculateVmxOffset(reg_info);
+ assert(vmx_offset < sizeof(m_vmx_ppc64le));
+ uint8_t *dst = (uint8_t *)&m_vmx_ppc64le + vmx_offset;
+ ::memcpy(dst, reg_value.GetBytes(), reg_value.GetByteSize());
+
+ error = WriteVMX();
+ if (error.Fail())
+ return error;
+
+ return Status();
+ }
+
+ if (IsVSX(reg_index)) {
+ uint32_t vsx_offset = CalculateVsxOffset(reg_info);
+ assert(vsx_offset < sizeof(m_vsx_ppc64le));
+
+ if (vsx_offset < sizeof(m_vsx_ppc64le) / 2) {
+ error = ReadVSX();
+ if (error.Fail())
+ return error;
+
+ error = ReadFPR();
+ if (error.Fail())
+ return error;
+
+ uint64_t value[2];
+ ::memcpy(value, reg_value.GetBytes(), 16);
+ uint8_t *dst, *src;
+ src = (uint8_t *)value;
+ dst = (uint8_t *)&m_vsx_ppc64le + vsx_offset / 2;
+ ::memcpy(dst, src, 8);
+ src += 8;
+ dst = (uint8_t *)&m_fpr_ppc64le + vsx_offset / 2;
+ ::memcpy(dst, src, 8);
+
+ WriteVSX();
+ WriteFPR();
+ } else {
+ error = ReadVMX();
+ if (error.Fail())
+ return error;
+
+ // Get pointer to m_vmx_ppc64le variable and set the data from it.
+ uint32_t vmx_offset = vsx_offset - sizeof(m_vsx_ppc64le) / 2;
+ uint8_t *dst = (uint8_t *)&m_vmx_ppc64le + vmx_offset;
+ ::memcpy(dst, reg_value.GetBytes(), reg_value.GetByteSize());
+ WriteVMX();
+ }
+
+ return Status();
+ }
+
+ return Status("failed - register wasn't recognized to be a GPR, FPR, VSX "
+ "or VMX, write strategy unknown");
+}
+
+Status NativeRegisterContextLinux_ppc64le::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ Status error;
+
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (!data_sp)
+ return Status("failed to allocate DataBufferHeap instance of size %" PRIu64,
+ REG_CONTEXT_SIZE);
+
+ error = ReadGPR();
+ if (error.Fail())
+ return error;
+
+ error = ReadFPR();
+ if (error.Fail())
+ return error;
+
+ error = ReadVMX();
+ if (error.Fail())
+ return error;
+
+ error = ReadVSX();
+ if (error.Fail())
+ return error;
+
+ uint8_t *dst = data_sp->GetBytes();
+ if (dst == nullptr) {
+ error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64
+ " returned a null pointer",
+ REG_CONTEXT_SIZE);
+ return error;
+ }
+
+ ::memcpy(dst, &m_gpr_ppc64le, GetGPRSize());
+ dst += GetGPRSize();
+ ::memcpy(dst, &m_fpr_ppc64le, GetFPRSize());
+ dst += GetFPRSize();
+ ::memcpy(dst, &m_vmx_ppc64le, sizeof(m_vmx_ppc64le));
+ dst += sizeof(m_vmx_ppc64le);
+ ::memcpy(dst, &m_vsx_ppc64le, sizeof(m_vsx_ppc64le));
+
+ return error;
+}
+
+Status NativeRegisterContextLinux_ppc64le::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ Status error;
+
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_ppc64le::%s invalid data_sp provided",
+ __FUNCTION__);
+ return error;
+ }
+
+ if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_ppc64le::%s data_sp contained mismatched "
+ "data size, expected %" PRIu64 ", actual %" PRIu64,
+ __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
+ return error;
+ }
+
+ uint8_t *src = data_sp->GetBytes();
+ if (src == nullptr) {
+ error.SetErrorStringWithFormat("NativeRegisterContextLinux_ppc64le::%s "
+ "DataBuffer::GetBytes() returned a null "
+ "pointer",
+ __FUNCTION__);
+ return error;
+ }
+
+ ::memcpy(&m_gpr_ppc64le, src, GetGPRSize());
+ error = WriteGPR();
+
+ if (error.Fail())
+ return error;
+
+ src += GetGPRSize();
+ ::memcpy(&m_fpr_ppc64le, src, GetFPRSize());
+
+ error = WriteFPR();
+ if (error.Fail())
+ return error;
+
+ src += GetFPRSize();
+ ::memcpy(&m_vmx_ppc64le, src, sizeof(m_vmx_ppc64le));
+
+ error = WriteVMX();
+ if (error.Fail())
+ return error;
+
+ src += sizeof(m_vmx_ppc64le);
+ ::memcpy(&m_vsx_ppc64le, src, sizeof(m_vsx_ppc64le));
+ error = WriteVSX();
+
+ return error;
+}
+
+bool NativeRegisterContextLinux_ppc64le::IsGPR(unsigned reg) const {
+ return reg <= k_last_gpr_ppc64le; // GPR's come first.
+}
+
+bool NativeRegisterContextLinux_ppc64le::IsFPR(unsigned reg) const {
+ return (k_first_fpr_ppc64le <= reg && reg <= k_last_fpr_ppc64le);
+}
+
+Status NativeRegisterContextLinux_ppc64le::DoReadGPR(
+ void *buf, size_t buf_size) {
+ int regset = NT_PRSTATUS;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_thread.GetID(),
+ &regset, buf, buf_size);
+}
+
+Status NativeRegisterContextLinux_ppc64le::DoWriteGPR(
+ void *buf, size_t buf_size) {
+ int regset = NT_PRSTATUS;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGS, m_thread.GetID(),
+ &regset, buf, buf_size);
+}
+
+Status NativeRegisterContextLinux_ppc64le::DoReadFPR(void *buf,
+ size_t buf_size) {
+ int regset = NT_FPREGSET;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_GETFPREGS, m_thread.GetID(),
+ &regset, buf, buf_size);
+}
+
+Status NativeRegisterContextLinux_ppc64le::DoWriteFPR(void *buf,
+ size_t buf_size) {
+ int regset = NT_FPREGSET;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETFPREGS, m_thread.GetID(),
+ &regset, buf, buf_size);
+}
+
+uint32_t NativeRegisterContextLinux_ppc64le::CalculateFprOffset(
+ const RegisterInfo *reg_info) const {
+ return reg_info->byte_offset -
+ GetRegisterInfoAtIndex(k_first_fpr_ppc64le)->byte_offset;
+}
+
+uint32_t NativeRegisterContextLinux_ppc64le::CalculateVmxOffset(
+ const RegisterInfo *reg_info) const {
+ return reg_info->byte_offset -
+ GetRegisterInfoAtIndex(k_first_vmx_ppc64le)->byte_offset;
+}
+
+uint32_t NativeRegisterContextLinux_ppc64le::CalculateVsxOffset(
+ const RegisterInfo *reg_info) const {
+ return reg_info->byte_offset -
+ GetRegisterInfoAtIndex(k_first_vsx_ppc64le)->byte_offset;
+}
+
+Status NativeRegisterContextLinux_ppc64le::ReadVMX() {
+ int regset = NT_PPC_VMX;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_GETVRREGS, m_thread.GetID(),
+ &regset, &m_vmx_ppc64le,
+ sizeof(m_vmx_ppc64le));
+}
+
+Status NativeRegisterContextLinux_ppc64le::WriteVMX() {
+ int regset = NT_PPC_VMX;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETVRREGS, m_thread.GetID(),
+ &regset, &m_vmx_ppc64le,
+ sizeof(m_vmx_ppc64le));
+}
+
+Status NativeRegisterContextLinux_ppc64le::ReadVSX() {
+ int regset = NT_PPC_VSX;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_GETVSRREGS, m_thread.GetID(),
+ &regset, &m_vsx_ppc64le,
+ sizeof(m_vsx_ppc64le));
+}
+
+Status NativeRegisterContextLinux_ppc64le::WriteVSX() {
+ int regset = NT_PPC_VSX;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETVSRREGS, m_thread.GetID(),
+ &regset, &m_vsx_ppc64le,
+ sizeof(m_vsx_ppc64le));
+}
+
+bool NativeRegisterContextLinux_ppc64le::IsVMX(unsigned reg) {
+ return (reg >= k_first_vmx_ppc64le) && (reg <= k_last_vmx_ppc64le);
+}
+
+bool NativeRegisterContextLinux_ppc64le::IsVSX(unsigned reg) {
+ return (reg >= k_first_vsx_ppc64le) && (reg <= k_last_vsx_ppc64le);
+}
+
+uint32_t NativeRegisterContextLinux_ppc64le::NumSupportedHardwareWatchpoints() {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
+
+ // Read hardware breakpoint and watchpoint information.
+ Status error = ReadHardwareDebugInfo();
+
+ if (error.Fail())
+ return 0;
+
+ LLDB_LOG(log, "{0}", m_max_hwp_supported);
+ return m_max_hwp_supported;
+}
+
+uint32_t NativeRegisterContextLinux_ppc64le::SetHardwareWatchpoint(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "addr: {0:x}, size: {1:x} watch_flags: {2:x}", addr, size,
+ watch_flags);
+
+ // Read hardware breakpoint and watchpoint information.
+ Status error = ReadHardwareDebugInfo();
+
+ if (error.Fail())
+ return LLDB_INVALID_INDEX32;
+
+ uint32_t control_value = 0, wp_index = 0;
+ 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.
+ switch (watch_flags) {
+ case eWatchpointKindWrite:
+ rw_mode = PPC_BREAKPOINT_TRIGGER_WRITE;
+ watch_flags = 2;
+ break;
+ case eWatchpointKindRead:
+ rw_mode = PPC_BREAKPOINT_TRIGGER_READ;
+ watch_flags = 1;
+ break;
+ case (eWatchpointKindRead | eWatchpointKindWrite):
+ rw_mode = PPC_BREAKPOINT_TRIGGER_RW;
+ break;
+ default:
+ return LLDB_INVALID_INDEX32;
+ }
+
+ // Check if size has a valid hardware watchpoint length.
+ if (size != 1 && size != 2 && size != 4 && size != 8)
+ return LLDB_INVALID_INDEX32;
+
+ // Check 8-byte alignment for hardware watchpoint target address.
+ // Below is a hack to recalculate address and size in order to
+ // make sure we can watch non 8-byte alligned addresses as well.
+ if (addr & 0x07) {
+
+ addr_t begin = llvm::alignDown(addr, 8);
+ addr_t end = llvm::alignTo(addr + size, 8);
+ size = llvm::PowerOf2Ceil(end - begin);
+
+ addr = addr & (~0x07);
+ }
+
+ // Setup control value
+ control_value = watch_flags << 3;
+ control_value |= ((1 << size) - 1) << 5;
+ control_value |= (2 << 1) | 1;
+
+ // Iterate over stored watchpoints and find a free wp_index
+ wp_index = LLDB_INVALID_INDEX32;
+ for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
+ if ((m_hwp_regs[i].control & 1) == 0) {
+ wp_index = i; // Mark last free slot
+ } else if (m_hwp_regs[i].address == addr) {
+ return LLDB_INVALID_INDEX32; // We do not support duplicate watchpoints.
+ }
+ }
+
+ if (wp_index == LLDB_INVALID_INDEX32)
+ return LLDB_INVALID_INDEX32;
+
+ // Update watchpoint in local cache
+ m_hwp_regs[wp_index].real_addr = real_addr;
+ m_hwp_regs[wp_index].address = addr;
+ m_hwp_regs[wp_index].control = control_value;
+ m_hwp_regs[wp_index].mode = rw_mode;
+
+ // PTRACE call to set corresponding watchpoint register.
+ error = WriteHardwareDebugRegs();
+
+ if (error.Fail()) {
+ m_hwp_regs[wp_index].address = 0;
+ m_hwp_regs[wp_index].control &= llvm::maskTrailingZeros<uint32_t>(1);
+
+ return LLDB_INVALID_INDEX32;
+ }
+
+ return wp_index;
+}
+
+bool NativeRegisterContextLinux_ppc64le::ClearHardwareWatchpoint(
+ uint32_t wp_index) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+ // Read hardware breakpoint and watchpoint information.
+ Status error = ReadHardwareDebugInfo();
+
+ if (error.Fail())
+ return false;
+
+ if (wp_index >= m_max_hwp_supported)
+ return false;
+
+ // Create a backup we can revert to in case of failure.
+ lldb::addr_t tempAddr = m_hwp_regs[wp_index].address;
+ uint32_t tempControl = m_hwp_regs[wp_index].control;
+ long *tempSlot = reinterpret_cast<long *>(m_hwp_regs[wp_index].slot);
+
+ // Update watchpoint in local cache
+ m_hwp_regs[wp_index].control &= llvm::maskTrailingZeros<uint32_t>(1);
+ m_hwp_regs[wp_index].address = 0;
+ m_hwp_regs[wp_index].slot = 0;
+ m_hwp_regs[wp_index].mode = 0;
+
+ // Ptrace call to update hardware debug registers
+ error = NativeProcessLinux::PtraceWrapper(PPC_PTRACE_DELHWDEBUG,
+ m_thread.GetID(), 0, tempSlot);
+
+ if (error.Fail()) {
+ m_hwp_regs[wp_index].control = tempControl;
+ m_hwp_regs[wp_index].address = tempAddr;
+ m_hwp_regs[wp_index].slot = reinterpret_cast<long>(tempSlot);
+
+ return false;
+ }
+
+ return true;
+}
+
+uint32_t
+NativeRegisterContextLinux_ppc64le::GetWatchpointSize(uint32_t wp_index) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+ unsigned control = (m_hwp_regs[wp_index].control >> 5) & 0xff;
+ if (llvm::isPowerOf2_32(control + 1)) {
+ return llvm::countPopulation(control);
+ }
+
+ return 0;
+}
+
+bool NativeRegisterContextLinux_ppc64le::WatchpointIsEnabled(
+ uint32_t wp_index) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+ return !!((m_hwp_regs[wp_index].control & 0x1) == 0x1);
+}
+
+Status NativeRegisterContextLinux_ppc64le::GetWatchpointHitIndex(
+ uint32_t &wp_index, lldb::addr_t trap_addr) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "wp_index: {0}, trap_addr: {1:x}", wp_index, trap_addr);
+
+ uint32_t watch_size;
+ lldb::addr_t watch_addr;
+
+ for (wp_index = 0; wp_index < m_max_hwp_supported; ++wp_index) {
+ watch_size = GetWatchpointSize(wp_index);
+ watch_addr = m_hwp_regs[wp_index].address;
+
+ if (WatchpointIsEnabled(wp_index) && trap_addr >= watch_addr &&
+ trap_addr <= watch_addr + watch_size) {
+ m_hwp_regs[wp_index].hit_addr = trap_addr;
+ return Status();
+ }
+ }
+
+ wp_index = LLDB_INVALID_INDEX32;
+ return Status();
+}
+
+lldb::addr_t
+NativeRegisterContextLinux_ppc64le::GetWatchpointAddress(uint32_t wp_index) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+ if (wp_index >= m_max_hwp_supported)
+ return LLDB_INVALID_ADDRESS;
+
+ if (WatchpointIsEnabled(wp_index))
+ return m_hwp_regs[wp_index].real_addr;
+ else
+ return LLDB_INVALID_ADDRESS;
+}
+
+lldb::addr_t
+NativeRegisterContextLinux_ppc64le::GetWatchpointHitAddress(uint32_t wp_index) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+ if (wp_index >= m_max_hwp_supported)
+ return LLDB_INVALID_ADDRESS;
+
+ if (WatchpointIsEnabled(wp_index))
+ return m_hwp_regs[wp_index].hit_addr;
+
+ return LLDB_INVALID_ADDRESS;
+}
+
+Status NativeRegisterContextLinux_ppc64le::ReadHardwareDebugInfo() {
+ if (!m_refresh_hwdebug_info) {
+ return Status();
+ }
+
+ ::pid_t tid = m_thread.GetID();
+
+ struct ppc_debug_info hwdebug_info;
+ Status error;
+
+ error = NativeProcessLinux::PtraceWrapper(
+ PPC_PTRACE_GETHWDBGINFO, tid, 0, &hwdebug_info, sizeof(hwdebug_info));
+
+ if (error.Fail())
+ return error;
+
+ m_max_hwp_supported = hwdebug_info.num_data_bps;
+ m_max_hbp_supported = hwdebug_info.num_instruction_bps;
+ m_refresh_hwdebug_info = false;
+
+ return error;
+}
+
+Status NativeRegisterContextLinux_ppc64le::WriteHardwareDebugRegs() {
+ struct ppc_hw_breakpoint reg_state;
+ Status error;
+ long ret;
+
+ for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
+ reg_state.addr = m_hwp_regs[i].address;
+ reg_state.trigger_type = m_hwp_regs[i].mode;
+ reg_state.version = 1;
+ reg_state.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
+ reg_state.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
+ reg_state.addr2 = 0;
+ reg_state.condition_value = 0;
+
+ error = NativeProcessLinux::PtraceWrapper(PPC_PTRACE_SETHWDEBUG,
+ m_thread.GetID(), 0, &reg_state,
+ sizeof(reg_state), &ret);
+
+ if (error.Fail())
+ return error;
+
+ m_hwp_regs[i].slot = ret;
+ }
+
+ return error;
+}
+
+#endif // defined(__powerpc64__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h
new file mode 100644
index 0000000000000..bb25af80d02cd
--- /dev/null
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h
@@ -0,0 +1,149 @@
+//===-- NativeRegisterContextLinux_ppc64le.h --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// This implementation is related to the OpenPOWER ABI for Power Architecture
+// 64-bit ELF V2 ABI
+
+#if defined(__powerpc64__)
+
+#ifndef lldb_NativeRegisterContextLinux_ppc64le_h
+#define lldb_NativeRegisterContextLinux_ppc64le_h
+
+#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
+#include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h"
+
+#define DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
+#include "RegisterInfos_ppc64le.h"
+#undef DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
+
+namespace lldb_private {
+namespace process_linux {
+
+class NativeProcessLinux;
+
+class NativeRegisterContextLinux_ppc64le : public NativeRegisterContextLinux {
+public:
+ NativeRegisterContextLinux_ppc64le(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread);
+
+ uint32_t GetRegisterSetCount() const override;
+
+ uint32_t GetUserRegisterCount() const override;
+
+ const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
+
+ Status ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
+
+ Status WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
+
+ Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ //------------------------------------------------------------------
+ // Hardware watchpoint mangement functions
+ //------------------------------------------------------------------
+
+ uint32_t NumSupportedHardwareWatchpoints() override;
+
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags) override;
+
+ bool ClearHardwareWatchpoint(uint32_t hw_index) override;
+
+ Status GetWatchpointHitIndex(uint32_t &wp_index,
+ lldb::addr_t trap_addr) override;
+
+ lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override;
+
+ lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
+
+ uint32_t GetWatchpointSize(uint32_t wp_index);
+
+ bool WatchpointIsEnabled(uint32_t wp_index);
+
+protected:
+ Status DoReadGPR(void *buf, size_t buf_size) override;
+
+ Status DoWriteGPR(void *buf, size_t buf_size) override;
+
+ Status DoReadFPR(void *buf, size_t buf_size) override;
+
+ Status DoWriteFPR(void *buf, size_t buf_size) override;
+
+ bool IsVMX(unsigned reg);
+
+ bool IsVSX(unsigned reg);
+
+ Status ReadVMX();
+
+ Status WriteVMX();
+
+ Status ReadVSX();
+
+ Status WriteVSX();
+
+ void *GetGPRBuffer() override { return &m_gpr_ppc64le; }
+
+ void *GetFPRBuffer() override { return &m_fpr_ppc64le; }
+
+ size_t GetFPRSize() override { return sizeof(m_fpr_ppc64le); }
+
+private:
+ GPR m_gpr_ppc64le; // 64-bit general purpose registers.
+ FPR m_fpr_ppc64le; // floating-point registers including extended register.
+ VMX m_vmx_ppc64le; // VMX registers.
+ VSX m_vsx_ppc64le; // Last lower bytes from first VSX registers.
+
+ bool IsGPR(unsigned reg) const;
+
+ bool IsFPR(unsigned reg) const;
+
+ bool IsVMX(unsigned reg) const;
+
+ bool IsVSX(unsigned reg) const;
+
+ uint32_t CalculateFprOffset(const RegisterInfo *reg_info) const;
+
+ uint32_t CalculateVmxOffset(const RegisterInfo *reg_info) const;
+
+ uint32_t CalculateVsxOffset(const RegisterInfo *reg_info) const;
+
+ Status ReadHardwareDebugInfo();
+
+ Status WriteHardwareDebugRegs();
+
+ // Debug register info for hardware watchpoints management.
+ struct DREG {
+ lldb::addr_t address; // Breakpoint/watchpoint address value.
+ lldb::addr_t hit_addr; // Address at which last watchpoint trigger
+ // exception occurred.
+ lldb::addr_t real_addr; // Address value that should cause target to stop.
+ uint32_t control; // Breakpoint/watchpoint control value.
+ uint32_t refcount; // Serves as enable/disable and reference counter.
+ long slot; // Saves the value returned from PTRACE_SETHWDEBUG.
+ int mode; // Defines if watchpoint is read/write/access.
+ };
+
+ std::array<DREG, 4> m_hwp_regs;
+
+ // 16 is just a maximum value, query hardware for actual watchpoint count
+ uint32_t m_max_hwp_supported = 16;
+ uint32_t m_max_hbp_supported = 16;
+ bool m_refresh_hwdebug_info = true;
+};
+
+} // namespace process_linux
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextLinux_ppc64le_h
+
+#endif // defined(__powerpc64__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
index c2a696e08bf94..021394ab154b5 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
@@ -97,12 +97,11 @@ static const RegisterSet g_reg_sets_s390x[k_num_register_sets] = {
#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */
#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */
-NativeRegisterContextLinux *
+std::unique_ptr<NativeRegisterContextLinux>
NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx) {
- return new NativeRegisterContextLinux_s390x(target_arch, native_thread,
- concrete_frame_idx);
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ return llvm::make_unique<NativeRegisterContextLinux_s390x>(target_arch,
+ native_thread);
}
// ----------------------------------------------------------------------------
@@ -117,9 +116,8 @@ CreateRegisterInfoInterface(const ArchSpec &target_arch) {
}
NativeRegisterContextLinux_s390x::NativeRegisterContextLinux_s390x(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx)
- : NativeRegisterContextLinux(native_thread, concrete_frame_idx,
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ : NativeRegisterContextLinux(native_thread,
CreateRegisterInfoInterface(target_arch)) {
// Set up data about ranges of valid registers.
switch (target_arch.GetMachine()) {
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h
index 3ffbaeeb0bba8..57b1a0481512f 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h
@@ -24,8 +24,7 @@ class NativeProcessLinux;
class NativeRegisterContextLinux_s390x : public NativeRegisterContextLinux {
public:
NativeRegisterContextLinux_s390x(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+ NativeThreadProtocol &native_thread);
uint32_t GetRegisterSetCount() const override;
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
index e44e03b46b5cc..84ffe9b6e4202 100755
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
@@ -243,12 +243,11 @@ static inline unsigned int fxsr_regset(const ArchSpec &arch) {
#define mask_XSTATE_BNDCFG (1ULL << 4)
#define mask_XSTATE_MPX (mask_XSTATE_BNDREGS | mask_XSTATE_BNDCFG)
-NativeRegisterContextLinux *
+std::unique_ptr<NativeRegisterContextLinux>
NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx) {
- return new NativeRegisterContextLinux_x86_64(target_arch, native_thread,
- concrete_frame_idx);
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ return std::unique_ptr<NativeRegisterContextLinux>(
+ new NativeRegisterContextLinux_x86_64(target_arch, native_thread));
}
// ----------------------------------------------------------------------------
@@ -270,9 +269,8 @@ CreateRegisterInfoInterface(const ArchSpec &target_arch) {
}
NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx)
- : NativeRegisterContextLinux(native_thread, concrete_frame_idx,
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ : NativeRegisterContextLinux(native_thread,
CreateRegisterInfoInterface(target_arch)),
m_xstate_type(XStateType::Invalid), m_fpr(), m_iovec(), m_ymm_set(),
m_mpx_set(), m_reg_info(), m_gpr_x86_64() {
@@ -334,11 +332,11 @@ NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64(
// 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.xstate.xsave;
- m_iovec.iov_len = sizeof(m_fpr.xstate.xsave);
+ m_iovec.iov_base = &m_fpr;
+ m_iovec.iov_len = sizeof(m_fpr);
// Clear out the FPR state.
- ::memset(&m_fpr, 0, sizeof(FPR));
+ ::memset(&m_fpr, 0, sizeof(m_fpr));
// Store byte offset of fctrl (i.e. first register of FPR)
const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl");
@@ -441,17 +439,14 @@ NativeRegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info,
if (byte_order != lldb::eByteOrderInvalid) {
if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
- reg_value.SetBytes(
- m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes,
- reg_info->byte_size, byte_order);
+ reg_value.SetBytes(m_fpr.fxsave.stmm[reg - m_reg_info.first_st].bytes,
+ reg_info->byte_size, byte_order);
if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
- reg_value.SetBytes(
- m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes,
- reg_info->byte_size, byte_order);
+ reg_value.SetBytes(m_fpr.fxsave.stmm[reg - m_reg_info.first_mm].bytes,
+ reg_info->byte_size, byte_order);
if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
- reg_value.SetBytes(
- m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
- reg_info->byte_size, byte_order);
+ 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
if (CopyXSTATEtoYMM(reg, byte_order))
@@ -492,7 +487,7 @@ NativeRegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info,
return error;
}
- // Get pointer to m_fpr.xstate.fxsave variable and set the data from it.
+ // 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(PTRACE_GETFPREGS,..)}
@@ -530,6 +525,22 @@ NativeRegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info,
return error;
}
+void NativeRegisterContextLinux_x86_64::UpdateXSTATEforWrite(
+ uint32_t reg_index) {
+ XSAVE_HDR::XFeature &xstate_bv = m_fpr.xsave.header.xstate_bv;
+ if (IsFPR(reg_index)) {
+ // IsFPR considers both %st and %xmm registers as floating point, but these
+ // map to two features. Set both flags, just in case.
+ xstate_bv |= XSAVE_HDR::XFeature::FP | XSAVE_HDR::XFeature::SSE;
+ } else if (IsAVX(reg_index)) {
+ // Lower bytes of some %ymm registers are shared with %xmm registers.
+ xstate_bv |= XSAVE_HDR::XFeature::YMM | XSAVE_HDR::XFeature::SSE;
+ } else if (IsMPX(reg_index)) {
+ // MPX registers map to two XSAVE features.
+ xstate_bv |= XSAVE_HDR::XFeature::BNDREGS | XSAVE_HDR::XFeature::BNDCSR;
+ }
+}
+
Status NativeRegisterContextLinux_x86_64::WriteRegister(
const RegisterInfo *reg_info, const RegisterValue &reg_value) {
assert(reg_info && "reg_info is null");
@@ -540,25 +551,24 @@ Status NativeRegisterContextLinux_x86_64::WriteRegister(
? reg_info->name
: "<unknown register>");
+ UpdateXSTATEforWrite(reg_index);
+
if (IsGPR(reg_index))
return WriteRegisterRaw(reg_index, reg_value);
if (IsFPR(reg_index) || IsAVX(reg_index) || IsMPX(reg_index)) {
if (reg_info->encoding == lldb::eEncodingVector) {
if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st)
- ::memcpy(
- m_fpr.xstate.fxsave.stmm[reg_index - m_reg_info.first_st].bytes,
- reg_value.GetBytes(), reg_value.GetByteSize());
+ ::memcpy(m_fpr.fxsave.stmm[reg_index - m_reg_info.first_st].bytes,
+ reg_value.GetBytes(), reg_value.GetByteSize());
if (reg_index >= m_reg_info.first_mm && reg_index <= m_reg_info.last_mm)
- ::memcpy(
- m_fpr.xstate.fxsave.stmm[reg_index - m_reg_info.first_mm].bytes,
- reg_value.GetBytes(), reg_value.GetByteSize());
+ ::memcpy(m_fpr.fxsave.stmm[reg_index - m_reg_info.first_mm].bytes,
+ reg_value.GetBytes(), reg_value.GetByteSize());
if (reg_index >= m_reg_info.first_xmm && reg_index <= m_reg_info.last_xmm)
- ::memcpy(
- m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes,
- reg_value.GetBytes(), reg_value.GetByteSize());
+ ::memcpy(m_fpr.fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes,
+ reg_value.GetBytes(), reg_value.GetByteSize());
if (reg_index >= m_reg_info.first_ymm &&
reg_index <= m_reg_info.last_ymm) {
@@ -586,7 +596,7 @@ Status NativeRegisterContextLinux_x86_64::WriteRegister(
return Status("CopyMPXtoXSTATE() failed");
}
} else {
- // Get pointer to m_fpr.xstate.fxsave variable and set the data to it.
+ // 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
@@ -658,7 +668,7 @@ Status NativeRegisterContextLinux_x86_64::ReadAllRegisterValues(
::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize());
dst += GetRegisterInfoInterface().GetGPRSize();
if (m_xstate_type == XStateType::FXSAVE)
- ::memcpy(dst, &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
+ ::memcpy(dst, &m_fpr.fxsave, sizeof(m_fpr.fxsave));
else if (m_xstate_type == XStateType::XSAVE) {
lldb::ByteOrder byte_order = GetByteOrder();
@@ -749,9 +759,9 @@ Status NativeRegisterContextLinux_x86_64::WriteAllRegisterValues(
src += GetRegisterInfoInterface().GetGPRSize();
if (m_xstate_type == XStateType::FXSAVE)
- ::memcpy(&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave));
+ ::memcpy(&m_fpr.fxsave, src, sizeof(m_fpr.fxsave));
else if (m_xstate_type == XStateType::XSAVE)
- ::memcpy(&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave));
+ ::memcpy(&m_fpr.xsave, src, sizeof(m_fpr.xsave));
error = WriteFPR();
if (error.Fail())
@@ -805,12 +815,12 @@ bool NativeRegisterContextLinux_x86_64::IsCPUFeatureAvailable(
return true;
case RegSet::avx: // Check if CPU has AVX and if there is kernel support, by
// reading in the XCR0 area of XSAVE.
- if ((m_fpr.xstate.xsave.i387.xcr0 & mask_XSTATE_AVX) == mask_XSTATE_AVX)
+ if ((m_fpr.xsave.i387.xcr0 & mask_XSTATE_AVX) == mask_XSTATE_AVX)
return true;
break;
case RegSet::mpx: // Check if CPU has MPX and if there is kernel support, by
// reading in the XCR0 area of XSAVE.
- if ((m_fpr.xstate.xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX)
+ if ((m_fpr.xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX)
return true;
break;
}
@@ -847,11 +857,10 @@ Status NativeRegisterContextLinux_x86_64::WriteFPR() {
switch (m_xstate_type) {
case XStateType::FXSAVE:
return WriteRegisterSet(
- &m_iovec, sizeof(m_fpr.xstate.xsave),
+ &m_iovec, sizeof(m_fpr.fxsave),
fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
case XStateType::XSAVE:
- return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave),
- NT_X86_XSTATE);
+ return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xsave), NT_X86_XSTATE);
default:
return Status("Unrecognized FPR type.");
}
@@ -871,11 +880,11 @@ bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM(
if (byte_order == lldb::eByteOrderLittle) {
::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
- m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
+ m_fpr.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
sizeof(XMMReg));
::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes +
sizeof(XMMReg),
- m_fpr.xstate.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
+ m_fpr.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
sizeof(YMMHReg));
return true;
}
@@ -883,10 +892,10 @@ bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM(
if (byte_order == lldb::eByteOrderBig) {
::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes +
sizeof(XMMReg),
- m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
+ m_fpr.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
sizeof(XMMReg));
::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
- m_fpr.xstate.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
+ m_fpr.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
sizeof(YMMHReg));
return true;
}
@@ -899,19 +908,19 @@ bool NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE(
return false;
if (byte_order == lldb::eByteOrderLittle) {
- ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ ::memcpy(m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(XMMReg));
- ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ ::memcpy(m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
sizeof(YMMHReg));
return true;
}
if (byte_order == lldb::eByteOrderBig) {
- ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ ::memcpy(m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
sizeof(XMMReg));
- ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ ::memcpy(m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(YMMHReg));
return true;
}
@@ -921,7 +930,7 @@ bool NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE(
void *NativeRegisterContextLinux_x86_64::GetFPRBuffer() {
switch (m_xstate_type) {
case XStateType::FXSAVE:
- return &m_fpr.xstate.fxsave;
+ return &m_fpr.fxsave;
case XStateType::XSAVE:
return &m_iovec;
default:
@@ -932,7 +941,7 @@ void *NativeRegisterContextLinux_x86_64::GetFPRBuffer() {
size_t NativeRegisterContextLinux_x86_64::GetFPRSize() {
switch (m_xstate_type) {
case XStateType::FXSAVE:
- return sizeof(m_fpr.xstate.fxsave);
+ return sizeof(m_fpr.fxsave);
case XStateType::XSAVE:
return sizeof(m_iovec);
default:
@@ -945,15 +954,14 @@ Status NativeRegisterContextLinux_x86_64::ReadFPR() {
// Probe XSAVE and if it is not supported fall back to FXSAVE.
if (m_xstate_type != XStateType::FXSAVE) {
- error =
- ReadRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
+ error = ReadRegisterSet(&m_iovec, sizeof(m_fpr.xsave), NT_X86_XSTATE);
if (!error.Fail()) {
m_xstate_type = XStateType::XSAVE;
return error;
}
}
error = ReadRegisterSet(
- &m_iovec, sizeof(m_fpr.xstate.xsave),
+ &m_iovec, sizeof(m_fpr.xsave),
fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
if (!error.Fail()) {
m_xstate_type = XStateType::FXSAVE;
@@ -975,11 +983,11 @@ bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoMPX(uint32_t reg) {
if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
::memcpy(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
- m_fpr.xstate.xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
+ m_fpr.xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
sizeof(MPXReg));
} else {
::memcpy(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
- m_fpr.xstate.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
+ m_fpr.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
sizeof(MPXCsr));
}
return true;
@@ -990,10 +998,10 @@ bool NativeRegisterContextLinux_x86_64::CopyMPXtoXSTATE(uint32_t reg) {
return false;
if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
- ::memcpy(m_fpr.xstate.xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
+ ::memcpy(m_fpr.xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, sizeof(MPXReg));
} else {
- ::memcpy(m_fpr.xstate.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
+ ::memcpy(m_fpr.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, sizeof(MPXCsr));
}
return true;
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
index abb0dba4d91ca..9dcf82f50a458 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
@@ -15,6 +15,7 @@
#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
#include "Plugins/Process/Utility/RegisterContext_x86.h"
#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
+#include <sys/uio.h>
namespace lldb_private {
namespace process_linux {
@@ -24,8 +25,7 @@ class NativeProcessLinux;
class NativeRegisterContextLinux_x86_64 : public NativeRegisterContextLinux {
public:
NativeRegisterContextLinux_x86_64(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+ NativeThreadProtocol &native_thread);
uint32_t GetRegisterSetCount() const override;
@@ -110,7 +110,7 @@ private:
// Private member variables.
mutable XStateType m_xstate_type;
FPR m_fpr; // Extended States Area, named FPR for historical reasons.
- IOVEC m_iovec;
+ struct iovec m_iovec;
YMM m_ymm_set;
MPX m_mpx_set;
RegInfo m_reg_info;
@@ -137,6 +137,8 @@ private:
bool CopyMPXtoXSTATE(uint32_t reg);
bool IsMPX(uint32_t reg_index) const;
+
+ void UpdateXSTATEforWrite(uint32_t reg_index);
};
} // namespace process_linux
diff --git a/source/Plugins/Process/Linux/NativeThreadLinux.cpp b/source/Plugins/Process/Linux/NativeThreadLinux.cpp
index 5cd40941dcf8e..0db3bd56b8e4c 100644
--- a/source/Plugins/Process/Linux/NativeThreadLinux.cpp
+++ b/source/Plugins/Process/Linux/NativeThreadLinux.cpp
@@ -88,7 +88,11 @@ void LogThreadStopInfo(Log &log, const ThreadStopInfo &stop_info,
NativeThreadLinux::NativeThreadLinux(NativeProcessLinux &process,
lldb::tid_t tid)
: NativeThreadProtocol(process, tid), m_state(StateType::eStateInvalid),
- m_stop_info(), m_reg_context_sp(), m_stop_description() {}
+ m_stop_info(),
+ m_reg_context_up(
+ NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
+ process.GetArchitecture(), *this)),
+ m_stop_description() {}
std::string NativeThreadLinux::GetName() {
NativeProcessLinux &process = GetProcess();
@@ -139,23 +143,6 @@ bool NativeThreadLinux::GetStopReason(ThreadStopInfo &stop_info,
llvm_unreachable("unhandled StateType!");
}
-NativeRegisterContextSP NativeThreadLinux::GetRegisterContext() {
- // Return the register context if we already created it.
- if (m_reg_context_sp)
- return m_reg_context_sp;
-
- ArchSpec target_arch;
- if (!m_process.GetArchitecture(target_arch))
- return NativeRegisterContextSP();
-
- const uint32_t concrete_frame_idx = 0;
- m_reg_context_sp.reset(
- NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- target_arch, *this, concrete_frame_idx));
-
- return m_reg_context_sp;
-}
-
Status NativeThreadLinux::SetWatchpoint(lldb::addr_t addr, size_t size,
uint32_t watch_flags, bool hardware) {
if (!hardware)
@@ -165,8 +152,8 @@ Status NativeThreadLinux::SetWatchpoint(lldb::addr_t addr, size_t size,
Status error = RemoveWatchpoint(addr);
if (error.Fail())
return error;
- NativeRegisterContextSP reg_ctx = GetRegisterContext();
- uint32_t wp_index = reg_ctx->SetHardwareWatchpoint(addr, size, watch_flags);
+ uint32_t wp_index =
+ m_reg_context_up->SetHardwareWatchpoint(addr, size, watch_flags);
if (wp_index == LLDB_INVALID_INDEX32)
return Status("Setting hardware watchpoint failed.");
m_watchpoint_index_map.insert({addr, wp_index});
@@ -179,7 +166,7 @@ Status NativeThreadLinux::RemoveWatchpoint(lldb::addr_t addr) {
return Status();
uint32_t wp_index = wp->second;
m_watchpoint_index_map.erase(wp);
- if (GetRegisterContext()->ClearHardwareWatchpoint(wp_index))
+ if (m_reg_context_up->ClearHardwareWatchpoint(wp_index))
return Status();
return Status("Clearing hardware watchpoint failed.");
}
@@ -193,8 +180,7 @@ Status NativeThreadLinux::SetHardwareBreakpoint(lldb::addr_t addr,
if (error.Fail())
return error;
- NativeRegisterContextSP reg_ctx = GetRegisterContext();
- uint32_t bp_index = reg_ctx->SetHardwareBreakpoint(addr, size);
+ uint32_t bp_index = m_reg_context_up->SetHardwareBreakpoint(addr, size);
if (bp_index == LLDB_INVALID_INDEX32)
return Status("Setting hardware breakpoint failed.");
@@ -209,7 +195,7 @@ Status NativeThreadLinux::RemoveHardwareBreakpoint(lldb::addr_t addr) {
return Status();
uint32_t bp_index = bp->second;
- if (GetRegisterContext()->ClearHardwareBreakpoint(bp_index)) {
+ if (m_reg_context_up->ClearHardwareBreakpoint(bp_index)) {
m_hw_break_index_map.erase(bp);
return Status();
}
@@ -231,7 +217,7 @@ Status NativeThreadLinux::Resume(uint32_t signo) {
NativeProcessLinux &process = GetProcess();
const auto &watchpoint_map = process.GetWatchpointMap();
- GetRegisterContext()->ClearAllHardwareWatchpoints();
+ m_reg_context_up->ClearAllHardwareWatchpoints();
for (const auto &pair : watchpoint_map) {
const auto &wp = pair.second;
SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags, wp.m_hardware);
@@ -243,7 +229,7 @@ Status NativeThreadLinux::Resume(uint32_t signo) {
NativeProcessLinux &process = GetProcess();
const auto &hw_breakpoint_map = process.GetHardwareBreakpointMap();
- GetRegisterContext()->ClearAllHardwareBreakpoints();
+ m_reg_context_up->ClearAllHardwareBreakpoints();
for (const auto &pair : hw_breakpoint_map) {
const auto &bp = pair.second;
SetHardwareBreakpoint(bp.m_addr, bp.m_size);
@@ -365,7 +351,7 @@ void NativeThreadLinux::SetStoppedByWatchpoint(uint32_t wp_index) {
lldbassert(wp_index != LLDB_INVALID_INDEX32 && "wp_index cannot be invalid");
std::ostringstream ostr;
- ostr << GetRegisterContext()->GetWatchpointAddress(wp_index) << " ";
+ ostr << m_reg_context_up->GetWatchpointAddress(wp_index) << " ";
ostr << wp_index;
/*
@@ -379,7 +365,7 @@ void NativeThreadLinux::SetStoppedByWatchpoint(uint32_t wp_index) {
* stop-info
* packet.
*/
- ostr << " " << GetRegisterContext()->GetWatchpointHitAddress(wp_index);
+ ostr << " " << m_reg_context_up->GetWatchpointHitAddress(wp_index);
m_stop_description = ostr.str();
diff --git a/source/Plugins/Process/Linux/NativeThreadLinux.h b/source/Plugins/Process/Linux/NativeThreadLinux.h
index 6ae87feffcda8..a7c4e982012d2 100644
--- a/source/Plugins/Process/Linux/NativeThreadLinux.h
+++ b/source/Plugins/Process/Linux/NativeThreadLinux.h
@@ -10,7 +10,8 @@
#ifndef liblldb_NativeThreadLinux_H_
#define liblldb_NativeThreadLinux_H_
-#include "SingleStepCheck.h"
+#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
+#include "Plugins/Process/Linux/SingleStepCheck.h"
#include "lldb/Host/common/NativeThreadProtocol.h"
#include "lldb/lldb-private-forward.h"
@@ -40,7 +41,9 @@ public:
bool GetStopReason(ThreadStopInfo &stop_info,
std::string &description) override;
- NativeRegisterContextSP GetRegisterContext() override;
+ NativeRegisterContextLinux &GetRegisterContext() override {
+ return *m_reg_context_up;
+ }
Status SetWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags,
bool hardware) override;
@@ -103,15 +106,13 @@ private:
// ---------------------------------------------------------------------
lldb::StateType m_state;
ThreadStopInfo m_stop_info;
- NativeRegisterContextSP m_reg_context_sp;
+ std::unique_ptr<NativeRegisterContextLinux> m_reg_context_up;
std::string m_stop_description;
using WatchpointIndexMap = std::map<lldb::addr_t, uint32_t>;
WatchpointIndexMap m_watchpoint_index_map;
WatchpointIndexMap m_hw_break_index_map;
std::unique_ptr<SingleStepWorkaround> m_step_workaround;
};
-
-typedef std::shared_ptr<NativeThreadLinux> NativeThreadLinuxSP;
} // namespace process_linux
} // namespace lldb_private
diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
index 52b9441e0e792..b4eae58af83cc 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
+++ b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
@@ -17,12 +17,12 @@
#include <vector>
// Other libraries and framework includes
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/ThreadSafeValue.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
diff --git a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
index ae2f11f380061..1902cc492ff4f 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
@@ -12,13 +12,13 @@
#include "lldb/Utility/SafeMachO.h"
#include "lldb/Breakpoint/Watchpoint.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/State.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Unwind.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/StreamString.h"
diff --git a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
index 388989a21f767..387f04afa5b46 100644
--- a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
+++ b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
@@ -109,10 +109,8 @@ NativeProcessNetBSD::Factory::Launch(ProcessLaunchInfo &launch_info,
if (status.Fail())
return status.ToError();
- for (const auto &thread_sp : process_up->m_threads) {
- static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal(
- SIGSTOP);
- }
+ for (const auto &thread : process_up->m_threads)
+ static_cast<NativeThreadNetBSD &>(*thread).SetStoppedBySignal(SIGSTOP);
process_up->SetState(StateType::eStateStopped);
return std::move(process_up);
@@ -198,9 +196,9 @@ void NativeProcessNetBSD::MonitorSIGSTOP(lldb::pid_t pid) {
// Handle SIGSTOP from LLGS (LLDB GDB Server)
if (info.psi_siginfo.si_code == SI_USER &&
info.psi_siginfo.si_pid == ::getpid()) {
- /* Stop Tracking All Threads attached to Process */
- for (const auto &thread_sp : m_threads) {
- static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal(
+ /* Stop Tracking all Threads attached to Process */
+ for (const auto &thread : m_threads) {
+ static_cast<NativeThreadNetBSD &>(*thread).SetStoppedBySignal(
SIGSTOP, &info.psi_siginfo);
}
}
@@ -221,18 +219,15 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
switch (info.psi_siginfo.si_code) {
case TRAP_BRKPT:
- for (const auto &thread_sp : m_threads) {
- static_pointer_cast<NativeThreadNetBSD>(thread_sp)
- ->SetStoppedByBreakpoint();
- FixupBreakpointPCAsNeeded(
- *static_pointer_cast<NativeThreadNetBSD>(thread_sp));
+ for (const auto &thread : m_threads) {
+ static_cast<NativeThreadNetBSD &>(*thread).SetStoppedByBreakpoint();
+ FixupBreakpointPCAsNeeded(static_cast<NativeThreadNetBSD &>(*thread));
}
SetState(StateType::eStateStopped, true);
break;
case TRAP_TRACE:
- for (const auto &thread_sp : m_threads) {
- static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedByTrace();
- }
+ for (const auto &thread : m_threads)
+ static_cast<NativeThreadNetBSD &>(*thread).SetStoppedByTrace();
SetState(StateType::eStateStopped, true);
break;
case TRAP_EXEC: {
@@ -245,38 +240,35 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
// Let our delegate know we have just exec'd.
NotifyDidExec();
- for (const auto &thread_sp : m_threads) {
- static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedByExec();
- }
+ for (const auto &thread : m_threads)
+ static_cast<NativeThreadNetBSD &>(*thread).SetStoppedByExec();
SetState(StateType::eStateStopped, true);
} break;
case TRAP_DBREG: {
// If a watchpoint was hit, report it
uint32_t wp_index;
- Status error =
- static_pointer_cast<NativeThreadNetBSD>(m_threads[info.psi_lwpid])
- ->GetRegisterContext()
- ->GetWatchpointHitIndex(wp_index,
- (uintptr_t)info.psi_siginfo.si_addr);
+ Status error = static_cast<NativeThreadNetBSD &>(*m_threads[info.psi_lwpid])
+ .GetRegisterContext()
+ .GetWatchpointHitIndex(
+ wp_index, (uintptr_t)info.psi_siginfo.si_addr);
if (error.Fail())
LLDB_LOG(log,
"received error while checking for watchpoint hits, pid = "
"{0}, LWP = {1}, error = {2}",
GetID(), info.psi_lwpid, error);
if (wp_index != LLDB_INVALID_INDEX32) {
- for (const auto &thread_sp : m_threads) {
- static_pointer_cast<NativeThreadNetBSD>(thread_sp)
- ->SetStoppedByWatchpoint(wp_index);
- }
+ for (const auto &thread : m_threads)
+ static_cast<NativeThreadNetBSD &>(*thread).SetStoppedByWatchpoint(
+ wp_index);
SetState(StateType::eStateStopped, true);
break;
}
// If a breakpoint was hit, report it
uint32_t bp_index;
- error = static_pointer_cast<NativeThreadNetBSD>(m_threads[info.psi_lwpid])
- ->GetRegisterContext()
- ->GetHardwareBreakHitIndex(bp_index,
+ error = static_cast<NativeThreadNetBSD &>(*m_threads[info.psi_lwpid])
+ .GetRegisterContext()
+ .GetHardwareBreakHitIndex(bp_index,
(uintptr_t)info.psi_siginfo.si_addr);
if (error.Fail())
LLDB_LOG(log,
@@ -284,10 +276,8 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
"breakpoint hits, pid = {0}, LWP = {1}, error = {2}",
GetID(), info.psi_lwpid, error);
if (bp_index != LLDB_INVALID_INDEX32) {
- for (const auto &thread_sp : m_threads) {
- static_pointer_cast<NativeThreadNetBSD>(thread_sp)
- ->SetStoppedByBreakpoint();
- }
+ for (const auto &thread : m_threads)
+ static_cast<NativeThreadNetBSD &>(*thread).SetStoppedByBreakpoint();
SetState(StateType::eStateStopped, true);
break;
}
@@ -300,8 +290,8 @@ void NativeProcessNetBSD::MonitorSignal(lldb::pid_t pid, int signal) {
const auto siginfo_err =
PtraceWrapper(PT_GET_SIGINFO, pid, &info, sizeof(info));
- for (const auto &thread_sp : m_threads) {
- static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal(
+ for (const auto &thread : m_threads) {
+ static_cast<NativeThreadNetBSD &>(*thread).SetStoppedBySignal(
info.psi_siginfo.si_signo, &info.psi_siginfo);
}
SetState(StateType::eStateStopped, true);
@@ -351,12 +341,7 @@ NativeProcessNetBSD::FixupBreakpointPCAsNeeded(NativeThreadNetBSD &thread) {
Status error;
// Find out the size of a breakpoint (might depend on where we are in the
// code).
- NativeRegisterContextSP context_sp = thread.GetRegisterContext();
- if (!context_sp) {
- error.SetErrorString("cannot get a NativeRegisterContext for the thread");
- LLDB_LOG(log, "failed: {0}", error);
- return error;
- }
+ NativeRegisterContext& context = thread.GetRegisterContext();
uint32_t breakpoint_size = 0;
error = GetSoftwareBreakpointPCOffset(breakpoint_size);
if (error.Fail()) {
@@ -367,7 +352,7 @@ NativeProcessNetBSD::FixupBreakpointPCAsNeeded(NativeThreadNetBSD &thread) {
// First try probing for a breakpoint at a software breakpoint location: PC
// - breakpoint size.
const lldb::addr_t initial_pc_addr =
- context_sp->GetPCfromBreakpointLocation();
+ context.GetPCfromBreakpointLocation();
lldb::addr_t breakpoint_addr = initial_pc_addr;
if (breakpoint_size > 0) {
// Do not allow breakpoint probe to wrap around.
@@ -420,7 +405,7 @@ NativeProcessNetBSD::FixupBreakpointPCAsNeeded(NativeThreadNetBSD &thread) {
// Change the program counter.
LLDB_LOG(log, "pid {0} tid {1}: changing PC from {2:x} to {3:x}", GetID(),
thread.GetID(), initial_pc_addr, breakpoint_addr);
- error = context_sp->SetPC(breakpoint_addr);
+ error = context.SetPC(breakpoint_addr);
if (error.Fail()) {
LLDB_LOG(log, "pid {0} tid {1}: failed to set PC: {2}", GetID(),
thread.GetID(), error);
@@ -433,13 +418,13 @@ Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
LLDB_LOG(log, "pid {0}", GetID());
- const auto &thread_sp = m_threads[0];
+ const auto &thread = m_threads[0];
const ResumeAction *const action =
- resume_actions.GetActionForThread(thread_sp->GetID(), true);
+ resume_actions.GetActionForThread(thread->GetID(), true);
if (action == nullptr) {
LLDB_LOG(log, "no action specified for pid {0} tid {1}", GetID(),
- thread_sp->GetID());
+ thread->GetID());
return Status();
}
@@ -452,9 +437,8 @@ Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) {
action->signal);
if (!error.Success())
return error;
- for (const auto &thread_sp : m_threads) {
- static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetRunning();
- }
+ for (const auto &thread : m_threads)
+ static_cast<NativeThreadNetBSD &>(*thread).SetRunning();
SetState(eStateRunning, true);
break;
}
@@ -464,9 +448,8 @@ Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) {
action->signal);
if (!error.Success())
return error;
- for (const auto &thread_sp : m_threads) {
- static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStepping();
- }
+ for (const auto &thread : m_threads)
+ static_cast<NativeThreadNetBSD &>(*thread).SetStepping();
SetState(eStateStepping, true);
break;
@@ -478,7 +461,7 @@ Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) {
return Status("NativeProcessNetBSD::%s (): unexpected state %s specified "
"for pid %" PRIu64 ", tid %" PRIu64,
__FUNCTION__, StateAsCString(action->state), GetID(),
- thread_sp->GetID());
+ thread->GetID());
}
return Status();
@@ -690,11 +673,6 @@ lldb::addr_t NativeProcessNetBSD::GetSharedLibraryInfoAddress() {
size_t NativeProcessNetBSD::UpdateThreads() { return m_threads.size(); }
-bool NativeProcessNetBSD::GetArchitecture(ArchSpec &arch) const {
- arch = m_arch;
- return true;
-}
-
Status NativeProcessNetBSD::SetBreakpoint(lldb::addr_t addr, uint32_t size,
bool hardware) {
if (hardware)
@@ -764,9 +742,9 @@ void NativeProcessNetBSD::SigchldHandler() {
}
bool NativeProcessNetBSD::HasThreadNoLock(lldb::tid_t thread_id) {
- for (auto thread_sp : m_threads) {
- assert(thread_sp && "thread list should not contain NULL threads");
- if (thread_sp->GetID() == thread_id) {
+ for (const auto &thread : m_threads) {
+ assert(thread && "thread list should not contain NULL threads");
+ if (thread->GetID() == thread_id) {
// We have this thread.
return true;
}
@@ -776,7 +754,7 @@ bool NativeProcessNetBSD::HasThreadNoLock(lldb::tid_t thread_id) {
return false;
}
-NativeThreadNetBSDSP NativeProcessNetBSD::AddThread(lldb::tid_t thread_id) {
+NativeThreadNetBSD &NativeProcessNetBSD::AddThread(lldb::tid_t thread_id) {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
LLDB_LOG(log, "pid {0} adding thread with tid {1}", GetID(), thread_id);
@@ -788,9 +766,8 @@ NativeThreadNetBSDSP NativeProcessNetBSD::AddThread(lldb::tid_t thread_id) {
if (m_threads.empty())
SetCurrentThreadID(thread_id);
- auto thread_sp = std::make_shared<NativeThreadNetBSD>(*this, thread_id);
- m_threads.push_back(thread_sp);
- return thread_sp;
+ m_threads.push_back(llvm::make_unique<NativeThreadNetBSD>(*this, thread_id));
+ return static_cast<NativeThreadNetBSD &>(*m_threads.back());
}
Status NativeProcessNetBSD::Attach() {
@@ -811,10 +788,8 @@ Status NativeProcessNetBSD::Attach() {
if (status.Fail())
return status;
- for (const auto &thread_sp : m_threads) {
- static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal(
- SIGSTOP);
- }
+ for (const auto &thread : m_threads)
+ static_cast<NativeThreadNetBSD &>(*thread).SetStoppedBySignal(SIGSTOP);
// Let our process instance know the thread has stopped.
SetState(StateType::eStateStopped);
@@ -928,7 +903,7 @@ Status NativeProcessNetBSD::ReinitializeThreads() {
}
// Reinitialize from scratch threads and register them in process
while (info.pl_lwpid != 0) {
- NativeThreadNetBSDSP thread_sp = AddThread(info.pl_lwpid);
+ AddThread(info.pl_lwpid);
error = PtraceWrapper(PT_LWPINFO, GetID(), &info, sizeof(info));
if (error.Fail()) {
return error;
diff --git a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
index 2cbd5e30ab23b..7090fce34fc9c 100644
--- a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
+++ b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
@@ -10,12 +10,8 @@
#ifndef liblldb_NativeProcessNetBSD_H_
#define liblldb_NativeProcessNetBSD_H_
-// C++ Includes
-
-// Other libraries and framework includes
-
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/FileSpec.h"
#include "NativeThreadNetBSD.h"
@@ -77,7 +73,7 @@ public:
size_t UpdateThreads() override;
- bool GetArchitecture(ArchSpec &arch) const override;
+ const ArchSpec &GetArchitecture() const override { return m_arch; }
Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
bool hardware) override;
@@ -121,7 +117,7 @@ private:
bool HasThreadNoLock(lldb::tid_t thread_id);
- NativeThreadNetBSDSP AddThread(lldb::tid_t thread_id);
+ NativeThreadNetBSD &AddThread(lldb::tid_t thread_id);
void MonitorCallback(lldb::pid_t pid, int signal);
void MonitorExited(lldb::pid_t pid, WaitStatus status);
diff --git a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp
index dde86880c41a1..d4fef6342439d 100644
--- a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp
+++ b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp
@@ -20,9 +20,9 @@ using namespace lldb_private::process_netbsd;
// clang-format on
NativeRegisterContextNetBSD::NativeRegisterContextNetBSD(
- NativeThreadProtocol &native_thread, uint32_t concrete_frame_idx,
+ NativeThreadProtocol &native_thread,
RegisterInfoInterface *reg_info_interface_p)
- : NativeRegisterContextRegisterInfo(native_thread, concrete_frame_idx,
+ : NativeRegisterContextRegisterInfo(native_thread,
reg_info_interface_p) {}
Status NativeRegisterContextNetBSD::ReadGPR() {
diff --git a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h
index d96b7aea00486..b81430e7f5acf 100644
--- a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h
+++ b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h
@@ -21,7 +21,6 @@ namespace process_netbsd {
class NativeRegisterContextNetBSD : public NativeRegisterContextRegisterInfo {
public:
NativeRegisterContextNetBSD(NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx,
RegisterInfoInterface *reg_info_interface_p);
// This function is implemented in the NativeRegisterContextNetBSD_*
@@ -31,8 +30,7 @@ public:
// executable.
static NativeRegisterContextNetBSD *
CreateHostNativeRegisterContextNetBSD(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+ NativeThreadProtocol &native_thread);
protected:
virtual Status ReadGPR();
diff --git a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
index 9690da0e1374f..347c15ae5b239 100644
--- a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
+++ b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
@@ -149,10 +149,8 @@ const int fpu_save = []() -> int {
NativeRegisterContextNetBSD *
NativeRegisterContextNetBSD::CreateHostNativeRegisterContextNetBSD(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx) {
- return new NativeRegisterContextNetBSD_x86_64(target_arch, native_thread,
- concrete_frame_idx);
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ return new NativeRegisterContextNetBSD_x86_64(target_arch, native_thread);
}
// ----------------------------------------------------------------------------
@@ -169,9 +167,8 @@ CreateRegisterInfoInterface(const ArchSpec &target_arch) {
}
NativeRegisterContextNetBSD_x86_64::NativeRegisterContextNetBSD_x86_64(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx)
- : NativeRegisterContextNetBSD(native_thread, concrete_frame_idx,
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ : NativeRegisterContextNetBSD(native_thread,
CreateRegisterInfoInterface(target_arch)),
m_gpr_x86_64(), m_fpr_x86_64(), m_dbr_x86_64() {}
diff --git a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
index 5f5a6a0792e4d..c55ddfec66156 100644
--- a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
+++ b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
@@ -30,8 +30,7 @@ class NativeProcessNetBSD;
class NativeRegisterContextNetBSD_x86_64 : public NativeRegisterContextNetBSD {
public:
NativeRegisterContextNetBSD_x86_64(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+ NativeThreadProtocol &native_thread);
uint32_t GetRegisterSetCount() const override;
const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
diff --git a/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp b/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
index 1fd7400bf800c..83f1da78d01d0 100644
--- a/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
+++ b/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
@@ -27,7 +27,9 @@ using namespace lldb_private::process_netbsd;
NativeThreadNetBSD::NativeThreadNetBSD(NativeProcessNetBSD &process,
lldb::tid_t tid)
: NativeThreadProtocol(process, tid), m_state(StateType::eStateInvalid),
- m_stop_info(), m_reg_context_sp(), m_stop_description() {}
+ m_stop_info(), m_reg_context_up(
+NativeRegisterContextNetBSD::CreateHostNativeRegisterContextNetBSD(process.GetArchitecture(), *this)
+), m_stop_description() {}
void NativeThreadNetBSD::SetStoppedBySignal(uint32_t signo,
const siginfo_t *info) {
@@ -77,10 +79,10 @@ void NativeThreadNetBSD::SetStoppedByWatchpoint(uint32_t wp_index) {
lldbassert(wp_index != LLDB_INVALID_INDEX32 && "wp_index cannot be invalid");
std::ostringstream ostr;
- ostr << GetRegisterContext()->GetWatchpointAddress(wp_index) << " ";
+ ostr << GetRegisterContext().GetWatchpointAddress(wp_index) << " ";
ostr << wp_index;
- ostr << " " << GetRegisterContext()->GetWatchpointHitAddress(wp_index);
+ ostr << " " << GetRegisterContext().GetWatchpointHitAddress(wp_index);
m_stop_description = ostr.str();
@@ -139,21 +141,9 @@ bool NativeThreadNetBSD::GetStopReason(ThreadStopInfo &stop_info,
llvm_unreachable("unhandled StateType!");
}
-NativeRegisterContextSP NativeThreadNetBSD::GetRegisterContext() {
- // Return the register context if we already created it.
- if (m_reg_context_sp)
- return m_reg_context_sp;
-
- ArchSpec target_arch;
- if (!m_process.GetArchitecture(target_arch))
- return NativeRegisterContextSP();
-
- const uint32_t concrete_frame_idx = 0;
- m_reg_context_sp.reset(
- NativeRegisterContextNetBSD::CreateHostNativeRegisterContextNetBSD(
- target_arch, *this, concrete_frame_idx));
-
- return m_reg_context_sp;
+NativeRegisterContext& NativeThreadNetBSD::GetRegisterContext() {
+ assert(m_reg_context_up);
+return *m_reg_context_up;
}
Status NativeThreadNetBSD::SetWatchpoint(lldb::addr_t addr, size_t size,
@@ -165,8 +155,7 @@ Status NativeThreadNetBSD::SetWatchpoint(lldb::addr_t addr, size_t size,
Status error = RemoveWatchpoint(addr);
if (error.Fail())
return error;
- NativeRegisterContextSP reg_ctx = GetRegisterContext();
- uint32_t wp_index = reg_ctx->SetHardwareWatchpoint(addr, size, watch_flags);
+ uint32_t wp_index = GetRegisterContext().SetHardwareWatchpoint(addr, size, watch_flags);
if (wp_index == LLDB_INVALID_INDEX32)
return Status("Setting hardware watchpoint failed.");
m_watchpoint_index_map.insert({addr, wp_index});
@@ -179,7 +168,7 @@ Status NativeThreadNetBSD::RemoveWatchpoint(lldb::addr_t addr) {
return Status();
uint32_t wp_index = wp->second;
m_watchpoint_index_map.erase(wp);
- if (GetRegisterContext()->ClearHardwareWatchpoint(wp_index))
+ if (GetRegisterContext().ClearHardwareWatchpoint(wp_index))
return Status();
return Status("Clearing hardware watchpoint failed.");
}
@@ -193,8 +182,7 @@ Status NativeThreadNetBSD::SetHardwareBreakpoint(lldb::addr_t addr,
if (error.Fail())
return error;
- NativeRegisterContextSP reg_ctx = GetRegisterContext();
- uint32_t bp_index = reg_ctx->SetHardwareBreakpoint(addr, size);
+ uint32_t bp_index = GetRegisterContext().SetHardwareBreakpoint(addr, size);
if (bp_index == LLDB_INVALID_INDEX32)
return Status("Setting hardware breakpoint failed.");
@@ -209,7 +197,7 @@ Status NativeThreadNetBSD::RemoveHardwareBreakpoint(lldb::addr_t addr) {
return Status();
uint32_t bp_index = bp->second;
- if (GetRegisterContext()->ClearHardwareBreakpoint(bp_index)) {
+ if (GetRegisterContext().ClearHardwareBreakpoint(bp_index)) {
m_hw_break_index_map.erase(bp);
return Status();
}
diff --git a/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h b/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
index 1e3f587be5f5b..72426244c1127 100644
--- a/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
+++ b/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
@@ -37,7 +37,7 @@ public:
bool GetStopReason(ThreadStopInfo &stop_info,
std::string &description) override;
- NativeRegisterContextSP GetRegisterContext() override;
+ NativeRegisterContext& GetRegisterContext() override;
Status SetWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags,
bool hardware) override;
@@ -67,7 +67,7 @@ private:
// ---------------------------------------------------------------------
lldb::StateType m_state;
ThreadStopInfo m_stop_info;
- NativeRegisterContextSP m_reg_context_sp;
+ std::unique_ptr<NativeRegisterContext> m_reg_context_up;
std::string m_stop_description;
using WatchpointIndexMap = std::map<lldb::addr_t, uint32_t>;
WatchpointIndexMap m_watchpoint_index_map;
diff --git a/source/Plugins/Process/Utility/CMakeLists.txt b/source/Plugins/Process/Utility/CMakeLists.txt
index bda0ad626f6f8..3780fb5e4c18d 100644
--- a/source/Plugins/Process/Utility/CMakeLists.txt
+++ b/source/Plugins/Process/Utility/CMakeLists.txt
@@ -39,11 +39,13 @@ add_lldb_library(lldbPluginProcessUtility PLUGIN
RegisterContextPOSIX_arm64.cpp
RegisterContextPOSIX_mips64.cpp
RegisterContextPOSIX_powerpc.cpp
+ RegisterContextPOSIX_ppc64le.cpp
RegisterContextPOSIX_s390x.cpp
RegisterContextPOSIX_x86.cpp
RegisterContextThreadMemory.cpp
RegisterInfoPOSIX_arm.cpp
RegisterInfoPOSIX_arm64.cpp
+ RegisterInfoPOSIX_ppc64le.cpp
StopInfoMachException.cpp
ThreadMemory.cpp
UnwindLLDB.cpp
diff --git a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
index 1a4511a822309..61e5bf4481d6a 100644
--- a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
+++ b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
@@ -9,14 +9,10 @@
#include "DynamicRegisterInfo.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Host/StringConvert.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/StringExtractor.h"
#include "lldb/Utility/StructuredData.h"
diff --git a/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
index 4e1f10c6ae181..5c51a035ec665 100644
--- a/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
+++ b/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
@@ -64,7 +64,7 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
options.SetTimeout(std::chrono::milliseconds(500));
options.SetTrapExceptions(false);
- addr_t prot_arg, flags_arg = 0;
+ addr_t prot_arg;
if (prot == eMmapProtNone)
prot_arg = PROT_NONE;
else {
@@ -77,11 +77,6 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
prot_arg |= PROT_WRITE;
}
- const ArchSpec arch = process->GetTarget().GetArchitecture();
- flags_arg =
- process->GetTarget().GetPlatform()->ConvertMmapFlagsToPlatform(arch,
- flags);
-
AddressRange mmap_range;
if (sc.GetAddressRange(range_scope, 0, use_inline_block_range,
mmap_range)) {
@@ -89,7 +84,10 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
process->GetTarget().GetScratchClangASTContext();
CompilerType clang_void_ptr_type =
clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- lldb::addr_t args[] = {addr, length, prot_arg, flags_arg, fd, offset};
+ const ArchSpec arch = process->GetTarget().GetArchitecture();
+ MmapArgList args =
+ process->GetTarget().GetPlatform()->GetMmapArgumentList(
+ arch, addr, length, prot_arg, flags, fd, offset);
lldb::ThreadPlanSP call_plan_sp(
new ThreadPlanCallFunction(*thread, mmap_range.GetBaseAddress(),
clang_void_ptr_type, args, options));
diff --git a/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp b/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp
index 0b18143624255..3a9d497711c0f 100644
--- a/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp
+++ b/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp
@@ -14,9 +14,9 @@
using namespace lldb_private;
NativeRegisterContextRegisterInfo::NativeRegisterContextRegisterInfo(
- NativeThreadProtocol &thread, uint32_t concrete_frame_idx,
+ NativeThreadProtocol &thread,
RegisterInfoInterface *register_info_interface)
- : NativeRegisterContext(thread, concrete_frame_idx),
+ : NativeRegisterContext(thread),
m_register_info_interface_up(register_info_interface) {
assert(register_info_interface && "null register_info_interface");
}
diff --git a/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h b/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h
index c1b597462b60a..8f2e4409105fa 100644
--- a/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h
+++ b/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h
@@ -23,7 +23,7 @@ public:
/// of the register_info_interface pointer.
///
NativeRegisterContextRegisterInfo(
- NativeThreadProtocol &thread, uint32_t concrete_frame_idx,
+ NativeThreadProtocol &thread,
RegisterInfoInterface *register_info_interface);
uint32_t GetRegisterCount() const override;
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
index 0c36f1a8346cd..344c08965fad5 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
@@ -426,7 +426,7 @@ bool RegisterContextDarwin_arm64::ReadRegister(const RegisterInfo *reg_info,
case fpu_v29:
case fpu_v30:
case fpu_v31:
- value.SetBytes(fpu.v[reg].bytes, reg_info->byte_size,
+ value.SetBytes(fpu.v[reg].bytes.buffer, reg_info->byte_size,
endian::InlHostByteOrder());
break;
@@ -618,7 +618,7 @@ bool RegisterContextDarwin_arm64::WriteRegister(const RegisterInfo *reg_info,
case fpu_v29:
case fpu_v30:
case fpu_v31:
- ::memcpy(fpu.v[reg].bytes, value.GetBytes(), value.GetByteSize());
+ ::memcpy(fpu.v[reg].bytes.buffer, value.GetBytes(), value.GetByteSize());
break;
case fpu_fpsr:
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
index 2d1fe0555b58f..4a0e50947ee70 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
@@ -78,7 +78,7 @@ public:
};
struct VReg {
- uint8_t bytes[16];
+ llvm::AlignedCharArray<16, 16> bytes;
};
// mirrors <mach/arm/thread_status.h> arm_neon_state64_t
diff --git a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index bd73a29e08713..5435a02433aba 100644
--- a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -1517,8 +1517,8 @@ RegisterContextLLDB::SavedLocationForRegister(
dwarfexpr.SetRegisterKind(unwindplan_registerkind);
Value result;
Status error;
- if (dwarfexpr.Evaluate(&exe_ctx, nullptr, nullptr, this, 0, nullptr,
- nullptr, result, &error)) {
+ if (dwarfexpr.Evaluate(&exe_ctx, this, 0, nullptr, nullptr, result,
+ &error)) {
addr_t val;
val = result.GetScalar().ULongLong();
if (unwindplan_regloc.IsDWARFExpression()) {
@@ -1827,8 +1827,8 @@ bool RegisterContextLLDB::ReadCFAValueForRow(
dwarfexpr.SetRegisterKind(row_register_kind);
Value result;
Status error;
- if (dwarfexpr.Evaluate(&exe_ctx, nullptr, nullptr, this, 0, nullptr,
- nullptr, result, &error)) {
+ if (dwarfexpr.Evaluate(&exe_ctx, this, 0, nullptr, nullptr, result,
+ &error)) {
cfa_value = result.GetScalar().ULongLong();
UnwindLogMsg("CFA value set by DWARF expression is 0x%" PRIx64,
diff --git a/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp b/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp
index a4cf077101946..71d35bbd3938e 100644
--- a/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp
@@ -50,22 +50,30 @@ int RegisterContextMach_arm::DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) {
int RegisterContextMach_arm::DoWriteGPR(lldb::tid_t tid, int flavor,
const GPR &gpr) {
- return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount);
+ return ::thread_set_state(
+ tid, flavor, reinterpret_cast<thread_state_t>(const_cast<GPR *>(&gpr)),
+ GPRWordCount);
}
int RegisterContextMach_arm::DoWriteFPU(lldb::tid_t tid, int flavor,
const FPU &fpu) {
- return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount);
+ return ::thread_set_state(
+ tid, flavor, reinterpret_cast<thread_state_t>(const_cast<FPU *>(&fpu)),
+ FPUWordCount);
}
int RegisterContextMach_arm::DoWriteEXC(lldb::tid_t tid, int flavor,
const EXC &exc) {
- return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount);
+ return ::thread_set_state(
+ tid, flavor, reinterpret_cast<thread_state_t>(const_cast<EXC *>(&exc)),
+ EXCWordCount);
}
int RegisterContextMach_arm::DoWriteDBG(lldb::tid_t tid, int flavor,
const DBG &dbg) {
- return ::thread_set_state(tid, flavor, (thread_state_t)&dbg, DBGWordCount);
+ return ::thread_set_state(
+ tid, flavor, reinterpret_cast<thread_state_t>(const_cast<DBG *>(&dbg)),
+ DBGWordCount);
}
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp b/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp
index 959149edbc3e0..5a260d5de1d55 100644
--- a/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp
@@ -43,17 +43,23 @@ int RegisterContextMach_i386::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) {
int RegisterContextMach_i386::DoWriteGPR(lldb::tid_t tid, int flavor,
const GPR &gpr) {
- return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount);
+ return ::thread_set_state(
+ tid, flavor, reinterpret_cast<thread_state_t>(const_cast<GPR *>(&gpr)),
+ GPRWordCount);
}
int RegisterContextMach_i386::DoWriteFPU(lldb::tid_t tid, int flavor,
const FPU &fpu) {
- return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount);
+ return ::thread_set_state(
+ tid, flavor, reinterpret_cast<thread_state_t>(const_cast<FPU *>(&fpu)),
+ FPUWordCount);
}
int RegisterContextMach_i386::DoWriteEXC(lldb::tid_t tid, int flavor,
const EXC &exc) {
- return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount);
+ return ::thread_set_state(
+ tid, flavor, reinterpret_cast<thread_state_t>(const_cast<EXC *>(&exc)),
+ EXCWordCount);
}
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp
index 522b73a2888e7..0180879d51eee 100644
--- a/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp
@@ -46,17 +46,23 @@ int RegisterContextMach_x86_64::DoReadEXC(lldb::tid_t tid, int flavor,
int RegisterContextMach_x86_64::DoWriteGPR(lldb::tid_t tid, int flavor,
const GPR &gpr) {
- return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount);
+ return ::thread_set_state(
+ tid, flavor, reinterpret_cast<thread_state_t>(const_cast<GPR *>(&gpr)),
+ GPRWordCount);
}
int RegisterContextMach_x86_64::DoWriteFPU(lldb::tid_t tid, int flavor,
const FPU &fpu) {
- return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount);
+ return ::thread_set_state(
+ tid, flavor, reinterpret_cast<thread_state_t>(const_cast<FPU *>(&fpu)),
+ FPUWordCount);
}
int RegisterContextMach_x86_64::DoWriteEXC(lldb::tid_t tid, int flavor,
const EXC &exc) {
- return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount);
+ return ::thread_set_state(
+ tid, flavor, reinterpret_cast<thread_state_t>(const_cast<EXC *>(&exc)),
+ EXCWordCount);
}
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp
new file mode 100644
index 0000000000000..de410f063b536
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp
@@ -0,0 +1,216 @@
+//===-- RegisterContextPOSIX_ppc64le.cpp -------------------------*- C++-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <cstring>
+#include <errno.h>
+#include <stdint.h>
+
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Core/Scalar.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/DataExtractor.h"
+#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;
+using namespace lldb;
+
+static const uint32_t g_gpr_regnums[] = {
+ gpr_r0_ppc64le, gpr_r1_ppc64le, gpr_r2_ppc64le, gpr_r3_ppc64le,
+ gpr_r4_ppc64le, gpr_r5_ppc64le, gpr_r6_ppc64le, gpr_r7_ppc64le,
+ gpr_r8_ppc64le, gpr_r9_ppc64le, gpr_r10_ppc64le, gpr_r11_ppc64le,
+ gpr_r12_ppc64le, gpr_r13_ppc64le, gpr_r14_ppc64le, gpr_r15_ppc64le,
+ gpr_r16_ppc64le, gpr_r17_ppc64le, gpr_r18_ppc64le, gpr_r19_ppc64le,
+ gpr_r20_ppc64le, gpr_r21_ppc64le, gpr_r22_ppc64le, gpr_r23_ppc64le,
+ gpr_r24_ppc64le, gpr_r25_ppc64le, gpr_r26_ppc64le, gpr_r27_ppc64le,
+ gpr_r28_ppc64le, gpr_r29_ppc64le, gpr_r30_ppc64le, gpr_r31_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,
+};
+
+static const uint32_t g_fpr_regnums[] = {
+ fpr_f0_ppc64le, fpr_f1_ppc64le, fpr_f2_ppc64le, fpr_f3_ppc64le,
+ fpr_f4_ppc64le, fpr_f5_ppc64le, fpr_f6_ppc64le, fpr_f7_ppc64le,
+ fpr_f8_ppc64le, fpr_f9_ppc64le, fpr_f10_ppc64le, fpr_f11_ppc64le,
+ fpr_f12_ppc64le, fpr_f13_ppc64le, fpr_f14_ppc64le, fpr_f15_ppc64le,
+ fpr_f16_ppc64le, fpr_f17_ppc64le, fpr_f18_ppc64le, fpr_f19_ppc64le,
+ fpr_f20_ppc64le, fpr_f21_ppc64le, fpr_f22_ppc64le, fpr_f23_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,
+};
+
+static const uint32_t g_vmx_regnums[] = {
+ vmx_vr0_ppc64le, vmx_vr1_ppc64le, vmx_vr2_ppc64le, vmx_vr3_ppc64le,
+ vmx_vr4_ppc64le, vmx_vr5_ppc64le, vmx_vr6_ppc64le, vmx_vr7_ppc64le,
+ vmx_vr8_ppc64le, vmx_vr9_ppc64le, vmx_vr10_ppc64le, vmx_vr11_ppc64le,
+ vmx_vr12_ppc64le, vmx_vr13_ppc64le, vmx_vr14_ppc64le, vmx_vr15_ppc64le,
+ vmx_vr16_ppc64le, vmx_vr17_ppc64le, vmx_vr18_ppc64le, vmx_vr19_ppc64le,
+ vmx_vr20_ppc64le, vmx_vr21_ppc64le, vmx_vr22_ppc64le, vmx_vr23_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,
+};
+
+static const uint32_t g_vsx_regnums[] = {
+ vsx_vs0_ppc64le, vsx_vs1_ppc64le, vsx_vs2_ppc64le, vsx_vs3_ppc64le,
+ vsx_vs4_ppc64le, vsx_vs5_ppc64le, vsx_vs6_ppc64le, vsx_vs7_ppc64le,
+ vsx_vs8_ppc64le, vsx_vs9_ppc64le, vsx_vs10_ppc64le, vsx_vs11_ppc64le,
+ vsx_vs12_ppc64le, vsx_vs13_ppc64le, vsx_vs14_ppc64le, vsx_vs15_ppc64le,
+ vsx_vs16_ppc64le, vsx_vs17_ppc64le, vsx_vs18_ppc64le, vsx_vs19_ppc64le,
+ vsx_vs20_ppc64le, vsx_vs21_ppc64le, vsx_vs22_ppc64le, vsx_vs23_ppc64le,
+ vsx_vs24_ppc64le, vsx_vs25_ppc64le, vsx_vs26_ppc64le, vsx_vs27_ppc64le,
+ vsx_vs28_ppc64le, vsx_vs29_ppc64le, vsx_vs30_ppc64le, vsx_vs31_ppc64le,
+ vsx_vs32_ppc64le, vsx_vs33_ppc64le, vsx_vs34_ppc64le, vsx_vs35_ppc64le,
+ vsx_vs36_ppc64le, vsx_vs37_ppc64le, vsx_vs38_ppc64le, vsx_vs39_ppc64le,
+ vsx_vs40_ppc64le, vsx_vs41_ppc64le, vsx_vs42_ppc64le, vsx_vs43_ppc64le,
+ vsx_vs44_ppc64le, vsx_vs45_ppc64le, vsx_vs46_ppc64le, vsx_vs47_ppc64le,
+ vsx_vs48_ppc64le, vsx_vs49_ppc64le, vsx_vs50_ppc64le, vsx_vs51_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,
+};
+
+// Number of register sets provided by this context.
+enum { k_num_register_sets = 4 };
+
+static const RegisterSet g_reg_sets_ppc64le[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_ppc64le,
+ g_gpr_regnums},
+ {"Floating Point Registers", "fpr", k_num_fpr_registers_ppc64le,
+ g_fpr_regnums},
+ {"Altivec/VMX Registers", "vmx", k_num_vmx_registers_ppc64le,
+ g_vmx_regnums},
+ {"VSX Registers", "vsx", k_num_vsx_registers_ppc64le, g_vsx_regnums},
+};
+
+bool RegisterContextPOSIX_ppc64le::IsGPR(unsigned reg) {
+ return (reg <= k_last_gpr_ppc64le); // GPR's come first.
+}
+
+bool RegisterContextPOSIX_ppc64le::IsFPR(unsigned reg) {
+ return (reg >= k_first_fpr_ppc64le) && (reg <= k_last_fpr_ppc64le);
+}
+
+bool RegisterContextPOSIX_ppc64le::IsVMX(unsigned reg) {
+ return (reg >= k_first_vmx_ppc64le) && (reg <= k_last_vmx_ppc64le);
+}
+
+bool RegisterContextPOSIX_ppc64le::IsVSX(unsigned reg) {
+ return (reg >= k_first_vsx_ppc64le) && (reg <= k_last_vsx_ppc64le);
+}
+
+RegisterContextPOSIX_ppc64le::RegisterContextPOSIX_ppc64le(
+ Thread &thread, uint32_t concrete_frame_idx,
+ 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() {}
+
+unsigned RegisterContextPOSIX_ppc64le::GetRegisterOffset(unsigned reg) {
+ assert(reg < k_num_registers_ppc64le && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_offset;
+}
+
+unsigned RegisterContextPOSIX_ppc64le::GetRegisterSize(unsigned reg) {
+ assert(reg < k_num_registers_ppc64le && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_size;
+}
+
+size_t RegisterContextPOSIX_ppc64le::GetRegisterCount() {
+ size_t num_registers = k_num_registers_ppc64le;
+ return num_registers;
+}
+
+size_t RegisterContextPOSIX_ppc64le::GetGPRSize() {
+ return m_register_info_ap->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.
+ return m_register_info_ap->GetRegisterInfo();
+}
+
+const RegisterInfo *
+RegisterContextPOSIX_ppc64le::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg < k_num_registers_ppc64le)
+ return &GetRegisterInfo()[reg];
+ else
+ return NULL;
+}
+
+size_t RegisterContextPOSIX_ppc64le::GetRegisterSetCount() {
+ size_t sets = 0;
+ for (size_t set = 0; set < k_num_register_sets; ++set) {
+ if (IsRegisterSetAvailable(set))
+ ++sets;
+ }
+
+ return sets;
+}
+
+const RegisterSet *RegisterContextPOSIX_ppc64le::GetRegisterSet(size_t set) {
+ if (IsRegisterSetAvailable(set))
+ return &g_reg_sets_ppc64le[set];
+ else
+ return NULL;
+}
+
+const char *RegisterContextPOSIX_ppc64le::GetRegisterName(unsigned reg) {
+ assert(reg < k_num_registers_ppc64le && "Invalid register offset.");
+ return GetRegisterInfo()[reg].name;
+}
+
+lldb::ByteOrder RegisterContextPOSIX_ppc64le::GetByteOrder() {
+ // Get the target process whose privileged thread was used for the register
+ // read.
+ lldb::ByteOrder byte_order = eByteOrderInvalid;
+ Process *process = CalculateProcess().get();
+
+ if (process)
+ byte_order = process->GetByteOrder();
+ return byte_order;
+}
+
+bool RegisterContextPOSIX_ppc64le::IsRegisterSetAvailable(size_t set_index) {
+ size_t num_sets = k_num_register_sets;
+
+ 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.
+uint32_t RegisterContextPOSIX_ppc64le::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ const uint32_t num_regs = GetRegisterCount();
+
+ assert(kind < kNumRegisterKinds);
+ for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
+
+ if (reg_info->kinds[kind] == num)
+ return reg_idx;
+ }
+
+ return LLDB_INVALID_REGNUM;
+}
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h
new file mode 100644
index 0000000000000..1070b4dea4051
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h
@@ -0,0 +1,82 @@
+//===-- RegisterContextPOSIX_ppc64le.h --------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_RegisterContextPOSIX_ppc64le_h_
+#define liblldb_RegisterContextPOSIX_ppc64le_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h"
+#include "RegisterInfoInterface.h"
+#include "Utility/PPC64LE_DWARF_Registers.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Utility/Log.h"
+
+class RegisterContextPOSIX_ppc64le : public lldb_private::RegisterContext {
+public:
+ RegisterContextPOSIX_ppc64le(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info);
+
+ void InvalidateAllRegisters() override;
+
+ size_t GetRegisterCount() override;
+
+ virtual size_t GetGPRSize();
+
+ virtual unsigned GetRegisterSize(unsigned reg);
+
+ virtual unsigned GetRegisterOffset(unsigned reg);
+
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
+
+ size_t GetRegisterSetCount() override;
+
+ const lldb_private::RegisterSet *GetRegisterSet(size_t set) override;
+
+ const char *GetRegisterName(unsigned reg);
+
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
+
+protected:
+ // 64-bit general purpose registers.
+ uint64_t m_gpr_ppc64le[k_num_gpr_registers_ppc64le];
+
+ // floating-point registers including extended register.
+ uint64_t m_fpr_ppc64le[k_num_fpr_registers_ppc64le];
+
+ // VMX registers.
+ uint64_t m_vmx_ppc64le[k_num_vmx_registers_ppc64le * 2];
+
+ // VSX registers.
+ uint64_t m_vsx_ppc64le[k_num_vsx_registers_ppc64le * 2];
+
+ std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap;
+
+ // Determines if an extended register set is supported on the processor
+ // running the inferior process.
+ virtual bool IsRegisterSetAvailable(size_t set_index);
+
+ virtual const lldb_private::RegisterInfo *GetRegisterInfo();
+
+ bool IsGPR(unsigned reg);
+
+ bool IsFPR(unsigned reg);
+
+ bool IsVMX(unsigned reg);
+
+ bool IsVSX(unsigned reg);
+
+ lldb::ByteOrder GetByteOrder();
+};
+
+#endif // liblldb_RegisterContextPOSIX_ppc64le_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
index 5e1bf35356b8f..41cec8add9875 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
@@ -365,12 +365,6 @@ RegisterContextPOSIX_x86::RegisterContextPOSIX_x86(
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.
- m_iovec.iov_base = &m_fpr.xstate.xsave;
- m_iovec.iov_len = sizeof(m_fpr.xstate.xsave);
-
::memset(&m_fpr, 0, sizeof(FPR));
m_fpr_type = eNotValid;
@@ -481,19 +475,19 @@ bool RegisterContextPOSIX_x86::CopyYMMtoXSTATE(uint32_t reg,
return false;
if (byte_order == eByteOrderLittle) {
- ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ ::memcpy(m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(XMMReg));
- ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ ::memcpy(m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
sizeof(YMMHReg));
return true;
}
if (byte_order == eByteOrderBig) {
- ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ ::memcpy(m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
sizeof(XMMReg));
- ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ ::memcpy(m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(YMMHReg));
return true;
}
@@ -508,20 +502,20 @@ bool RegisterContextPOSIX_x86::CopyXSTATEtoYMM(uint32_t reg,
if (byte_order == eByteOrderLittle) {
::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
- m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
sizeof(XMMReg));
::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
- m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
sizeof(YMMHReg));
return true;
}
if (byte_order == eByteOrderBig) {
::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
- m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
sizeof(XMMReg));
::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
- m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
sizeof(YMMHReg));
return true;
}
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
index aa689273f2189..ca71a6f272f80 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
@@ -149,9 +149,9 @@ protected:
RegInfo m_reg_info;
FPRType
m_fpr_type; // determines the type of data stored by union FPR, if any.
- FPR m_fpr; // floating-point registers including extended register sets.
- IOVEC m_iovec; // wrapper for xsave.
- YMM m_ymm_set; // copy of ymmh and xmm register halves.
+ lldb_private::FPR m_fpr; // floating-point registers including extended
+ // register sets.
+ lldb_private::YMM m_ymm_set; // copy of ymmh and xmm register halves.
std::unique_ptr<lldb_private::RegisterInfoInterface>
m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
diff --git a/source/Plugins/Process/Utility/RegisterContext_mips.h b/source/Plugins/Process/Utility/RegisterContext_mips.h
index 565747cb4bd71..da470bd827327 100644
--- a/source/Plugins/Process/Utility/RegisterContext_mips.h
+++ b/source/Plugins/Process/Utility/RegisterContext_mips.h
@@ -241,11 +241,6 @@ enum {
dwarf_config5_mips64,
};
-struct IOVEC_mips {
- void *iov_base;
- size_t iov_len;
-};
-
// GP registers
struct GPR_linux_mips {
uint64_t zero;
diff --git a/source/Plugins/Process/Utility/RegisterContext_x86.h b/source/Plugins/Process/Utility/RegisterContext_x86.h
index 5f6fc295a15c1..6146dcaf7e5a2 100644
--- a/source/Plugins/Process/Utility/RegisterContext_x86.h
+++ b/source/Plugins/Process/Utility/RegisterContext_x86.h
@@ -13,8 +13,10 @@
#include <cstddef>
#include <cstdint>
+#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/Support/Compiler.h"
+namespace lldb_private {
//---------------------------------------------------------------------------
// i386 ehframe, dwarf regnums
//---------------------------------------------------------------------------
@@ -313,13 +315,28 @@ struct MPX {
LLVM_PACKED_START
struct XSAVE_HDR {
- uint64_t xstate_bv; // OS enabled xstate mask to determine the extended states
+ enum class XFeature : uint64_t {
+ FP = 1,
+ SSE = FP << 1,
+ YMM = SSE << 1,
+ BNDREGS = YMM << 1,
+ BNDCSR = BNDREGS << 1,
+ OPMASK = BNDCSR << 1,
+ ZMM_Hi256 = OPMASK << 1,
+ Hi16_ZMM = ZMM_Hi256 << 1,
+ PT = Hi16_ZMM << 1,
+ PKRU = PT << 1,
+ LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue*/ PKRU)
+ };
+
+ XFeature xstate_bv; // OS enabled xstate mask to determine the extended states
// supported by the processor
- uint64_t xcomp_bv; // Mask to indicate the format of the XSAVE area and of
+ XFeature xcomp_bv; // Mask to indicate the format of the XSAVE area and of
// the XRSTOR instruction
uint64_t reserved1[1];
uint64_t reserved2[5];
};
+static_assert(sizeof(XSAVE_HDR) == 64, "XSAVE_HDR layout incorrect");
LLVM_PACKED_END
// x86 extensions to FXSAVE (i.e. for AVX and MPX processors)
@@ -338,21 +355,13 @@ struct LLVM_ALIGNAS(64) XSAVE {
LLVM_PACKED_END
// Floating-point registers
-struct FPR {
- // Thread state for the floating-point unit of the processor read by ptrace.
- union XSTATE {
- FXSAVE fxsave; // Generic floating-point registers.
- XSAVE xsave; // x86 extended processor state.
- } xstate;
+union FPR {
+ FXSAVE fxsave; // Generic floating-point registers.
+ XSAVE xsave; // x86 extended processor state.
};
-//---------------------------------------------------------------------------
-// ptrace PTRACE_GETREGSET, PTRACE_SETREGSET structure
-//---------------------------------------------------------------------------
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
-struct IOVEC {
- void *iov_base; // pointer to XSAVE
- size_t iov_len; // sizeof(XSAVE)
-};
+} // namespace lldb_private
#endif
diff --git a/source/Plugins/Process/Utility/RegisterInfoInterface.h b/source/Plugins/Process/Utility/RegisterInfoInterface.h
index 74d5d6e502085..1894b53681224 100644
--- a/source/Plugins/Process/Utility/RegisterInfoInterface.h
+++ b/source/Plugins/Process/Utility/RegisterInfoInterface.h
@@ -10,10 +10,9 @@
#ifndef lldb_RegisterInfoInterface_h
#define lldb_RegisterInfoInterface_h
-#include <vector>
-
-#include "lldb/Core/ArchSpec.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/lldb-private-types.h"
+#include <vector>
namespace lldb_private {
diff --git a/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp b/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp
new file mode 100644
index 0000000000000..e5e7350fe68ad
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp
@@ -0,0 +1,66 @@
+//===-- RegisterInfoPOSIX_ppc64le.cpp --------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---------------------------------------------------------------------===//
+
+#include <cassert>
+#include <stddef.h>
+#include <vector>
+
+#include "lldb/lldb-defines.h"
+#include "llvm/Support/Compiler.h"
+
+#include "RegisterInfoPOSIX_ppc64le.h"
+
+//-----------------------------------------------------------------------------
+// Include RegisterInfoPOSIX_ppc64le to declare our g_register_infos_ppc64le
+//-----------------------------------------------------------------------------
+#define DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
+#include "RegisterInfos_ppc64le.h"
+#undef DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
+
+static const lldb_private::RegisterInfo *
+GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::ppc64le:
+ return g_register_infos_ppc64le;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
+ }
+}
+
+static uint32_t
+GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::ppc64le:
+ return static_cast<uint32_t>(sizeof(g_register_infos_ppc64le) /
+ sizeof(g_register_infos_ppc64le[0]));
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
+}
+
+RegisterInfoPOSIX_ppc64le::RegisterInfoPOSIX_ppc64le(
+ const lldb_private::ArchSpec &target_arch)
+ : lldb_private::RegisterInfoInterface(target_arch),
+ m_register_info_p(GetRegisterInfoPtr(target_arch)),
+ m_register_info_count(GetRegisterInfoCount(target_arch)) {}
+
+size_t RegisterInfoPOSIX_ppc64le::GetGPRSize() const {
+ return sizeof(GPR);
+}
+
+const lldb_private::RegisterInfo *
+RegisterInfoPOSIX_ppc64le::GetRegisterInfo() const {
+ return m_register_info_p;
+}
+
+uint32_t RegisterInfoPOSIX_ppc64le::GetRegisterCount() const {
+ return m_register_info_count;
+}
diff --git a/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h b/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h
new file mode 100644
index 0000000000000..411ab05c2b13d
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h
@@ -0,0 +1,32 @@
+//===-- RegisterInfoPOSIX_ppc64le.h -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_RegisterContextLinux_ppc64le_H_
+#define liblldb_RegisterContextLinux_ppc64le_H_
+
+#include "RegisterInfoInterface.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
+
+class RegisterInfoPOSIX_ppc64le : public lldb_private::RegisterInfoInterface {
+public:
+ RegisterInfoPOSIX_ppc64le(const lldb_private::ArchSpec &target_arch);
+
+ size_t GetGPRSize() const override;
+
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
+
+ uint32_t GetRegisterCount() const override;
+
+private:
+ const lldb_private::RegisterInfo *m_register_info_p;
+ uint32_t m_register_info_count;
+};
+
+#endif
diff --git a/source/Plugins/Process/Utility/RegisterInfos_i386.h b/source/Plugins/Process/Utility/RegisterInfos_i386.h
index 8597d0c39dc48..ffdc4d0d116b0 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_i386.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_i386.h
@@ -27,19 +27,19 @@
// Based on DNBArchImplI386.cpp from debugserver
#define YMM_OFFSET(reg_index) \
(LLVM_EXTENSION offsetof(UserArea, i387) + \
- LLVM_EXTENSION offsetof(FPR, xstate) + \
+ LLVM_EXTENSION offsetof(FPR, fxsave) + \
LLVM_EXTENSION offsetof(FXSAVE, xmm[7]) + sizeof(XMMReg) + \
(32 * reg_index))
-#define BNDR_OFFSET(reg_index) \
- (LLVM_EXTENSION offsetof(UserArea, i387) + \
- LLVM_EXTENSION offsetof(FPR, xstate) + \
- LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index]))
+#define BNDR_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, i387) + \
+ LLVM_EXTENSION offsetof(FPR, xsave) + \
+ LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index]))
-#define BNDC_OFFSET(reg_index) \
- (LLVM_EXTENSION offsetof(UserArea, i387) + \
- LLVM_EXTENSION offsetof(FPR, xstate) + \
- LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index]))
+#define BNDC_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, i387) + \
+ LLVM_EXTENSION offsetof(FPR, xsave) + \
+ LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index]))
// Number of bytes needed to represent a FPR.
#if !defined(FPR_SIZE)
diff --git a/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h b/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h
new file mode 100644
index 0000000000000..bffa7a1d8b635
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h
@@ -0,0 +1,476 @@
+//===-- RegisterInfos_ppc64le.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_PPC64LE_STRUCT
+
+// C Includes
+#include <stddef.h>
+
+// Computes the offset of the given GPR in the user data area.
+#define GPR_OFFSET(regname) (offsetof(GPR, regname))
+#define FPR_OFFSET(regname) (offsetof(FPR, regname) + sizeof(GPR))
+#define VMX_OFFSET(regname) (offsetof(VMX, regname) + sizeof(GPR) + sizeof(FPR))
+#define VSX_OFFSET(regname) \
+ (offsetof(VSX, regname) + sizeof(GPR) + sizeof(FPR) + sizeof(VMX))
+#define GPR_SIZE(regname) (sizeof(((GPR *)NULL)->regname))
+
+#include "Utility/PPC64LE_DWARF_Registers.h"
+#include "lldb-ppc64le-register-enums.h"
+
+// Note that the size and offset will be updated by platform-specific classes.
+#define DEFINE_GPR(reg, alt, lldb_kind) \
+ { \
+ #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), lldb::eEncodingUint, \
+ lldb::eFormatHex, \
+ {ppc64le_dwarf::dwarf_##reg##_ppc64le,\
+ ppc64le_dwarf::dwarf_##reg##_ppc64le,\
+ lldb_kind, \
+ LLDB_INVALID_REGNUM, \
+ gpr_##reg##_ppc64le }, \
+ NULL, NULL, NULL, 0 \
+ }
+#define DEFINE_FPR(reg, alt, lldb_kind) \
+ { \
+#reg, alt, 8, FPR_OFFSET(reg), lldb::eEncodingIEEE754, lldb::eFormatFloat, \
+ {ppc64le_dwarf::dwarf_##reg##_ppc64le, \
+ ppc64le_dwarf::dwarf_##reg##_ppc64le, lldb_kind, LLDB_INVALID_REGNUM, \
+ fpr_##reg##_ppc64le }, \
+ NULL, NULL, NULL, 0 \
+ }
+#define DEFINE_VMX(reg, lldb_kind) \
+ { \
+#reg, NULL, 16, VMX_OFFSET(reg), lldb::eEncodingVector, \
+ lldb::eFormatVectorOfUInt32, \
+ {ppc64le_dwarf::dwarf_##reg##_ppc64le, \
+ ppc64le_dwarf::dwarf_##reg##_ppc64le, lldb_kind, LLDB_INVALID_REGNUM, \
+ vmx_##reg##_ppc64le }, \
+ NULL, NULL, NULL, 0 \
+ }
+#define DEFINE_VSX(reg, lldb_kind) \
+ { \
+#reg, NULL, 16, VSX_OFFSET(reg), lldb::eEncodingVector, \
+ lldb::eFormatVectorOfUInt32, \
+ {ppc64le_dwarf::dwarf_##reg##_ppc64le, \
+ ppc64le_dwarf::dwarf_##reg##_ppc64le, lldb_kind, LLDB_INVALID_REGNUM, \
+ vsx_##reg##_ppc64le }, \
+ NULL, NULL, NULL, 0 \
+ }
+
+// General purpose registers.
+// EH_Frame, Generic, Process Plugin
+#define POWERPC_REGS \
+ DEFINE_GPR(r0, NULL, LLDB_INVALID_REGNUM) \
+ , DEFINE_GPR(r1, "sp", LLDB_REGNUM_GENERIC_SP), \
+ DEFINE_GPR(r2, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r3, "arg1", LLDB_REGNUM_GENERIC_ARG1), \
+ DEFINE_GPR(r4, "arg2", LLDB_REGNUM_GENERIC_ARG2), \
+ DEFINE_GPR(r5, "arg3", LLDB_REGNUM_GENERIC_ARG3), \
+ DEFINE_GPR(r6, "arg4", LLDB_REGNUM_GENERIC_ARG4), \
+ DEFINE_GPR(r7, "arg5", LLDB_REGNUM_GENERIC_ARG5), \
+ DEFINE_GPR(r8, "arg6", LLDB_REGNUM_GENERIC_ARG6), \
+ DEFINE_GPR(r9, "arg7", LLDB_REGNUM_GENERIC_ARG7), \
+ DEFINE_GPR(r10, "arg8", LLDB_REGNUM_GENERIC_ARG8), \
+ DEFINE_GPR(r11, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r12, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r13, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r14, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r15, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r16, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r17, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r18, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r19, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r20, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r21, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r22, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r23, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r24, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r25, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r26, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r27, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r28, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r29, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r30, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r31, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(pc, "pc", LLDB_REGNUM_GENERIC_PC), \
+ DEFINE_GPR(msr, "msr", LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(origr3, "orig_r3", LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(ctr, "ctr", LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(lr, "lr", LLDB_REGNUM_GENERIC_RA), \
+ DEFINE_GPR(xer, "xer", LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(cr, "cr", LLDB_REGNUM_GENERIC_FLAGS), \
+ DEFINE_GPR(softe, "softe", LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(trap, "trap", LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f0, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f1, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f2, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f3, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f4, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f5, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f6, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f7, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f8, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f9, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f10, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f11, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f12, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f13, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f14, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f15, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f16, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f17, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f18, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f19, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f20, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f21, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f22, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f23, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f24, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f25, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f26, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f27, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f28, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f29, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f30, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f31, NULL, LLDB_INVALID_REGNUM), \
+ {"fpscr", \
+ NULL, \
+ 8, \
+ FPR_OFFSET(fpscr), \
+ lldb::eEncodingUint, \
+ lldb::eFormatHex, \
+ {ppc64le_dwarf::dwarf_fpscr_ppc64le, \
+ ppc64le_dwarf::dwarf_fpscr_ppc64le, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, fpr_fpscr_ppc64le}, \
+ NULL, \
+ NULL, \
+ NULL, \
+ 0}, \
+ DEFINE_VMX(vr0, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr1, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr2, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr3, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr4, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr5, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr6, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr7, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr8, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr9, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr10, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr11, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr12, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr13, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr14, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr15, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr16, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr17, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr18, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr19, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr20, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr21, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr22, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr23, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr24, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr25, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr26, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr27, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr28, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr29, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr30, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr31, LLDB_INVALID_REGNUM), \
+ {"vscr", \
+ NULL, \
+ 4, \
+ VMX_OFFSET(vscr), \
+ lldb::eEncodingUint, \
+ lldb::eFormatHex, \
+ {ppc64le_dwarf::dwarf_vscr_ppc64le, ppc64le_dwarf::dwarf_vscr_ppc64le, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, vmx_vscr_ppc64le}, \
+ NULL, \
+ NULL, \
+ NULL, \
+ 0}, \
+ {"vrsave", \
+ NULL, \
+ 4, \
+ VMX_OFFSET(vrsave), \
+ lldb::eEncodingUint, \
+ lldb::eFormatHex, \
+ {ppc64le_dwarf::dwarf_vrsave_ppc64le, \
+ ppc64le_dwarf::dwarf_vrsave_ppc64le, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, vmx_vrsave_ppc64le}, \
+ NULL, \
+ NULL, \
+ NULL, \
+ 0}, \
+ DEFINE_VSX(vs0, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs1, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs2, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs3, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs4, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs5, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs6, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs7, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs8, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs9, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs10, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs11, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs12, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs13, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs14, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs15, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs16, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs17, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs18, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs19, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs20, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs21, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs22, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs23, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs24, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs25, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs26, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs27, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs28, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs29, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs30, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs31, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs32, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs33, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs34, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs35, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs36, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs37, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs38, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs39, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs40, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs41, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs42, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs43, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs44, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs45, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs46, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs47, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs48, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs49, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs50, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs51, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs52, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs53, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs54, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs55, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs56, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs57, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs58, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs59, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs50, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs61, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs62, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs63, LLDB_INVALID_REGNUM), /* */
+
+typedef struct _GPR {
+ 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 pc;
+ uint64_t msr;
+ uint64_t origr3;
+ uint64_t ctr;
+ uint64_t lr;
+ uint64_t xer;
+ uint64_t cr;
+ uint64_t softe;
+ uint64_t trap;
+ uint64_t pad[3];
+} GPR;
+
+typedef struct _FPR {
+ 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;
+
+typedef struct _VMX {
+ 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;
+
+typedef struct _VSX {
+ uint32_t vs0[4];
+ uint32_t vs1[4];
+ uint32_t vs2[4];
+ uint32_t vs3[4];
+ uint32_t vs4[4];
+ uint32_t vs5[4];
+ uint32_t vs6[4];
+ uint32_t vs7[4];
+ uint32_t vs8[4];
+ uint32_t vs9[4];
+ uint32_t vs10[4];
+ uint32_t vs11[4];
+ uint32_t vs12[4];
+ uint32_t vs13[4];
+ uint32_t vs14[4];
+ uint32_t vs15[4];
+ uint32_t vs16[4];
+ uint32_t vs17[4];
+ uint32_t vs18[4];
+ uint32_t vs19[4];
+ uint32_t vs20[4];
+ uint32_t vs21[4];
+ uint32_t vs22[4];
+ uint32_t vs23[4];
+ uint32_t vs24[4];
+ uint32_t vs25[4];
+ uint32_t vs26[4];
+ uint32_t vs27[4];
+ uint32_t vs28[4];
+ uint32_t vs29[4];
+ uint32_t vs30[4];
+ uint32_t vs31[4];
+ uint32_t vs32[4];
+ uint32_t vs33[4];
+ uint32_t vs34[4];
+ uint32_t vs35[4];
+ uint32_t vs36[4];
+ uint32_t vs37[4];
+ uint32_t vs38[4];
+ uint32_t vs39[4];
+ uint32_t vs40[4];
+ uint32_t vs41[4];
+ uint32_t vs42[4];
+ uint32_t vs43[4];
+ uint32_t vs44[4];
+ uint32_t vs45[4];
+ uint32_t vs46[4];
+ uint32_t vs47[4];
+ uint32_t vs48[4];
+ uint32_t vs49[4];
+ uint32_t vs50[4];
+ uint32_t vs51[4];
+ uint32_t vs52[4];
+ uint32_t vs53[4];
+ uint32_t vs54[4];
+ uint32_t vs55[4];
+ uint32_t vs56[4];
+ uint32_t vs57[4];
+ uint32_t vs58[4];
+ uint32_t vs59[4];
+ uint32_t vs60[4];
+ uint32_t vs61[4];
+ uint32_t vs62[4];
+ uint32_t vs63[4];
+} VSX;
+
+static lldb_private::RegisterInfo g_register_infos_ppc64le[] = {
+ POWERPC_REGS
+};
+
+static_assert((sizeof(g_register_infos_ppc64le) /
+ sizeof(g_register_infos_ppc64le[0])) ==
+ k_num_registers_ppc64le,
+ "g_register_infos_powerpc64 has wrong number of register infos");
+
+#undef DEFINE_FPR
+#undef DEFINE_GPR
+#undef DEFINE_VMX
+#undef DEFINE_VSX
+
+#endif // DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
diff --git a/source/Plugins/Process/Utility/RegisterInfos_x86_64.h b/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
index 8861ecd668062..651536cb60450 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
@@ -7,11 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Support/Compiler.h"
-#include <cstddef>
-#include <cstdint>
-
-// Project includes
+// This file is meant to be textually included. Do not #include modular
+// headers here.
// Computes the offset of the given GPR in the user data area.
#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR, regname))
@@ -19,25 +16,25 @@
// Computes the offset of the given FPR in the extended data area.
#define FPR_OFFSET(regname) \
(LLVM_EXTENSION offsetof(UserArea, fpr) + \
- LLVM_EXTENSION offsetof(FPR, xstate) + \
+ LLVM_EXTENSION offsetof(FPR, fxsave) + \
LLVM_EXTENSION offsetof(FXSAVE, regname))
// Computes the offset of the YMM register assembled from register halves.
// Based on DNBArchImplX86_64.cpp from debugserver
#define YMM_OFFSET(reg_index) \
(LLVM_EXTENSION offsetof(UserArea, fpr) + \
- LLVM_EXTENSION offsetof(FPR, xstate) + \
+ LLVM_EXTENSION offsetof(FPR, xsave) + \
LLVM_EXTENSION offsetof(XSAVE, ymmh[0]) + (32 * reg_index))
-#define BNDR_OFFSET(reg_index) \
- (LLVM_EXTENSION offsetof(UserArea, fpr) + \
- LLVM_EXTENSION offsetof(FPR, xstate) + \
- LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index]))
+#define BNDR_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, fpr) + \
+ LLVM_EXTENSION offsetof(FPR, xsave) + \
+ LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index]))
-#define BNDC_OFFSET(reg_index) \
- (LLVM_EXTENSION offsetof(UserArea, fpr) + \
- LLVM_EXTENSION offsetof(FPR, xstate) + \
- LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index]))
+#define BNDC_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, fpr) + \
+ LLVM_EXTENSION offsetof(FPR, xsave) + \
+ LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index]))
#ifdef DECLARE_REGISTER_INFOS_X86_64_STRUCT
diff --git a/source/Plugins/Process/Utility/StopInfoMachException.cpp b/source/Plugins/Process/Utility/StopInfoMachException.cpp
index 435f3d18c0625..3e860874183cf 100644
--- a/source/Plugins/Process/Utility/StopInfoMachException.cpp
+++ b/source/Plugins/Process/Utility/StopInfoMachException.cpp
@@ -14,7 +14,6 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/Watchpoint.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/ExecutionContext.h"
diff --git a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
index f907735d8f587..d831011cb6612 100644
--- a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
+++ b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
@@ -7,11 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Symbol.h"
@@ -19,6 +14,7 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Utility/ArchSpec.h"
#include "RegisterContextMacOSXFrameBackchain.h"
@@ -85,8 +81,6 @@ size_t UnwindMacOSXFrameBackchain::GetStackFrameData_i386(
if (process == NULL)
return 0;
- std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair;
-
struct Frame_i386 {
uint32_t fp;
uint32_t pc;
@@ -179,8 +173,6 @@ size_t UnwindMacOSXFrameBackchain::GetStackFrameData_x86_64(
StackFrame *first_frame = exe_ctx.GetFramePtr();
- std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair;
-
struct Frame_x86_64 {
uint64_t fp;
uint64_t pc;
diff --git a/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h b/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h
new file mode 100644
index 0000000000000..675804d132680
--- /dev/null
+++ b/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h
@@ -0,0 +1,210 @@
+//===-- lldb-ppc64le-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_ppc64le_register_enums_h
+#define lldb_ppc64le_register_enums_h
+
+// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
+
+// ---------------------------------------------------------------------------
+// Internal codes for all ppc64le registers.
+// ---------------------------------------------------------------------------
+enum {
+ k_first_gpr_ppc64le,
+ gpr_r0_ppc64le = k_first_gpr_ppc64le,
+ gpr_r1_ppc64le,
+ gpr_r2_ppc64le,
+ gpr_r3_ppc64le,
+ gpr_r4_ppc64le,
+ gpr_r5_ppc64le,
+ gpr_r6_ppc64le,
+ gpr_r7_ppc64le,
+ gpr_r8_ppc64le,
+ gpr_r9_ppc64le,
+ gpr_r10_ppc64le,
+ gpr_r11_ppc64le,
+ gpr_r12_ppc64le,
+ gpr_r13_ppc64le,
+ gpr_r14_ppc64le,
+ gpr_r15_ppc64le,
+ gpr_r16_ppc64le,
+ gpr_r17_ppc64le,
+ gpr_r18_ppc64le,
+ gpr_r19_ppc64le,
+ gpr_r20_ppc64le,
+ gpr_r21_ppc64le,
+ gpr_r22_ppc64le,
+ gpr_r23_ppc64le,
+ gpr_r24_ppc64le,
+ gpr_r25_ppc64le,
+ gpr_r26_ppc64le,
+ gpr_r27_ppc64le,
+ gpr_r28_ppc64le,
+ gpr_r29_ppc64le,
+ gpr_r30_ppc64le,
+ gpr_r31_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,
+ k_last_gpr_ppc64le = gpr_trap_ppc64le,
+
+ k_first_fpr_ppc64le,
+ fpr_f0_ppc64le = k_first_fpr_ppc64le,
+ fpr_f1_ppc64le,
+ fpr_f2_ppc64le,
+ fpr_f3_ppc64le,
+ fpr_f4_ppc64le,
+ fpr_f5_ppc64le,
+ fpr_f6_ppc64le,
+ fpr_f7_ppc64le,
+ fpr_f8_ppc64le,
+ fpr_f9_ppc64le,
+ fpr_f10_ppc64le,
+ fpr_f11_ppc64le,
+ fpr_f12_ppc64le,
+ fpr_f13_ppc64le,
+ fpr_f14_ppc64le,
+ fpr_f15_ppc64le,
+ fpr_f16_ppc64le,
+ fpr_f17_ppc64le,
+ fpr_f18_ppc64le,
+ fpr_f19_ppc64le,
+ fpr_f20_ppc64le,
+ fpr_f21_ppc64le,
+ fpr_f22_ppc64le,
+ fpr_f23_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,
+ k_last_fpr_ppc64le = fpr_fpscr_ppc64le,
+
+ k_first_vmx_ppc64le,
+ vmx_vr0_ppc64le = k_first_vmx_ppc64le,
+ vmx_vr1_ppc64le,
+ vmx_vr2_ppc64le,
+ vmx_vr3_ppc64le,
+ vmx_vr4_ppc64le,
+ vmx_vr5_ppc64le,
+ vmx_vr6_ppc64le,
+ vmx_vr7_ppc64le,
+ vmx_vr8_ppc64le,
+ vmx_vr9_ppc64le,
+ vmx_vr10_ppc64le,
+ vmx_vr11_ppc64le,
+ vmx_vr12_ppc64le,
+ vmx_vr13_ppc64le,
+ vmx_vr14_ppc64le,
+ vmx_vr15_ppc64le,
+ vmx_vr16_ppc64le,
+ vmx_vr17_ppc64le,
+ vmx_vr18_ppc64le,
+ vmx_vr19_ppc64le,
+ vmx_vr20_ppc64le,
+ vmx_vr21_ppc64le,
+ vmx_vr22_ppc64le,
+ vmx_vr23_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,
+ k_last_vmx_ppc64le = vmx_vrsave_ppc64le,
+
+ k_first_vsx_ppc64le,
+ vsx_vs0_ppc64le = k_first_vsx_ppc64le,
+ vsx_vs1_ppc64le,
+ vsx_vs2_ppc64le,
+ vsx_vs3_ppc64le,
+ vsx_vs4_ppc64le,
+ vsx_vs5_ppc64le,
+ vsx_vs6_ppc64le,
+ vsx_vs7_ppc64le,
+ vsx_vs8_ppc64le,
+ vsx_vs9_ppc64le,
+ vsx_vs10_ppc64le,
+ vsx_vs11_ppc64le,
+ vsx_vs12_ppc64le,
+ vsx_vs13_ppc64le,
+ vsx_vs14_ppc64le,
+ vsx_vs15_ppc64le,
+ vsx_vs16_ppc64le,
+ vsx_vs17_ppc64le,
+ vsx_vs18_ppc64le,
+ vsx_vs19_ppc64le,
+ vsx_vs20_ppc64le,
+ vsx_vs21_ppc64le,
+ vsx_vs22_ppc64le,
+ vsx_vs23_ppc64le,
+ vsx_vs24_ppc64le,
+ vsx_vs25_ppc64le,
+ vsx_vs26_ppc64le,
+ vsx_vs27_ppc64le,
+ vsx_vs28_ppc64le,
+ vsx_vs29_ppc64le,
+ vsx_vs30_ppc64le,
+ vsx_vs31_ppc64le,
+ vsx_vs32_ppc64le,
+ vsx_vs33_ppc64le,
+ vsx_vs34_ppc64le,
+ vsx_vs35_ppc64le,
+ vsx_vs36_ppc64le,
+ vsx_vs37_ppc64le,
+ vsx_vs38_ppc64le,
+ vsx_vs39_ppc64le,
+ vsx_vs40_ppc64le,
+ vsx_vs41_ppc64le,
+ vsx_vs42_ppc64le,
+ vsx_vs43_ppc64le,
+ vsx_vs44_ppc64le,
+ vsx_vs45_ppc64le,
+ vsx_vs46_ppc64le,
+ vsx_vs47_ppc64le,
+ vsx_vs48_ppc64le,
+ vsx_vs49_ppc64le,
+ vsx_vs50_ppc64le,
+ vsx_vs51_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,
+ k_last_vsx_ppc64le = vsx_vs63_ppc64le,
+
+ k_num_registers_ppc64le,
+ k_num_gpr_registers_ppc64le = k_last_gpr_ppc64le - k_first_gpr_ppc64le + 1,
+ k_num_fpr_registers_ppc64le = k_last_fpr_ppc64le - k_first_fpr_ppc64le + 1,
+ k_num_vmx_registers_ppc64le = k_last_vmx_ppc64le - k_first_vmx_ppc64le + 1,
+ k_num_vsx_registers_ppc64le = k_last_vsx_ppc64le - k_first_vsx_ppc64le + 1,
+};
+
+#endif // #ifndef lldb_ppc64le_register_enums_h
diff --git a/source/Plugins/Process/elf-core/CMakeLists.txt b/source/Plugins/Process/elf-core/CMakeLists.txt
index c7ffae6953207..3082c73f6dda7 100644
--- a/source/Plugins/Process/elf-core/CMakeLists.txt
+++ b/source/Plugins/Process/elf-core/CMakeLists.txt
@@ -7,8 +7,10 @@ add_lldb_library(lldbPluginProcessElfCore PLUGIN
RegisterContextPOSIXCore_arm64.cpp
RegisterContextPOSIXCore_mips64.cpp
RegisterContextPOSIXCore_powerpc.cpp
+ RegisterContextPOSIXCore_ppc64le.cpp
RegisterContextPOSIXCore_s390x.cpp
RegisterContextPOSIXCore_x86_64.cpp
+ RegisterUtilities.cpp
LINK_LIBS
lldbCore
diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index 71eb6437ceed1..7d6a0c9ad2df0 100644
--- a/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -32,8 +32,7 @@
#include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
-
-// Project includes
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
#include "ProcessElfCore.h"
#include "ThreadElfCore.h"
@@ -101,10 +100,7 @@ bool ProcessElfCore::CanDebug(lldb::TargetSP target_sp,
ProcessElfCore::ProcessElfCore(lldb::TargetSP target_sp,
lldb::ListenerSP listener_sp,
const FileSpec &core_file)
- : Process(target_sp, listener_sp), m_core_module_sp(),
- m_core_file(core_file), m_dyld_plugin_name(),
- m_os(llvm::Triple::UnknownOS), m_thread_data_valid(false),
- m_thread_data(), m_core_aranges() {}
+ : Process(target_sp, listener_sp), m_core_file(core_file) {}
//----------------------------------------------------------------------
// Destructor
@@ -193,9 +189,8 @@ Status ProcessElfCore::DoLoadCore() {
// Parse thread contexts and auxv structure
if (header->p_type == llvm::ELF::PT_NOTE) {
- error = ParseThreadContextsFromNoteSegment(header, data);
- if (error.Fail())
- return error;
+ if (llvm::Error error = ParseThreadContextsFromNoteSegment(header, data))
+ return Status(std::move(error));
}
// PT_LOAD segments contains address map
if (header->p_type == llvm::ELF::PT_LOAD) {
@@ -404,7 +399,6 @@ size_t ProcessElfCore::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
void ProcessElfCore::Clear() {
m_thread_list.Clear();
- m_os = llvm::Triple::UnknownOS;
SetUnixSignals(std::make_shared<UnixSignals>());
}
@@ -427,43 +421,10 @@ lldb::addr_t ProcessElfCore::GetImageInfoAddress() {
return LLDB_INVALID_ADDRESS;
}
-/// Core files PT_NOTE segment descriptor types
-enum {
- NT_PRSTATUS = 1,
- NT_FPREGSET,
- NT_PRPSINFO,
- NT_TASKSTRUCT,
- NT_PLATFORM,
- NT_AUXV,
- NT_FILE = 0x46494c45,
- NT_PRXFPREG = 0x46e62b7f,
- NT_SIGINFO = 0x53494749,
- NT_OPENBSD_PROCINFO = 10,
- NT_OPENBSD_AUXV = 11,
- NT_OPENBSD_REGS = 20,
- NT_OPENBSD_FPREGS = 21,
-};
-
-namespace FREEBSD {
-
-enum {
- NT_PRSTATUS = 1,
- NT_FPREGSET,
- NT_PRPSINFO,
- NT_THRMISC = 7,
- NT_PROCSTAT_AUXV = 16,
- NT_PPC_VMX = 0x100
-};
-}
-
-namespace NETBSD {
-
-enum { NT_PROCINFO = 1, NT_AUXV, NT_AMD64_REGS = 33, NT_AMD64_FPREGS = 35 };
-}
-
// Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details.
-static void ParseFreeBSDPrStatus(ThreadData &thread_data, DataExtractor &data,
- ArchSpec &arch) {
+static void ParseFreeBSDPrStatus(ThreadData &thread_data,
+ const DataExtractor &data,
+ const ArchSpec &arch) {
lldb::offset_t offset = 0;
bool lp64 = (arch.GetMachine() == llvm::Triple::aarch64 ||
arch.GetMachine() == llvm::Triple::mips64 ||
@@ -492,12 +453,8 @@ static void ParseFreeBSDPrStatus(ThreadData &thread_data, DataExtractor &data,
thread_data.gpregset = DataExtractor(data, offset, len);
}
-static void ParseFreeBSDThrMisc(ThreadData &thread_data, DataExtractor &data) {
- lldb::offset_t offset = 0;
- thread_data.name = data.GetCStr(&offset, 20);
-}
-
-static void ParseNetBSDProcInfo(ThreadData &thread_data, DataExtractor &data) {
+static void ParseNetBSDProcInfo(ThreadData &thread_data,
+ const DataExtractor &data) {
lldb::offset_t offset = 0;
int version = data.GetU32(&offset);
@@ -508,7 +465,8 @@ static void ParseNetBSDProcInfo(ThreadData &thread_data, DataExtractor &data) {
thread_data.signo = data.GetU32(&offset);
}
-static void ParseOpenBSDProcInfo(ThreadData &thread_data, DataExtractor &data) {
+static void ParseOpenBSDProcInfo(ThreadData &thread_data,
+ const DataExtractor &data) {
lldb::offset_t offset = 0;
int version = data.GetU32(&offset);
@@ -519,202 +477,263 @@ static void ParseOpenBSDProcInfo(ThreadData &thread_data, DataExtractor &data) {
thread_data.signo = data.GetU32(&offset);
}
-/// Parse Thread context from PT_NOTE segment and store it in the thread list
-/// Notes:
-/// 1) A PT_NOTE segment is composed of one or more NOTE entries.
-/// 2) NOTE Entry contains a standard header followed by variable size data.
-/// (see ELFNote structure)
-/// 3) A Thread Context in a core file usually described by 3 NOTE entries.
-/// a) NT_PRSTATUS - Register context
-/// b) NT_PRPSINFO - Process info(pid..)
-/// c) NT_FPREGSET - Floating point registers
-/// 4) The NOTE entries can be in any order
-/// 5) If a core file contains multiple thread contexts then there is two data
-/// forms
-/// a) Each thread context(2 or more NOTE entries) contained in its own
-/// segment (PT_NOTE)
-/// b) All thread context is stored in a single segment(PT_NOTE).
-/// This case is little tricker since while parsing we have to find where
-/// the
-/// new thread starts. The current implementation marks beginning of
-/// new thread when it finds NT_PRSTATUS or NT_PRPSINFO NOTE entry.
-/// For case (b) there may be either one NT_PRPSINFO per thread, or a single
-/// one that applies to all threads (depending on the platform type).
-Status ProcessElfCore::ParseThreadContextsFromNoteSegment(
- const elf::ELFProgramHeader *segment_header, DataExtractor segment_data) {
- assert(segment_header && segment_header->p_type == llvm::ELF::PT_NOTE);
-
+llvm::Expected<std::vector<CoreNote>>
+ProcessElfCore::parseSegment(const DataExtractor &segment) {
lldb::offset_t offset = 0;
- std::unique_ptr<ThreadData> thread_data(new ThreadData);
+ std::vector<CoreNote> result;
+
+ while (offset < segment.GetByteSize()) {
+ ELFNote note = ELFNote();
+ if (!note.Parse(segment, &offset))
+ return llvm::make_error<llvm::StringError>(
+ "Unable to parse note segment", llvm::inconvertibleErrorCode());
+
+ size_t note_start = offset;
+ size_t note_size = llvm::alignTo(note.n_descsz, 4);
+ DataExtractor note_data(segment, note_start, note_size);
+
+ result.push_back({note, note_data});
+ offset += note_size;
+ }
+
+ return std::move(result);
+}
+
+llvm::Error ProcessElfCore::parseFreeBSDNotes(llvm::ArrayRef<CoreNote> notes) {
bool have_prstatus = false;
bool have_prpsinfo = false;
+ ThreadData thread_data;
+ for (const auto &note : notes) {
+ if (note.info.n_name != "FreeBSD")
+ continue;
+
+ if ((note.info.n_type == FREEBSD::NT_PRSTATUS && have_prstatus) ||
+ (note.info.n_type == FREEBSD::NT_PRPSINFO && have_prpsinfo)) {
+ assert(thread_data.gpregset.GetByteSize() > 0);
+ // Add the new thread to thread list
+ m_thread_data.push_back(thread_data);
+ thread_data = ThreadData();
+ have_prstatus = false;
+ have_prpsinfo = false;
+ }
- ArchSpec arch = GetArchitecture();
- ELFLinuxPrPsInfo prpsinfo;
- ELFLinuxPrStatus prstatus;
- ELFLinuxSigInfo siginfo;
- size_t header_size;
- size_t len;
- Status error;
+ switch (note.info.n_type) {
+ case FREEBSD::NT_PRSTATUS:
+ have_prstatus = true;
+ ParseFreeBSDPrStatus(thread_data, note.data, GetArchitecture());
+ break;
+ case FREEBSD::NT_PRPSINFO:
+ have_prpsinfo = true;
+ break;
+ case FREEBSD::NT_THRMISC: {
+ lldb::offset_t offset = 0;
+ thread_data.name = note.data.GetCStr(&offset, 20);
+ break;
+ }
+ case FREEBSD::NT_PROCSTAT_AUXV:
+ // FIXME: FreeBSD sticks an int at the beginning of the note
+ m_auxv = DataExtractor(note.data, 4, note.data.GetByteSize() - 4);
+ break;
+ default:
+ thread_data.notes.push_back(note);
+ break;
+ }
+ }
+ if (!have_prstatus) {
+ return llvm::make_error<llvm::StringError>(
+ "Could not find NT_PRSTATUS note in core file.",
+ llvm::inconvertibleErrorCode());
+ }
+ m_thread_data.push_back(thread_data);
+ return llvm::Error::success();
+}
- // Loop through the NOTE entires in the segment
- while (offset < segment_header->p_filesz) {
- ELFNote note = ELFNote();
- note.Parse(segment_data, &offset);
+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.
+ if (!llvm::StringRef(note.info.n_name).startswith("NetBSD-CORE"))
+ continue;
+
+ switch (note.info.n_type) {
+ case NETBSD::NT_PROCINFO:
+ ParseNetBSDProcInfo(thread_data, note.data);
+ break;
+ case NETBSD::NT_AUXV:
+ m_auxv = note.data;
+ break;
+
+ case NETBSD::NT_AMD64_REGS:
+ if (GetArchitecture().GetMachine() == llvm::Triple::x86_64)
+ thread_data.gpregset = note.data;
+ break;
+ default:
+ thread_data.notes.push_back(note);
+ break;
+ }
+ }
+ if (thread_data.gpregset.GetByteSize() == 0) {
+ return llvm::make_error<llvm::StringError>(
+ "Could not find general purpose registers note in core file.",
+ llvm::inconvertibleErrorCode());
+ }
+ m_thread_data.push_back(thread_data);
+ return llvm::Error::success();
+}
+
+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.
+ if (!llvm::StringRef(note.info.n_name).startswith("OpenBSD"))
+ continue;
+
+ switch (note.info.n_type) {
+ case OPENBSD::NT_PROCINFO:
+ ParseOpenBSDProcInfo(thread_data, note.data);
+ break;
+ case OPENBSD::NT_AUXV:
+ m_auxv = note.data;
+ break;
+ case OPENBSD::NT_REGS:
+ thread_data.gpregset = note.data;
+ break;
+ default:
+ thread_data.notes.push_back(note);
+ break;
+ }
+ }
+ if (thread_data.gpregset.GetByteSize() == 0) {
+ return llvm::make_error<llvm::StringError>(
+ "Could not find general purpose registers note in core file.",
+ llvm::inconvertibleErrorCode());
+ }
+ m_thread_data.push_back(thread_data);
+ return llvm::Error::success();
+}
- // Beginning of new thread
- if ((note.n_type == NT_PRSTATUS && have_prstatus) ||
- (note.n_type == NT_PRPSINFO && have_prpsinfo)) {
- assert(thread_data->gpregset.GetByteSize() > 0);
+/// A description of a linux process usually contains the following NOTE
+/// entries:
+/// - NT_PRPSINFO - General process information like pid, uid, name, ...
+/// - NT_SIGINFO - Information about the signal that terminated the process
+/// - NT_AUXV - Process auxiliary vector
+/// - NT_FILE - Files mapped into memory
+///
+/// Additionally, for each thread in the process the core file will contain at
+/// least the NT_PRSTATUS note, containing the thread id and general purpose
+/// registers. It may include additional notes for other register sets (floating
+/// point and vector registers, ...). The tricky part here is that some of these
+/// notes have "CORE" in their owner fields, while other set it to "LINUX".
+llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
+ const ArchSpec &arch = GetArchitecture();
+ bool have_prstatus = false;
+ bool have_prpsinfo = false;
+ ThreadData thread_data;
+ for (const auto &note : notes) {
+ if (note.info.n_name != "CORE" && note.info.n_name != "LINUX")
+ continue;
+
+ if ((note.info.n_type == LINUX::NT_PRSTATUS && have_prstatus) ||
+ (note.info.n_type == LINUX::NT_PRPSINFO && have_prpsinfo)) {
+ assert(thread_data.gpregset.GetByteSize() > 0);
// Add the new thread to thread list
- m_thread_data.push_back(*thread_data);
- *thread_data = ThreadData();
+ m_thread_data.push_back(thread_data);
+ thread_data = ThreadData();
have_prstatus = false;
have_prpsinfo = false;
}
- size_t note_start, note_size;
- note_start = offset;
- note_size = llvm::alignTo(note.n_descsz, 4);
-
- // Store the NOTE information in the current thread
- DataExtractor note_data(segment_data, note_start, note_size);
- note_data.SetAddressByteSize(
- m_core_module_sp->GetArchitecture().GetAddressByteSize());
- if (note.n_name == "FreeBSD") {
- m_os = llvm::Triple::FreeBSD;
- switch (note.n_type) {
- case FREEBSD::NT_PRSTATUS:
- have_prstatus = true;
- ParseFreeBSDPrStatus(*thread_data, note_data, arch);
- break;
- case FREEBSD::NT_FPREGSET:
- thread_data->fpregset = note_data;
- break;
- case FREEBSD::NT_PRPSINFO:
- have_prpsinfo = true;
- break;
- case FREEBSD::NT_THRMISC:
- ParseFreeBSDThrMisc(*thread_data, note_data);
- break;
- case FREEBSD::NT_PROCSTAT_AUXV:
- // FIXME: FreeBSD sticks an int at the beginning of the note
- m_auxv = DataExtractor(segment_data, note_start + 4, note_size - 4);
- break;
- case FREEBSD::NT_PPC_VMX:
- thread_data->vregset = note_data;
- break;
- default:
- break;
- }
- } else if (note.n_name.substr(0, 11) == "NetBSD-CORE") {
- // NetBSD per-thread information is stored in notes named
- // "NetBSD-CORE@nnn" so match on the initial part of the string.
- m_os = llvm::Triple::NetBSD;
- if (note.n_type == NETBSD::NT_PROCINFO) {
- ParseNetBSDProcInfo(*thread_data, note_data);
- } else if (note.n_type == NETBSD::NT_AUXV) {
- m_auxv = DataExtractor(note_data);
- } else if (arch.GetMachine() == llvm::Triple::x86_64 &&
- note.n_type == NETBSD::NT_AMD64_REGS) {
- thread_data->gpregset = note_data;
- } else if (arch.GetMachine() == llvm::Triple::x86_64 &&
- note.n_type == NETBSD::NT_AMD64_FPREGS) {
- thread_data->fpregset = note_data;
- }
- } else if (note.n_name.substr(0, 7) == "OpenBSD") {
- // OpenBSD per-thread information is stored in notes named
- // "OpenBSD@nnn" so match on the initial part of the string.
- m_os = llvm::Triple::OpenBSD;
- switch (note.n_type) {
- case NT_OPENBSD_PROCINFO:
- ParseOpenBSDProcInfo(*thread_data, note_data);
- break;
- case NT_OPENBSD_AUXV:
- m_auxv = DataExtractor(note_data);
- break;
- case NT_OPENBSD_REGS:
- thread_data->gpregset = note_data;
- break;
- case NT_OPENBSD_FPREGS:
- thread_data->fpregset = note_data;
- break;
- }
- } else if (note.n_name == "CORE") {
- switch (note.n_type) {
- case NT_PRSTATUS:
- have_prstatus = true;
- error = prstatus.Parse(note_data, arch);
- if (error.Fail())
- return error;
- thread_data->prstatus_sig = prstatus.pr_cursig;
- thread_data->tid = prstatus.pr_pid;
- header_size = ELFLinuxPrStatus::GetSize(arch);
- len = note_data.GetByteSize() - header_size;
- thread_data->gpregset = DataExtractor(note_data, header_size, len);
- break;
- case NT_FPREGSET:
- // In a i386 core file NT_FPREGSET is present, but it's not the result
- // of the FXSAVE instruction like in 64 bit files.
- // The result from FXSAVE is in NT_PRXFPREG for i386 core files
- if (arch.GetCore() == ArchSpec::eCore_x86_64_x86_64)
- thread_data->fpregset = note_data;
- else if(arch.IsMIPS())
- thread_data->fpregset = note_data;
- break;
- case NT_PRPSINFO:
- have_prpsinfo = true;
- error = prpsinfo.Parse(note_data, arch);
- if (error.Fail())
- return error;
- thread_data->name = prpsinfo.pr_fname;
- SetID(prpsinfo.pr_pid);
- break;
- case NT_AUXV:
- m_auxv = DataExtractor(note_data);
- break;
- case NT_FILE: {
- m_nt_file_entries.clear();
- lldb::offset_t offset = 0;
- const uint64_t count = note_data.GetAddress(&offset);
- note_data.GetAddress(&offset); // Skip page size
- for (uint64_t i = 0; i < count; ++i) {
- NT_FILE_Entry entry;
- entry.start = note_data.GetAddress(&offset);
- entry.end = note_data.GetAddress(&offset);
- entry.file_ofs = note_data.GetAddress(&offset);
- m_nt_file_entries.push_back(entry);
- }
- for (uint64_t i = 0; i < count; ++i) {
- const char *path = note_data.GetCStr(&offset);
- if (path && path[0])
- m_nt_file_entries[i].path.SetCString(path);
- }
- } break;
- case NT_SIGINFO: {
- error = siginfo.Parse(note_data, arch);
- if (error.Fail())
- return error;
- thread_data->signo = siginfo.si_signo;
- } break;
- default:
- break;
+ switch (note.info.n_type) {
+ case LINUX::NT_PRSTATUS: {
+ have_prstatus = true;
+ ELFLinuxPrStatus prstatus;
+ Status status = prstatus.Parse(note.data, arch);
+ if (status.Fail())
+ return status.ToError();
+ thread_data.prstatus_sig = prstatus.pr_cursig;
+ thread_data.tid = prstatus.pr_pid;
+ uint32_t header_size = ELFLinuxPrStatus::GetSize(arch);
+ size_t len = note.data.GetByteSize() - header_size;
+ thread_data.gpregset = DataExtractor(note.data, header_size, len);
+ break;
+ }
+ case LINUX::NT_PRPSINFO: {
+ have_prpsinfo = true;
+ ELFLinuxPrPsInfo prpsinfo;
+ Status status = prpsinfo.Parse(note.data, arch);
+ if (status.Fail())
+ return status.ToError();
+ thread_data.name = prpsinfo.pr_fname;
+ SetID(prpsinfo.pr_pid);
+ break;
+ }
+ case LINUX::NT_SIGINFO: {
+ ELFLinuxSigInfo siginfo;
+ Status status = siginfo.Parse(note.data, arch);
+ if (status.Fail())
+ return status.ToError();
+ thread_data.signo = siginfo.si_signo;
+ break;
+ }
+ case LINUX::NT_FILE: {
+ m_nt_file_entries.clear();
+ lldb::offset_t offset = 0;
+ const uint64_t count = note.data.GetAddress(&offset);
+ note.data.GetAddress(&offset); // Skip page size
+ for (uint64_t i = 0; i < count; ++i) {
+ NT_FILE_Entry entry;
+ entry.start = note.data.GetAddress(&offset);
+ entry.end = note.data.GetAddress(&offset);
+ entry.file_ofs = note.data.GetAddress(&offset);
+ m_nt_file_entries.push_back(entry);
}
- } else if (note.n_name == "LINUX") {
- switch (note.n_type) {
- case NT_PRXFPREG:
- thread_data->fpregset = note_data;
+ for (uint64_t i = 0; i < count; ++i) {
+ const char *path = note.data.GetCStr(&offset);
+ if (path && path[0])
+ m_nt_file_entries[i].path.SetCString(path);
}
+ break;
+ }
+ case LINUX::NT_AUXV:
+ m_auxv = note.data;
+ break;
+ default:
+ thread_data.notes.push_back(note);
+ break;
}
-
- offset += note_size;
}
// Add last entry in the note section
- if (thread_data && thread_data->gpregset.GetByteSize() > 0) {
- m_thread_data.push_back(*thread_data);
- }
+ if (have_prstatus)
+ m_thread_data.push_back(thread_data);
+ return llvm::Error::success();
+}
- return error;
+/// Parse Thread context from PT_NOTE segment and store it in the thread list
+/// A note segment consists of one or more NOTE entries, but their types and
+/// meaning differ depending on the OS.
+llvm::Error ProcessElfCore::ParseThreadContextsFromNoteSegment(
+ const elf::ELFProgramHeader *segment_header, DataExtractor segment_data) {
+ assert(segment_header && segment_header->p_type == llvm::ELF::PT_NOTE);
+
+ auto notes_or_error = parseSegment(segment_data);
+ if(!notes_or_error)
+ return notes_or_error.takeError();
+ switch (GetArchitecture().GetTriple().getOS()) {
+ case llvm::Triple::FreeBSD:
+ return parseFreeBSDNotes(*notes_or_error);
+ case llvm::Triple::Linux:
+ return parseLinuxNotes(*notes_or_error);
+ case llvm::Triple::NetBSD:
+ return parseNetBSDNotes(*notes_or_error);
+ case llvm::Triple::OpenBSD:
+ return parseOpenBSDNotes(*notes_or_error);
+ default:
+ return llvm::make_error<llvm::StringError>(
+ "Don't know how to parse core file. Unsupported OS.",
+ llvm::inconvertibleErrorCode());
+ }
}
uint32_t ProcessElfCore::GetNumThreadContexts() {
@@ -724,15 +743,18 @@ uint32_t ProcessElfCore::GetNumThreadContexts() {
}
ArchSpec ProcessElfCore::GetArchitecture() {
- ObjectFileELF *core_file =
- (ObjectFileELF *)(m_core_module_sp->GetObjectFile());
ArchSpec arch;
- core_file->GetArchitecture(arch);
+ m_core_module_sp->GetObjectFile()->GetArchitecture(arch);
ArchSpec target_arch = GetTarget().GetArchitecture();
-
- if (target_arch.IsMIPS())
+ 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.
+ if (target_arch.IsMIPS()) {
return target_arch;
+ }
return arch;
}
diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.h b/source/Plugins/Process/elf-core/ProcessElfCore.h
index dbf7f926f8551..325c0152e0287 100644
--- a/source/Plugins/Process/elf-core/ProcessElfCore.h
+++ b/source/Plugins/Process/elf-core/ProcessElfCore.h
@@ -29,6 +29,7 @@
#include "lldb/Utility/Status.h"
#include "Plugins/ObjectFile/ELF/ELFHeader.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
struct ThreadData;
@@ -84,11 +85,21 @@ public:
void RefreshStateAfterStop() override;
+ lldb_private::Status WillResume() override {
+ lldb_private::Status error;
+ error.SetErrorStringWithFormat(
+ "error: %s does not support resuming processes",
+ GetPluginName().GetCString());
+ return error;
+ }
+
//------------------------------------------------------------------
// Process Queries
//------------------------------------------------------------------
bool IsAlive() override;
+ bool WarnBeforeDetach() const override { return false; }
+
//------------------------------------------------------------------
// Process Memory
//------------------------------------------------------------------
@@ -139,10 +150,8 @@ private:
std::string m_dyld_plugin_name;
DISALLOW_COPY_AND_ASSIGN(ProcessElfCore);
- llvm::Triple::OSType m_os;
-
// True if m_thread_contexts contains valid entries
- bool m_thread_data_valid;
+ bool m_thread_data_valid = false;
// Contain thread data read from NOTE segments
std::vector<ThreadData> m_thread_data;
@@ -160,7 +169,7 @@ private:
std::vector<NT_FILE_Entry> m_nt_file_entries;
// Parse thread(s) data structures(prstatus, prpsinfo) from given NOTE segment
- lldb_private::Status ParseThreadContextsFromNoteSegment(
+ llvm::Error ParseThreadContextsFromNoteSegment(
const elf::ELFProgramHeader *segment_header,
lldb_private::DataExtractor segment_data);
@@ -170,6 +179,13 @@ private:
// Parse a contiguous address range of the process from LOAD segment
lldb::addr_t
AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader *header);
+
+ llvm::Expected<std::vector<lldb_private::CoreNote>>
+ parseSegment(const lldb_private::DataExtractor &segment);
+ llvm::Error parseFreeBSDNotes(llvm::ArrayRef<lldb_private::CoreNote> notes);
+ llvm::Error parseNetBSDNotes(llvm::ArrayRef<lldb_private::CoreNote> notes);
+ llvm::Error parseOpenBSDNotes(llvm::ArrayRef<lldb_private::CoreNote> notes);
+ llvm::Error parseLinuxNotes(llvm::ArrayRef<lldb_private::CoreNote> notes);
};
#endif // liblldb_ProcessElfCore_h_
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
index 81d88e69b97ff..0d683153d9ed0 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
@@ -16,7 +16,7 @@ using namespace lldb_private;
RegisterContextCorePOSIX_arm::RegisterContextCorePOSIX_arm(
Thread &thread, RegisterInfoInterface *register_info,
- const DataExtractor &gpregset, const DataExtractor &fpregset)
+ const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
: RegisterContextPOSIX_arm(thread, 0, register_info) {
m_gpr_buffer.reset(
new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
index e095eac5eaf81..a98d64caee17a 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
@@ -10,11 +10,8 @@
#ifndef liblldb_RegisterContextCorePOSIX_arm_h_
#define liblldb_RegisterContextCorePOSIX_arm_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "Plugins/Process/Utility/RegisterContextPOSIX_arm.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
@@ -24,7 +21,7 @@ public:
lldb_private::Thread &thread,
lldb_private::RegisterInfoInterface *register_info,
const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset);
+ llvm::ArrayRef<lldb_private::CoreNote> notes);
~RegisterContextCorePOSIX_arm() override;
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
index 41c02bf94c377..919f8901d39a3 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
#include "RegisterContextPOSIXCore_arm64.h"
-
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
@@ -16,7 +16,7 @@ using namespace lldb_private;
RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(
Thread &thread, RegisterInfoInterface *register_info,
- const DataExtractor &gpregset, const DataExtractor &fpregset)
+ const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
: RegisterContextPOSIX_arm64(thread, 0, register_info) {
m_gpr_buffer.reset(
new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
index 3a2bbdb0a2ebf..c519b15571893 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
@@ -10,11 +10,8 @@
#ifndef liblldb_RegisterContextCorePOSIX_arm64_h_
#define liblldb_RegisterContextCorePOSIX_arm64_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
@@ -24,7 +21,7 @@ public:
lldb_private::Thread &thread,
lldb_private::RegisterInfoInterface *register_info,
const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset);
+ llvm::ArrayRef<lldb_private::CoreNote> notes);
~RegisterContextCorePOSIX_arm64() override;
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
index 7549cf074be7f..e252b5a35e9c8 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
@@ -16,12 +16,15 @@ using namespace lldb_private;
RegisterContextCorePOSIX_mips64::RegisterContextCorePOSIX_mips64(
Thread &thread, RegisterInfoInterface *register_info,
- const DataExtractor &gpregset, const DataExtractor &fpregset)
+ const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
: RegisterContextPOSIX_mips64(thread, 0, register_info) {
m_gpr_buffer.reset(
new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
m_gpr.SetData(m_gpr_buffer);
m_gpr.SetByteOrder(gpregset.GetByteOrder());
+
+ DataExtractor fpregset = getRegset(
+ notes, register_info->GetTargetArchitecture().GetTriple(), FPR_Desc);
m_fpr_buffer.reset(
new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
m_fpr.SetData(m_fpr_buffer);
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h
index 2cb527a8de7c5..cf1d8a5bc2d11 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h
@@ -10,11 +10,8 @@
#ifndef liblldb_RegisterContextCorePOSIX_mips64_h_
#define liblldb_RegisterContextCorePOSIX_mips64_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
@@ -24,7 +21,7 @@ public:
lldb_private::Thread &thread,
lldb_private::RegisterInfoInterface *register_info,
const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset);
+ llvm::ArrayRef<lldb_private::CoreNote> notes);
~RegisterContextCorePOSIX_mips64() override;
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
index 62f6413722f73..8670e341a2777 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
@@ -17,17 +17,21 @@ using namespace lldb_private;
RegisterContextCorePOSIX_powerpc::RegisterContextCorePOSIX_powerpc(
Thread &thread, RegisterInfoInterface *register_info,
- const DataExtractor &gpregset, const DataExtractor &fpregset,
- const DataExtractor &vregset)
+ const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
: RegisterContextPOSIX_powerpc(thread, 0, register_info) {
m_gpr_buffer.reset(
new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
m_gpr.SetData(m_gpr_buffer);
m_gpr.SetByteOrder(gpregset.GetByteOrder());
+
+ ArchSpec arch = register_info->GetTargetArchitecture();
+ DataExtractor fpregset = getRegset(notes, arch.GetTriple(), FPR_Desc);
m_fpr_buffer.reset(
new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
m_fpr.SetData(m_fpr_buffer);
m_fpr.SetByteOrder(fpregset.GetByteOrder());
+
+ DataExtractor vregset = getRegset(notes, arch.GetTriple(), PPC_VMX_Desc);
m_vec_buffer.reset(
new DataBufferHeap(vregset.GetDataStart(), vregset.GetByteSize()));
m_vec.SetData(m_vec_buffer);
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h
index aaa95e5d2397f..c352ab5912ff0 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h
@@ -10,11 +10,8 @@
#ifndef liblldb_RegisterContextCorePOSIX_powerpc_h_
#define liblldb_RegisterContextCorePOSIX_powerpc_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
#include "lldb/Utility/DataExtractor.h"
class RegisterContextCorePOSIX_powerpc : public RegisterContextPOSIX_powerpc {
@@ -23,8 +20,7 @@ public:
lldb_private::Thread &thread,
lldb_private::RegisterInfoInterface *register_info,
const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset,
- const lldb_private::DataExtractor &vregset);
+ llvm::ArrayRef<lldb_private::CoreNote> notes);
~RegisterContextCorePOSIX_powerpc() override;
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp
new file mode 100644
index 0000000000000..2237e72353acf
--- /dev/null
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp
@@ -0,0 +1,132 @@
+//===-- RegisterContextPOSIXCore_ppc64le.cpp --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RegisterContextPOSIXCore_ppc64le.h"
+
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/DataBufferHeap.h"
+
+#include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
+
+using namespace lldb_private;
+
+RegisterContextCorePOSIX_ppc64le::RegisterContextCorePOSIX_ppc64le(
+ Thread &thread, RegisterInfoInterface *register_info,
+ const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
+ : RegisterContextPOSIX_ppc64le(thread, 0, register_info) {
+ m_gpr_buffer.reset(
+ new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
+ m_gpr.SetData(m_gpr_buffer);
+ m_gpr.SetByteOrder(gpregset.GetByteOrder());
+
+ ArchSpec arch = register_info->GetTargetArchitecture();
+ DataExtractor fpregset = getRegset(notes, arch.GetTriple(), FPR_Desc);
+ m_fpr_buffer.reset(
+ new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
+ m_fpr.SetData(m_fpr_buffer);
+ m_fpr.SetByteOrder(fpregset.GetByteOrder());
+
+ DataExtractor vmxregset = getRegset(notes, arch.GetTriple(), PPC_VMX_Desc);
+ m_vmx_buffer.reset(
+ new DataBufferHeap(vmxregset.GetDataStart(), vmxregset.GetByteSize()));
+ m_vmx.SetData(m_vmx_buffer);
+ m_vmx.SetByteOrder(vmxregset.GetByteOrder());
+
+ DataExtractor vsxregset = getRegset(notes, arch.GetTriple(), PPC_VSX_Desc);
+ m_vsx_buffer.reset(
+ new DataBufferHeap(vsxregset.GetDataStart(), vsxregset.GetByteSize()));
+ m_vsx.SetData(m_vsx_buffer);
+ m_vsx.SetByteOrder(vsxregset.GetByteOrder());
+}
+
+size_t RegisterContextCorePOSIX_ppc64le::GetFPRSize() const {
+ return k_num_fpr_registers_ppc64le * sizeof(uint64_t);
+}
+
+size_t RegisterContextCorePOSIX_ppc64le::GetVMXSize() const {
+ return (k_num_vmx_registers_ppc64le - 1) * sizeof(uint64_t) * 2 +
+ sizeof(uint32_t);
+}
+
+size_t RegisterContextCorePOSIX_ppc64le::GetVSXSize() const {
+ return k_num_vsx_registers_ppc64le * sizeof(uint64_t) * 2;
+}
+
+bool RegisterContextCorePOSIX_ppc64le::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &value) {
+ lldb::offset_t offset = reg_info->byte_offset;
+
+ if (IsFPR(reg_info->kinds[lldb::eRegisterKindLLDB])) {
+ uint64_t v;
+ offset -= GetGPRSize();
+ offset = m_fpr.CopyData(offset, reg_info->byte_size, &v);
+
+ if (offset == reg_info->byte_size) {
+ value.SetBytes(&v, reg_info->byte_size, m_fpr.GetByteOrder());
+ return true;
+ }
+ } else if (IsVMX(reg_info->kinds[lldb::eRegisterKindLLDB])) {
+ uint32_t v[4];
+ offset -= GetGPRSize() + GetFPRSize();
+ offset = m_vmx.CopyData(offset, reg_info->byte_size, &v);
+
+ if (offset == reg_info->byte_size) {
+ value.SetBytes(v, reg_info->byte_size, m_vmx.GetByteOrder());
+ return true;
+ }
+ } else if (IsVSX(reg_info->kinds[lldb::eRegisterKindLLDB])) {
+ uint32_t v[4];
+ lldb::offset_t tmp_offset;
+ offset -= GetGPRSize() + GetFPRSize() + GetVMXSize();
+
+ if (offset < GetVSXSize() / 2) {
+ tmp_offset = m_vsx.CopyData(offset / 2, reg_info->byte_size / 2, &v);
+
+ if (tmp_offset != reg_info->byte_size / 2) {
+ return false;
+ }
+
+ uint8_t *dst = (uint8_t *)&v + sizeof(uint64_t);
+ tmp_offset = m_fpr.CopyData(offset / 2, reg_info->byte_size / 2, dst);
+
+ if (tmp_offset != reg_info->byte_size / 2) {
+ return false;
+ }
+
+ value.SetBytes(&v, reg_info->byte_size, m_vsx.GetByteOrder());
+ return true;
+ } else {
+ offset =
+ m_vmx.CopyData(offset - GetVSXSize() / 2, reg_info->byte_size, &v);
+ if (offset == reg_info->byte_size) {
+ value.SetBytes(v, reg_info->byte_size, m_vmx.GetByteOrder());
+ return true;
+ }
+ }
+ } else {
+ uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
+
+ if (offset == reg_info->byte_offset + reg_info->byte_size) {
+ if (reg_info->byte_size < sizeof(v))
+ value = (uint32_t)v;
+ else
+ value = v;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool RegisterContextCorePOSIX_ppc64le::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ return false;
+}
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h
new file mode 100644
index 0000000000000..c860781d60be9
--- /dev/null
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h
@@ -0,0 +1,49 @@
+//===-- RegisterContextPOSIXCore_ppc64le.h ----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_RegisterContextCorePOSIX_ppc64le_h_
+#define liblldb_RegisterContextCorePOSIX_ppc64le_h_
+
+#include "Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
+#include "lldb/Utility/DataExtractor.h"
+
+class RegisterContextCorePOSIX_ppc64le : public RegisterContextPOSIX_ppc64le {
+public:
+ RegisterContextCorePOSIX_ppc64le(
+ lldb_private::Thread &thread,
+ lldb_private::RegisterInfoInterface *register_info,
+ const lldb_private::DataExtractor &gpregset,
+ llvm::ArrayRef<lldb_private::CoreNote> notes);
+
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
+
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
+
+protected:
+ size_t GetFPRSize() const;
+
+ size_t GetVMXSize() const;
+
+ size_t GetVSXSize() const;
+
+private:
+ lldb::DataBufferSP m_gpr_buffer;
+ lldb::DataBufferSP m_fpr_buffer;
+ lldb::DataBufferSP m_vmx_buffer;
+ lldb::DataBufferSP m_vsx_buffer;
+ lldb_private::DataExtractor m_gpr;
+ lldb_private::DataExtractor m_fpr;
+ lldb_private::DataExtractor m_vmx;
+ lldb_private::DataExtractor m_vsx;
+};
+
+#endif // liblldb_RegisterContextCorePOSIX_ppc64le_h_
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
index b3530a8d6a42f..f0edbf1ea8548 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
@@ -17,13 +17,15 @@ using namespace lldb_private;
RegisterContextCorePOSIX_s390x::RegisterContextCorePOSIX_s390x(
Thread &thread, RegisterInfoInterface *register_info,
- const DataExtractor &gpregset, const DataExtractor &fpregset)
+ const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
: RegisterContextPOSIX_s390x(thread, 0, register_info) {
m_gpr_buffer.reset(
new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
m_gpr.SetData(m_gpr_buffer);
m_gpr.SetByteOrder(gpregset.GetByteOrder());
+ DataExtractor fpregset = getRegset(
+ notes, register_info->GetTargetArchitecture().GetTriple(), FPR_Desc);
m_fpr_buffer.reset(
new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
m_fpr.SetData(m_fpr_buffer);
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h
index 2b4ae10a87bd9..0df136372bdda 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h
@@ -10,11 +10,8 @@
#ifndef liblldb_RegisterContextCorePOSIX_s390x_h_
#define liblldb_RegisterContextCorePOSIX_s390x_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "Plugins/Process/Utility/RegisterContextPOSIX_s390x.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
#include "lldb/Utility/DataExtractor.h"
class RegisterContextCorePOSIX_s390x : public RegisterContextPOSIX_s390x {
@@ -23,7 +20,7 @@ public:
lldb_private::Thread &thread,
lldb_private::RegisterInfoInterface *register_info,
const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset);
+ llvm::ArrayRef<lldb_private::CoreNote> notes);
~RegisterContextCorePOSIX_s390x() override;
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
index 5766923186d19..a5c7ffda1da56 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
@@ -16,7 +16,7 @@ using namespace lldb_private;
RegisterContextCorePOSIX_x86_64::RegisterContextCorePOSIX_x86_64(
Thread &thread, RegisterInfoInterface *register_info,
- const DataExtractor &gpregset, const DataExtractor &fpregset)
+ const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
: RegisterContextPOSIX_x86(thread, 0, register_info) {
size_t size, len;
@@ -27,6 +27,8 @@ RegisterContextCorePOSIX_x86_64::RegisterContextCorePOSIX_x86_64(
if (len != size)
m_gpregset.reset();
+ DataExtractor fpregset = getRegset(
+ notes, register_info->GetTargetArchitecture().GetTriple(), FPR_Desc);
size = sizeof(FXSAVE);
m_fpregset.reset(new uint8_t[size]);
len =
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h
index 8340368f8c3c9..509624174a89e 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h
@@ -10,11 +10,8 @@
#ifndef liblldb_RegisterContextCorePOSIX_x86_64_h_
#define liblldb_RegisterContextCorePOSIX_x86_64_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "Plugins/Process/Utility/RegisterContextPOSIX_x86.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
class RegisterContextCorePOSIX_x86_64 : public RegisterContextPOSIX_x86 {
public:
@@ -22,7 +19,7 @@ public:
lldb_private::Thread &thread,
lldb_private::RegisterInfoInterface *register_info,
const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset);
+ llvm::ArrayRef<lldb_private::CoreNote> notes);
bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
lldb_private::RegisterValue &value) override;
diff --git a/source/Plugins/Process/elf-core/RegisterUtilities.cpp b/source/Plugins/Process/elf-core/RegisterUtilities.cpp
new file mode 100644
index 0000000000000..3837abadd0f6c
--- /dev/null
+++ b/source/Plugins/Process/elf-core/RegisterUtilities.cpp
@@ -0,0 +1,39 @@
+//===-- RegisterUtilities.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/Process/elf-core/RegisterUtilities.h"
+#include "llvm/ADT/STLExtras.h"
+
+using namespace lldb_private;
+
+static llvm::Optional<uint32_t>
+getNoteType(const llvm::Triple &Triple,
+ llvm::ArrayRef<RegsetDesc> RegsetDescs) {
+ for (const auto &Entry : RegsetDescs) {
+ if (Entry.OS != Triple.getOS())
+ continue;
+ if (Entry.Arch != llvm::Triple::UnknownArch &&
+ Entry.Arch != Triple.getArch())
+ continue;
+ return Entry.Note;
+ }
+ return llvm::None;
+}
+
+DataExtractor lldb_private::getRegset(llvm::ArrayRef<CoreNote> Notes,
+ const llvm::Triple &Triple,
+ llvm::ArrayRef<RegsetDesc> RegsetDescs) {
+ auto TypeOr = getNoteType(Triple, RegsetDescs);
+ if (!TypeOr)
+ return DataExtractor();
+ uint32_t Type = *TypeOr;
+ auto Iter = llvm::find_if(
+ Notes, [Type](const CoreNote &Note) { return Note.info.n_type == Type; });
+ return Iter == Notes.end() ? DataExtractor() : Iter->data;
+}
diff --git a/source/Plugins/Process/elf-core/RegisterUtilities.h b/source/Plugins/Process/elf-core/RegisterUtilities.h
new file mode 100644
index 0000000000000..9170d94c04b6d
--- /dev/null
+++ b/source/Plugins/Process/elf-core/RegisterUtilities.h
@@ -0,0 +1,110 @@
+//===-- RegisterUtilities.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_REGISTERUTILITIES_H
+#define LLDB_REGISTERUTILITIES_H
+
+#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
+#include "lldb/Utility/DataExtractor.h"
+
+namespace lldb_private {
+/// Core files PT_NOTE segment descriptor types
+
+namespace FREEBSD {
+enum {
+ NT_PRSTATUS = 1,
+ NT_FPREGSET,
+ NT_PRPSINFO,
+ NT_THRMISC = 7,
+ NT_PROCSTAT_AUXV = 16,
+ NT_PPC_VMX = 0x100
+};
+}
+
+namespace NETBSD {
+enum { NT_PROCINFO = 1, NT_AUXV, NT_AMD64_REGS = 33, NT_AMD64_FPREGS = 35 };
+}
+
+namespace OPENBSD {
+enum {
+ NT_PROCINFO = 10,
+ NT_AUXV = 11,
+ NT_REGS = 20,
+ NT_FPREGS = 21,
+};
+}
+
+namespace LINUX {
+enum {
+ NT_PRSTATUS = 1,
+ NT_FPREGSET,
+ NT_PRPSINFO,
+ NT_TASKSTRUCT,
+ NT_PLATFORM,
+ NT_AUXV,
+ NT_FILE = 0x46494c45,
+ NT_SIGINFO = 0x53494749,
+ NT_PPC_VMX = 0x100,
+ NT_PPC_VSX = 0x102,
+ NT_PRXFPREG = 0x46e62b7f,
+};
+}
+
+struct CoreNote {
+ ELFNote info;
+ DataExtractor data;
+};
+
+// A structure describing how to find a register set in a core file from a given
+// OS.
+struct RegsetDesc {
+ // OS to which this entry applies to. Must not be UnknownOS.
+ llvm::Triple::OSType OS;
+
+ // Architecture to which this entry applies to. Can be UnknownArch, in which
+ // case it applies to all architectures of a given OS.
+ llvm::Triple::ArchType Arch;
+
+ // The note type under which the register set can be found.
+ uint32_t Note;
+};
+
+// Returns the register set in Notes which corresponds to the specified Triple
+// according to the list of register set descriptions in RegsetDescs. The list
+// is scanned linearly, so you can use a more specific entry (e.g. linux-i386)
+// to override a more general entry (e.g. general linux), as long as you place
+// it earlier in the list. If a register set is not found, it returns an empty
+// DataExtractor.
+DataExtractor getRegset(llvm::ArrayRef<CoreNote> Notes,
+ const llvm::Triple &Triple,
+ llvm::ArrayRef<RegsetDesc> RegsetDescs);
+
+constexpr RegsetDesc FPR_Desc[] = {
+ {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, FREEBSD::NT_FPREGSET},
+ // In a i386 core file NT_FPREGSET is present, but it's not the result
+ // of the FXSAVE instruction like in 64 bit files.
+ // The result from FXSAVE is in NT_PRXFPREG for i386 core files
+ {llvm::Triple::Linux, llvm::Triple::x86, LINUX::NT_PRXFPREG},
+ {llvm::Triple::Linux, llvm::Triple::UnknownArch, LINUX::NT_FPREGSET},
+ {llvm::Triple::NetBSD, llvm::Triple::x86_64, NETBSD::NT_AMD64_FPREGS},
+ {llvm::Triple::OpenBSD, llvm::Triple::UnknownArch, OPENBSD::NT_FPREGS},
+};
+
+constexpr RegsetDesc PPC_VMX_Desc[] = {
+ {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, FREEBSD::NT_PPC_VMX},
+ {llvm::Triple::Linux, llvm::Triple::UnknownArch, LINUX::NT_PPC_VMX},
+};
+
+constexpr RegsetDesc PPC_VSX_Desc[] = {
+ {llvm::Triple::Linux, llvm::Triple::UnknownArch, LINUX::NT_PPC_VSX},
+};
+
+} // namespace lldb_private
+
+#endif // #ifndef LLDB_REGISTERUTILITIES_H
diff --git a/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/source/Plugins/Process/elf-core/ThreadElfCore.cpp
index 096c20363c78b..10c1ed288b2c5 100644
--- a/source/Plugins/Process/elf-core/ThreadElfCore.cpp
+++ b/source/Plugins/Process/elf-core/ThreadElfCore.cpp
@@ -18,9 +18,9 @@
#include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_mips.h"
#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_mips.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h"
#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"
#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
#include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h"
@@ -28,11 +28,13 @@
#include "Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h"
#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h"
#include "ProcessElfCore.h"
#include "RegisterContextPOSIXCore_arm.h"
#include "RegisterContextPOSIXCore_arm64.h"
#include "RegisterContextPOSIXCore_mips64.h"
#include "RegisterContextPOSIXCore_powerpc.h"
+#include "RegisterContextPOSIXCore_ppc64le.h"
#include "RegisterContextPOSIXCore_s390x.h"
#include "RegisterContextPOSIXCore_x86_64.h"
#include "ThreadElfCore.h"
@@ -45,8 +47,7 @@ using namespace lldb_private;
//----------------------------------------------------------------------
ThreadElfCore::ThreadElfCore(Process &process, const ThreadData &td)
: Thread(process, td.tid), m_thread_name(td.name), m_thread_reg_ctx_sp(),
- m_signo(td.signo), m_gpregset_data(td.gpregset),
- m_fpregset_data(td.fpregset), m_vregset_data(td.vregset) {}
+ m_signo(td.signo), m_gpregset_data(td.gpregset), m_notes(td.notes) {}
ThreadElfCore::~ThreadElfCore() { DestroyThread(); }
@@ -142,6 +143,9 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
case llvm::Triple::mips64:
reg_interface = new RegisterContextLinux_mips64(arch);
break;
+ case llvm::Triple::ppc64le:
+ reg_interface = new RegisterInfoPOSIX_ppc64le(arch);
+ break;
case llvm::Triple::systemz:
reg_interface = new RegisterContextLinux_s390x(arch);
break;
@@ -191,36 +195,39 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
switch (arch.GetMachine()) {
case llvm::Triple::aarch64:
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm64(
- *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ *this, reg_interface, m_gpregset_data, m_notes));
break;
case llvm::Triple::arm:
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm(
- *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ *this, reg_interface, m_gpregset_data, m_notes));
break;
case llvm::Triple::mipsel:
case llvm::Triple::mips:
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64(
- *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ *this, reg_interface, m_gpregset_data, m_notes));
break;
case llvm::Triple::mips64:
case llvm::Triple::mips64el:
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64(
- *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ *this, reg_interface, m_gpregset_data, m_notes));
break;
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc(
- *this, reg_interface, m_gpregset_data, m_fpregset_data,
- m_vregset_data));
+ *this, reg_interface, m_gpregset_data, m_notes));
+ break;
+ case llvm::Triple::ppc64le:
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_ppc64le(
+ *this, reg_interface, m_gpregset_data, m_notes));
break;
case llvm::Triple::systemz:
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_s390x(
- *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ *this, reg_interface, m_gpregset_data, m_notes));
break;
case llvm::Triple::x86:
case llvm::Triple::x86_64:
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64(
- *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ *this, reg_interface, m_gpregset_data, m_notes));
break;
default:
break;
@@ -249,7 +256,7 @@ ELFLinuxPrStatus::ELFLinuxPrStatus() {
memset(this, 0, sizeof(ELFLinuxPrStatus));
}
-size_t ELFLinuxPrStatus::GetSize(lldb_private::ArchSpec &arch) {
+size_t ELFLinuxPrStatus::GetSize(const lldb_private::ArchSpec &arch) {
constexpr size_t mips_linux_pr_status_size_o32 = 96;
constexpr size_t mips_linux_pr_status_size_n32 = 72;
if (arch.IsMIPS()) {
@@ -265,6 +272,7 @@ size_t ELFLinuxPrStatus::GetSize(lldb_private::ArchSpec &arch) {
switch (arch.GetCore()) {
case lldb_private::ArchSpec::eCore_s390x_generic:
case lldb_private::ArchSpec::eCore_x86_64_x86_64:
+ case lldb_private::ArchSpec::eCore_ppc64le_generic:
return sizeof(ELFLinuxPrStatus);
case lldb_private::ArchSpec::eCore_x86_32_i386:
case lldb_private::ArchSpec::eCore_x86_32_i486:
@@ -274,7 +282,8 @@ size_t ELFLinuxPrStatus::GetSize(lldb_private::ArchSpec &arch) {
}
}
-Status ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch) {
+Status ELFLinuxPrStatus::Parse(const DataExtractor &data,
+ const ArchSpec &arch) {
Status error;
if (GetSize(arch) > data.GetByteSize()) {
error.SetErrorStringWithFormat(
@@ -323,7 +332,7 @@ ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() {
memset(this, 0, sizeof(ELFLinuxPrPsInfo));
}
-size_t ELFLinuxPrPsInfo::GetSize(lldb_private::ArchSpec &arch) {
+size_t ELFLinuxPrPsInfo::GetSize(const lldb_private::ArchSpec &arch) {
constexpr size_t mips_linux_pr_psinfo_size_o32_n32 = 128;
if (arch.IsMIPS()) {
uint8_t address_byte_size = arch.GetAddressByteSize();
@@ -344,7 +353,8 @@ size_t ELFLinuxPrPsInfo::GetSize(lldb_private::ArchSpec &arch) {
}
}
-Status ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) {
+Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data,
+ const ArchSpec &arch) {
Status error;
ByteOrder byteorder = data.GetByteOrder();
if (GetSize(arch) > data.GetByteSize()) {
@@ -413,7 +423,7 @@ size_t ELFLinuxSigInfo::GetSize(const lldb_private::ArchSpec &arch) {
}
}
-Status ELFLinuxSigInfo::Parse(DataExtractor &data, const ArchSpec &arch) {
+Status ELFLinuxSigInfo::Parse(const DataExtractor &data, const ArchSpec &arch) {
Status error;
if (GetSize(arch) > data.GetByteSize()) {
error.SetErrorStringWithFormat(
diff --git a/source/Plugins/Process/elf-core/ThreadElfCore.h b/source/Plugins/Process/elf-core/ThreadElfCore.h
index 5218754137158..335f698dbb248 100644
--- a/source/Plugins/Process/elf-core/ThreadElfCore.h
+++ b/source/Plugins/Process/elf-core/ThreadElfCore.h
@@ -10,14 +10,11 @@
#ifndef liblldb_ThreadElfCore_h_
#define liblldb_ThreadElfCore_h_
-// C Includes
-// C++ Includes
-#include <string>
-
-// Other libraries and framework includes
-// Project includes
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataExtractor.h"
+#include "llvm/ADT/DenseMap.h"
+#include <string>
struct compat_timeval {
alignas(8) uint64_t tv_sec;
@@ -57,15 +54,15 @@ struct ELFLinuxPrStatus {
ELFLinuxPrStatus();
- lldb_private::Status Parse(lldb_private::DataExtractor &data,
- lldb_private::ArchSpec &arch);
+ lldb_private::Status Parse(const lldb_private::DataExtractor &data,
+ const lldb_private::ArchSpec &arch);
// Return the bytesize of the structure
// 64 bit - just sizeof
// 32 bit - hardcoded because we are reusing the struct, but some of the
// members are smaller -
// so the layout is not the same
- static size_t GetSize(lldb_private::ArchSpec &arch);
+ static size_t GetSize(const lldb_private::ArchSpec &arch);
};
static_assert(sizeof(ELFLinuxPrStatus) == 112,
@@ -78,7 +75,7 @@ struct ELFLinuxSigInfo {
ELFLinuxSigInfo();
- lldb_private::Status Parse(lldb_private::DataExtractor &data,
+ lldb_private::Status Parse(const lldb_private::DataExtractor &data,
const lldb_private::ArchSpec &arch);
// Return the bytesize of the structure
@@ -113,15 +110,15 @@ struct ELFLinuxPrPsInfo {
ELFLinuxPrPsInfo();
- lldb_private::Status Parse(lldb_private::DataExtractor &data,
- lldb_private::ArchSpec &arch);
+ lldb_private::Status Parse(const lldb_private::DataExtractor &data,
+ const lldb_private::ArchSpec &arch);
// Return the bytesize of the structure
// 64 bit - just sizeof
// 32 bit - hardcoded because we are reusing the struct, but some of the
// members are smaller -
// so the layout is not the same
- static size_t GetSize(lldb_private::ArchSpec &arch);
+ static size_t GetSize(const lldb_private::ArchSpec &arch);
};
static_assert(sizeof(ELFLinuxPrPsInfo) == 136,
@@ -129,8 +126,7 @@ static_assert(sizeof(ELFLinuxPrPsInfo) == 136,
struct ThreadData {
lldb_private::DataExtractor gpregset;
- lldb_private::DataExtractor fpregset;
- lldb_private::DataExtractor vregset;
+ std::vector<lldb_private::CoreNote> notes;
lldb::tid_t tid;
int signo = 0;
int prstatus_sig = 0;
@@ -177,8 +173,7 @@ protected:
int m_signo;
lldb_private::DataExtractor m_gpregset_data;
- lldb_private::DataExtractor m_fpregset_data;
- lldb_private::DataExtractor m_vregset_data;
+ std::vector<lldb_private::CoreNote> m_notes;
bool CalculateStopInfo() override;
};
diff --git a/source/Plugins/Process/gdb-remote/CMakeLists.txt b/source/Plugins/Process/gdb-remote/CMakeLists.txt
index 5e51feef1d3f8..7ae25f83c5f8a 100644
--- a/source/Plugins/Process/gdb-remote/CMakeLists.txt
+++ b/source/Plugins/Process/gdb-remote/CMakeLists.txt
@@ -7,6 +7,10 @@ set(LLDB_PLUGINS
lldbPluginPlatformMacOSX
)
+if(HAVE_LIBCOMPRESSION)
+ set(LIBCOMPRESSION compression)
+endif()
+
add_lldb_library(lldbPluginProcessGDBRemote PLUGIN
GDBRemoteClientBase.cpp
GDBRemoteCommunication.cpp
@@ -30,6 +34,7 @@ add_lldb_library(lldbPluginProcessGDBRemote PLUGIN
lldbTarget
lldbUtility
${LLDB_PLUGINS}
+ ${LIBCOMPRESSION}
LINK_COMPONENTS
Support
)
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 0c4df7e3f3065..949cf19db658a 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -600,10 +600,9 @@ bool GDBRemoteCommunication::DecompressPacket() {
#if defined(HAVE_LIBCOMPRESSION)
// libcompression is weak linked so check that compression_decode_buffer() is
// available
- if (compression_decode_buffer != NULL &&
- (m_compression_type == CompressionType::ZlibDeflate ||
- m_compression_type == CompressionType::LZFSE ||
- m_compression_type == CompressionType::LZ4)) {
+ if (m_compression_type == CompressionType::ZlibDeflate ||
+ m_compression_type == CompressionType::LZFSE ||
+ m_compression_type == CompressionType::LZ4) {
compression_algorithm compression_type;
if (m_compression_type == CompressionType::LZFSE)
compression_type = COMPRESSION_LZFSE;
@@ -815,7 +814,8 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
// checksum
if (m_bytes[0] == '$' && total_length > 4) {
for (size_t i = 0; !binary && i < total_length; ++i) {
- if (isprint(m_bytes[i]) == 0 && isspace(m_bytes[i]) == 0) {
+ unsigned char c = m_bytes[i];
+ if (isprint(c) == 0 && isspace(c) == 0) {
binary = true;
}
}
@@ -1375,3 +1375,39 @@ void GDBRemoteCommunication::AppendBytesToCache(const uint8_t *bytes,
}
}
}
+
+void llvm::format_provider<GDBRemoteCommunication::PacketResult>::format(
+ const GDBRemoteCommunication::PacketResult &result, raw_ostream &Stream,
+ StringRef Style) {
+ using PacketResult = GDBRemoteCommunication::PacketResult;
+
+ switch (result) {
+ case PacketResult::Success:
+ Stream << "Success";
+ break;
+ case PacketResult::ErrorSendFailed:
+ Stream << "ErrorSendFailed";
+ break;
+ case PacketResult::ErrorSendAck:
+ Stream << "ErrorSendAck";
+ break;
+ case PacketResult::ErrorReplyFailed:
+ Stream << "ErrorReplyFailed";
+ break;
+ case PacketResult::ErrorReplyTimeout:
+ Stream << "ErrorReplyTimeout";
+ break;
+ case PacketResult::ErrorReplyInvalid:
+ Stream << "ErrorReplyInvalid";
+ break;
+ case PacketResult::ErrorReplyAck:
+ Stream << "ErrorReplyAck";
+ break;
+ case PacketResult::ErrorDisconnected:
+ Stream << "ErrorDisconnected";
+ break;
+ case PacketResult::ErrorNoSequenceLock:
+ Stream << "ErrorNoSequenceLock";
+ break;
+ }
+}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index ce90de3e8470e..ecc9386e49c7d 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -290,4 +290,14 @@ private:
} // namespace process_gdb_remote
} // namespace lldb_private
+namespace llvm {
+template <>
+struct format_provider<
+ lldb_private::process_gdb_remote::GDBRemoteCommunication::PacketResult> {
+ static void format(const lldb_private::process_gdb_remote::
+ GDBRemoteCommunication::PacketResult &state,
+ raw_ostream &Stream, StringRef Style);
+};
+} // namespace llvm
+
#endif // liblldb_GDBRemoteCommunication_h_
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index e6fd386b903b8..867f57c475cec 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -1022,10 +1022,7 @@ void GDBRemoteCommunicationClient::MaybeEnableCompression(
std::string avail_name;
#if defined(HAVE_LIBCOMPRESSION)
- // libcompression is weak linked so test if compression_decode_buffer() is
- // available
- if (compression_decode_buffer != NULL &&
- avail_type == CompressionType::None) {
+ if (avail_type == CompressionType::None) {
for (auto compression : supported_compressions) {
if (compression == "lzfse") {
avail_type = CompressionType::LZFSE;
@@ -1037,10 +1034,7 @@ void GDBRemoteCommunicationClient::MaybeEnableCompression(
#endif
#if defined(HAVE_LIBCOMPRESSION)
- // libcompression is weak linked so test if compression_decode_buffer() is
- // available
- if (compression_decode_buffer != NULL &&
- avail_type == CompressionType::None) {
+ if (avail_type == CompressionType::None) {
for (auto compression : supported_compressions) {
if (compression == "zlib-deflate") {
avail_type = CompressionType::ZlibDeflate;
@@ -1064,10 +1058,7 @@ void GDBRemoteCommunicationClient::MaybeEnableCompression(
#endif
#if defined(HAVE_LIBCOMPRESSION)
- // libcompression is weak linked so test if compression_decode_buffer() is
- // available
- if (compression_decode_buffer != NULL &&
- avail_type == CompressionType::None) {
+ if (avail_type == CompressionType::None) {
for (auto compression : supported_compressions) {
if (compression == "lz4") {
avail_type = CompressionType::LZ4;
@@ -1079,10 +1070,7 @@ void GDBRemoteCommunicationClient::MaybeEnableCompression(
#endif
#if defined(HAVE_LIBCOMPRESSION)
- // libcompression is weak linked so test if compression_decode_buffer() is
- // available
- if (compression_decode_buffer != NULL &&
- avail_type == CompressionType::None) {
+ if (avail_type == CompressionType::None) {
for (auto compression : supported_compressions) {
if (compression == "lzma") {
avail_type = CompressionType::LZMA;
@@ -1601,21 +1589,24 @@ GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction(
// 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, watchpoint exceptions are always generated
- // before the instruction is executed. The connected target may not
- // support qHostInfo or qWatchpointSupportInfo packets.
+ // 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.
if (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel ||
- atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)
+ atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el ||
+ atype == llvm::Triple::ppc64le)
after = false;
else
after = true;
} else {
- // For MIPS, set m_watchpoints_trigger_after_instruction to eLazyBoolNo
- // if it is not calculated before.
- if (m_watchpoints_trigger_after_instruction == eLazyBoolCalculate &&
- (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel ||
- atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el))
+ // For MIPS and ppc64le, set m_watchpoints_trigger_after_instruction to
+ // eLazyBoolNo if it is not calculated before.
+ if ((m_watchpoints_trigger_after_instruction == eLazyBoolCalculate &&
+ (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel ||
+ atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)) ||
+ atype == llvm::Triple::ppc64le) {
m_watchpoints_trigger_after_instruction = eLazyBoolNo;
+ }
after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo);
}
@@ -2624,8 +2615,8 @@ size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
* tid.
* Assume pid=tid=1 in such cases.
*/
- if (response.IsUnsupportedResponse() && thread_ids.size() == 0 &&
- IsConnected()) {
+ if ((response.IsUnsupportedResponse() || response.IsNormalResponse()) &&
+ thread_ids.size() == 0 && IsConnected()) {
thread_ids.push_back(1);
}
} else {
@@ -3451,7 +3442,9 @@ ParseModuleSpec(StructuredData::Dictionary *dict) {
if (!dict->GetValueForKeyAsString("uuid", string))
return llvm::None;
- result.GetUUID().SetFromStringRef(string, string.size());
+ if (result.GetUUID().SetFromStringRef(string, string.size() / 2) !=
+ string.size())
+ return llvm::None;
if (!dict->GetValueForKeyAsInteger("file_offset", integer))
return llvm::None;
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 712d85eed082e..ba67b82463987 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -20,10 +20,8 @@
#include <string>
#include <vector>
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Target/Process.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/StreamGDBRemote.h"
#include "lldb/Utility/StructuredData.h"
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
index f53db502be934..3cf6b8ac07b24 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -403,8 +403,8 @@ GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo(
match_info.SetMatchAllUsers(
Args::StringToBoolean(value, false, &success));
} else if (key.equals("triple")) {
- match_info.GetProcessInfo().GetArchitecture().SetTriple(
- value.str().c_str(), NULL);
+ match_info.GetProcessInfo().GetArchitecture() =
+ HostInfo::GetAugmentedArchSpec(value);
} else {
success = false;
}
@@ -973,8 +973,7 @@ GDBRemoteCommunicationServerCommon::Handle_QLaunchArch(
const uint32_t bytes_left = packet.GetBytesLeft();
if (bytes_left > 0) {
const char *arch_triple = packet.Peek();
- ArchSpec arch_spec(arch_triple, NULL);
- m_process_launch_info.SetArchitecture(arch_spec);
+ m_process_launch_info.SetArchitecture(HostInfo::GetAugmentedArchSpec(arch_triple));
return SendOKResponse();
}
return SendErrorResponse(13);
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 9294359dbef1c..32741c2404e22 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -204,21 +204,8 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
});
}
-Status
-GDBRemoteCommunicationServerLLGS::SetLaunchArguments(const char *const args[],
- int argc) {
- if ((argc < 1) || !args || !args[0] || !args[0][0])
- return Status("%s: no process command line specified to launch",
- __FUNCTION__);
-
- m_process_launch_info.SetArguments(const_cast<const char **>(args), true);
- return Status();
-}
-
-Status
-GDBRemoteCommunicationServerLLGS::SetLaunchFlags(unsigned int launch_flags) {
- m_process_launch_info.GetFlags().Set(launch_flags);
- return Status();
+void GDBRemoteCommunicationServerLLGS::SetLaunchInfo(const ProcessLaunchInfo &info) {
+ m_process_launch_info = info;
}
Status GDBRemoteCommunicationServerLLGS::LaunchProcess() {
@@ -244,13 +231,8 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() {
"process but one already exists");
auto process_or =
m_process_factory.Launch(m_process_launch_info, *this, m_mainloop);
- if (!process_or) {
- Status status(process_or.takeError());
- llvm::errs() << llvm::formatv(
- "failed to launch executable `{0}`: {1}",
- m_process_launch_info.GetArguments().GetArgumentAtIndex(0), status);
- return status;
- }
+ if (!process_or)
+ return Status(process_or.takeError());
m_debugged_process_up = std::move(*process_or);
}
@@ -396,12 +378,12 @@ static void AppendHexValue(StreamString &response, const uint8_t *buf,
}
static void WriteRegisterValueInHexFixedWidth(
- StreamString &response, NativeRegisterContextSP &reg_ctx_sp,
+ StreamString &response, NativeRegisterContext &reg_ctx,
const RegisterInfo &reg_info, const RegisterValue *reg_value_p,
lldb::ByteOrder byte_order) {
RegisterValue reg_value;
if (!reg_value_p) {
- Status error = reg_ctx_sp->ReadRegister(&reg_info, reg_value);
+ Status error = reg_ctx.ReadRegister(&reg_info, reg_value);
if (error.Success())
reg_value_p = &reg_value;
// else log.
@@ -423,9 +405,7 @@ static void WriteRegisterValueInHexFixedWidth(
static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
- NativeRegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
- if (!reg_ctx_sp)
- return nullptr;
+ NativeRegisterContext& reg_ctx = thread.GetRegisterContext();
JSONObject::SP register_object_sp = std::make_shared<JSONObject>();
@@ -448,14 +428,14 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) {
for (const uint32_t *generic_reg_p = k_expedited_registers;
*generic_reg_p != LLDB_INVALID_REGNUM; ++generic_reg_p) {
- uint32_t reg_num = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
+ uint32_t reg_num = reg_ctx.ConvertRegisterKindToRegisterNumber(
eRegisterKindGeneric, *generic_reg_p);
if (reg_num == LLDB_INVALID_REGNUM)
continue; // Target does not support the given register.
#endif
const RegisterInfo *const reg_info_p =
- reg_ctx_sp->GetRegisterInfoAtIndex(reg_num);
+ reg_ctx.GetRegisterInfoAtIndex(reg_num);
if (reg_info_p == nullptr) {
if (log)
log->Printf(
@@ -469,7 +449,7 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) {
// registers.
RegisterValue reg_value;
- Status error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value);
+ Status error = reg_ctx.ReadRegister(reg_info_p, reg_value);
if (error.Fail()) {
if (log)
log->Printf("%s failed to read register '%s' index %" PRIu32 ": %s",
@@ -480,7 +460,7 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) {
}
StreamString stream;
- WriteRegisterValueInHexFixedWidth(stream, reg_ctx_sp, *reg_info_p,
+ WriteRegisterValueInHexFixedWidth(stream, reg_ctx, *reg_info_p,
&reg_value, lldb::eByteOrderBig);
register_object_sp->SetObject(
@@ -523,16 +503,16 @@ static JSONArray::SP GetJSONThreadsInfo(NativeProcessProtocol &process,
// Ensure we can get info on the given thread.
uint32_t thread_idx = 0;
- for (NativeThreadProtocolSP thread_sp;
- (thread_sp = process.GetThreadAtIndex(thread_idx)) != nullptr;
+ for (NativeThreadProtocol *thread;
+ (thread = process.GetThreadAtIndex(thread_idx)) != nullptr;
++thread_idx) {
- lldb::tid_t tid = thread_sp->GetID();
+ lldb::tid_t tid = thread->GetID();
// Grab the reason this thread stopped.
struct ThreadStopInfo tid_stop_info;
std::string description;
- if (!thread_sp->GetStopReason(tid_stop_info, description))
+ if (!thread->GetStopReason(tid_stop_info, description))
return nullptr;
const int signum = tid_stop_info.details.signal.signo;
@@ -548,7 +528,7 @@ static JSONArray::SP GetJSONThreadsInfo(NativeProcessProtocol &process,
threads_array_sp->AppendObject(thread_obj_sp);
if (!abridged) {
- if (JSONObject::SP registers_sp = GetRegistersAsJSON(*thread_sp))
+ if (JSONObject::SP registers_sp = GetRegistersAsJSON(*thread))
thread_obj_sp->SetObject("registers", registers_sp);
}
@@ -556,7 +536,7 @@ static JSONArray::SP GetJSONThreadsInfo(NativeProcessProtocol &process,
if (signum != 0)
thread_obj_sp->SetObject("signal", std::make_shared<JSONNumber>(signum));
- const std::string thread_name = thread_sp->GetName();
+ const std::string thread_name = thread->GetName();
if (!thread_name.empty())
thread_obj_sp->SetObject("name",
std::make_shared<JSONString>(thread_name));
@@ -604,14 +584,14 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
m_debugged_process_up->GetID(), tid);
// Ensure we can get info on the given thread.
- NativeThreadProtocolSP thread_sp(m_debugged_process_up->GetThreadByID(tid));
- if (!thread_sp)
+ NativeThreadProtocol *thread = m_debugged_process_up->GetThreadByID(tid);
+ if (!thread)
return SendErrorResponse(51);
// Grab the reason this thread stopped.
struct ThreadStopInfo tid_stop_info;
std::string description;
- if (!thread_sp->GetStopReason(tid_stop_info, description))
+ if (!thread->GetStopReason(tid_stop_info, description))
return SendErrorResponse(52);
// FIXME implement register handling for exec'd inferiors.
@@ -638,7 +618,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
response.Printf("thread:%" PRIx64 ";", tid);
// Include the thread name if there is one.
- const std::string thread_name = thread_sp->GetName();
+ const std::string thread_name = thread->GetName();
if (!thread_name.empty()) {
size_t thread_name_len = thread_name.length();
@@ -665,15 +645,13 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
response.PutCString("threads:");
uint32_t thread_index = 0;
- NativeThreadProtocolSP listed_thread_sp;
- for (listed_thread_sp =
- m_debugged_process_up->GetThreadAtIndex(thread_index);
- listed_thread_sp; ++thread_index,
- listed_thread_sp = m_debugged_process_up->GetThreadAtIndex(
- thread_index)) {
+ NativeThreadProtocol *listed_thread;
+ for (listed_thread = m_debugged_process_up->GetThreadAtIndex(thread_index);
+ listed_thread; ++thread_index,
+ listed_thread = m_debugged_process_up->GetThreadAtIndex(thread_index)) {
if (thread_index > 0)
response.PutChar(',');
- response.Printf("%" PRIx64, listed_thread_sp->GetID());
+ response.Printf("%" PRIx64, listed_thread->GetID());
}
response.PutChar(';');
@@ -701,20 +679,18 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
uint32_t i = 0;
response.PutCString("thread-pcs");
char delimiter = ':';
- for (NativeThreadProtocolSP thread_sp;
- (thread_sp = m_debugged_process_up->GetThreadAtIndex(i)) != nullptr;
+ for (NativeThreadProtocol *thread;
+ (thread = m_debugged_process_up->GetThreadAtIndex(i)) != nullptr;
++i) {
- NativeRegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext();
- if (!reg_ctx_sp)
- continue;
+ NativeRegisterContext& reg_ctx = thread->GetRegisterContext();
- uint32_t reg_to_read = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
+ uint32_t reg_to_read = reg_ctx.ConvertRegisterKindToRegisterNumber(
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
const RegisterInfo *const reg_info_p =
- reg_ctx_sp->GetRegisterInfoAtIndex(reg_to_read);
+ reg_ctx.GetRegisterInfoAtIndex(reg_to_read);
RegisterValue reg_value;
- Status error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value);
+ Status error = reg_ctx.ReadRegister(reg_info_p, reg_value);
if (error.Fail()) {
if (log)
log->Printf("%s failed to read register '%s' index %" PRIu32 ": %s",
@@ -727,7 +703,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
response.PutChar(delimiter);
delimiter = ',';
- WriteRegisterValueInHexFixedWidth(response, reg_ctx_sp, *reg_info_p,
+ WriteRegisterValueInHexFixedWidth(response, reg_ctx, *reg_info_p,
&reg_value, endian::InlHostByteOrder());
}
@@ -739,49 +715,48 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
//
// Grab the register context.
- NativeRegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext();
- if (reg_ctx_sp) {
- // Expedite all registers in the first register set (i.e. should be GPRs)
- // that are not contained in other registers.
- const RegisterSet *reg_set_p;
- if (reg_ctx_sp->GetRegisterSetCount() > 0 &&
- ((reg_set_p = reg_ctx_sp->GetRegisterSet(0)) != nullptr)) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s expediting registers "
- "from set '%s' (registers set count: %zu)",
- __FUNCTION__,
- reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
- reg_set_p->num_registers);
-
- for (const uint32_t *reg_num_p = reg_set_p->registers;
- *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) {
- const RegisterInfo *const reg_info_p =
- reg_ctx_sp->GetRegisterInfoAtIndex(*reg_num_p);
- if (reg_info_p == nullptr) {
+ NativeRegisterContext& reg_ctx = thread->GetRegisterContext();
+ // Expedite all registers in the first register set (i.e. should be GPRs)
+ // that are not contained in other registers.
+ const RegisterSet *reg_set_p;
+ if (reg_ctx.GetRegisterSetCount() > 0 &&
+ ((reg_set_p = reg_ctx.GetRegisterSet(0)) != nullptr)) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s expediting registers "
+ "from set '%s' (registers set count: %zu)",
+ __FUNCTION__,
+ reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
+ reg_set_p->num_registers);
+
+ for (const uint32_t *reg_num_p = reg_set_p->registers;
+ *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) {
+ const RegisterInfo *const reg_info_p =
+ reg_ctx.GetRegisterInfoAtIndex(*reg_num_p);
+ if (reg_info_p == nullptr) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to get "
+ "register info for register set '%s', register index "
+ "%" PRIu32,
+ __FUNCTION__,
+ reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
+ *reg_num_p);
+ } else if (reg_info_p->value_regs == nullptr) {
+ // Only expediate registers that are not contained in other registers.
+ RegisterValue reg_value;
+ Status error = reg_ctx.ReadRegister(reg_info_p, reg_value);
+ if (error.Success()) {
+ response.Printf("%.02x:", *reg_num_p);
+ WriteRegisterValueInHexFixedWidth(response, reg_ctx, *reg_info_p,
+ &reg_value, lldb::eByteOrderBig);
+ response.PutChar(';');
+ } else {
if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to get "
- "register info for register set '%s', register index "
- "%" PRIu32,
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to read "
+ "register '%s' index %" PRIu32 ": %s",
__FUNCTION__,
- reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
- *reg_num_p);
- } else if (reg_info_p->value_regs == nullptr) {
- // Only expediate registers that are not contained in other registers.
- RegisterValue reg_value;
- Status error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value);
- if (error.Success()) {
- response.Printf("%.02x:", *reg_num_p);
- WriteRegisterValueInHexFixedWidth(response, reg_ctx_sp, *reg_info_p,
- &reg_value, lldb::eByteOrderBig);
- response.PutChar(';');
- } else {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to read "
- "register '%s' index %" PRIu32 ": %s",
- __FUNCTION__, reg_info_p->name ? reg_info_p->name
- : "<unnamed-register>",
- *reg_num_p, error.AsCString());
- }
+ reg_info_p->name ? reg_info_p->name
+ : "<unnamed-register>",
+ *reg_num_p, error.AsCString());
}
}
}
@@ -837,6 +812,7 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited(
// We are ready to exit the debug monitor.
m_exit_now = true;
+ m_mainloop.RequestTermination();
}
void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped(
@@ -1316,12 +1292,12 @@ GDBRemoteCommunicationServerLLGS::Handle_qC(StringExtractorGDBRemote &packet) {
lldb::tid_t tid = m_debugged_process_up->GetCurrentThreadID();
SetCurrentThreadID(tid);
- NativeThreadProtocolSP thread_sp = m_debugged_process_up->GetCurrentThread();
- if (!thread_sp)
+ NativeThreadProtocol *thread = m_debugged_process_up->GetCurrentThread();
+ if (!thread)
return SendErrorResponse(69);
StreamString response;
- response.Printf("QC%" PRIx64, thread_sp->GetID());
+ response.Printf("QC%" PRIx64, thread->GetID());
return SendPacketNoLock(response.GetString());
}
@@ -1692,14 +1668,12 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo(
return SendErrorResponse(68);
// Ensure we have a thread.
- NativeThreadProtocolSP thread_sp(m_debugged_process_up->GetThreadAtIndex(0));
- if (!thread_sp)
+ NativeThreadProtocol *thread = m_debugged_process_up->GetThreadAtIndex(0);
+ if (!thread)
return SendErrorResponse(69);
// Get the register context for the first thread.
- NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
- if (!reg_context_sp)
- return SendErrorResponse(69);
+ NativeRegisterContext &reg_context = thread->GetRegisterContext();
// Parse out the register number from the request.
packet.SetFilePos(strlen("qRegisterInfo"));
@@ -1710,11 +1684,10 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo(
// Return the end of registers response if we've iterated one past the end of
// the register set.
- if (reg_index >= reg_context_sp->GetUserRegisterCount())
+ if (reg_index >= reg_context.GetUserRegisterCount())
return SendErrorResponse(69);
- const RegisterInfo *reg_info =
- reg_context_sp->GetRegisterInfoAtIndex(reg_index);
+ const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index);
if (!reg_info)
return SendErrorResponse(69);
@@ -1796,7 +1769,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo(
};
const char *const register_set_name =
- reg_context_sp->GetRegisterSetNameForRegisterAtIndex(reg_index);
+ reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index);
if (register_set_name) {
response.PutCString("set:");
response.PutCString(register_set_name);
@@ -1908,18 +1881,17 @@ GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo(
response.PutChar('m');
LLDB_LOG(log, "starting thread iteration");
- NativeThreadProtocolSP thread_sp;
+ NativeThreadProtocol *thread;
uint32_t thread_index;
for (thread_index = 0,
- thread_sp = m_debugged_process_up->GetThreadAtIndex(thread_index);
- thread_sp; ++thread_index,
- thread_sp = m_debugged_process_up->GetThreadAtIndex(thread_index)) {
- LLDB_LOG(log, "iterated thread {0}({1}, tid={2})", thread_index,
- thread_sp ? "is not null" : "null",
- thread_sp ? thread_sp->GetID() : LLDB_INVALID_THREAD_ID);
+ thread = m_debugged_process_up->GetThreadAtIndex(thread_index);
+ thread; ++thread_index,
+ thread = m_debugged_process_up->GetThreadAtIndex(thread_index)) {
+ LLDB_LOG(log, "iterated thread {0}(tid={2})", thread_index,
+ thread->GetID());
if (thread_index > 0)
response.PutChar(',');
- response.Printf("%" PRIx64, thread_sp->GetID());
+ response.Printf("%" PRIx64, thread->GetID());
}
LLDB_LOG(log, "finished thread iteration");
@@ -1951,38 +1923,27 @@ GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) {
}
// Get the thread to use.
- NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet);
- if (!thread_sp) {
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s failed, no thread available",
- __FUNCTION__);
+ NativeThreadProtocol *thread = GetThreadFromSuffix(packet);
+ if (!thread) {
+ LLDB_LOG(log, "failed, no thread available");
return SendErrorResponse(0x15);
}
// Get the thread's register context.
- NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
- if (!reg_context_sp) {
- LLDB_LOG(
- log,
- "pid {0} tid {1} failed, no register context available for the thread",
- m_debugged_process_up->GetID(), thread_sp->GetID());
- return SendErrorResponse(0x15);
- }
+ NativeRegisterContext &reg_context = thread->GetRegisterContext();
// Return the end of registers response if we've iterated one past the end of
// the register set.
- if (reg_index >= reg_context_sp->GetUserRegisterCount()) {
+ if (reg_index >= reg_context.GetUserRegisterCount()) {
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
"register %" PRIu32 " beyond register count %" PRIu32,
__FUNCTION__, reg_index,
- reg_context_sp->GetUserRegisterCount());
+ reg_context.GetUserRegisterCount());
return SendErrorResponse(0x15);
}
- const RegisterInfo *reg_info =
- reg_context_sp->GetRegisterInfoAtIndex(reg_index);
+ const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index);
if (!reg_info) {
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
@@ -1996,7 +1957,7 @@ GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) {
// Retrieve the value
RegisterValue reg_value;
- Status error = reg_context_sp->ReadRegister(reg_info, reg_value);
+ Status error = reg_context.ReadRegister(reg_info, reg_value);
if (error.Fail()) {
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, read of "
@@ -2047,24 +2008,13 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
return SendIllFormedResponse(
packet, "P packet missing '=' char after register number");
- // Get process architecture.
- ArchSpec process_arch;
- if (!m_debugged_process_up ||
- !m_debugged_process_up->GetArchitecture(process_arch)) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to retrieve "
- "inferior architecture",
- __FUNCTION__);
- return SendErrorResponse(0x49);
- }
-
// Parse out the value.
uint8_t reg_bytes[32]; // big enough to support up to 256 bit ymmN register
size_t reg_size = packet.GetHexBytesAvail(reg_bytes);
// Get the thread to use.
- NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet);
- if (!thread_sp) {
+ NativeThreadProtocol *thread = GetThreadFromSuffix(packet);
+ if (!thread) {
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, no thread "
"available (thread index 0)",
@@ -2073,18 +2023,8 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
}
// Get the thread's register context.
- NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
- if (!reg_context_sp) {
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64
- " failed, no register context available for the thread",
- __FUNCTION__, m_debugged_process_up->GetID(), thread_sp->GetID());
- return SendErrorResponse(0x15);
- }
-
- const RegisterInfo *reg_info =
- reg_context_sp->GetRegisterInfoAtIndex(reg_index);
+ NativeRegisterContext &reg_context = thread->GetRegisterContext();
+ const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index);
if (!reg_info) {
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
@@ -2095,12 +2035,11 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
// Return the end of registers response if we've iterated one past the end of
// the register set.
- if (reg_index >= reg_context_sp->GetUserRegisterCount()) {
+ if (reg_index >= reg_context.GetUserRegisterCount()) {
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
"register %" PRIu32 " beyond register count %" PRIu32,
- __FUNCTION__, reg_index,
- reg_context_sp->GetUserRegisterCount());
+ __FUNCTION__, reg_index, reg_context.GetUserRegisterCount());
return SendErrorResponse(0x47);
}
@@ -2115,8 +2054,10 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
// Build the reginfos response.
StreamGDBRemote response;
- RegisterValue reg_value(reg_bytes, reg_size, process_arch.GetByteOrder());
- Status error = reg_context_sp->WriteRegister(reg_info, reg_value);
+ RegisterValue reg_value(
+ reg_bytes, reg_size,
+ m_debugged_process_up->GetArchitecture().GetByteOrder());
+ Status error = reg_context.WriteRegister(reg_info, reg_value);
if (error.Fail()) {
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, write of "
@@ -2177,8 +2118,8 @@ GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) {
// Ensure we have the given thread when not specifying -1 (all threads) or 0
// (any thread).
if (tid != LLDB_INVALID_THREAD_ID && tid != 0) {
- NativeThreadProtocolSP thread_sp(m_debugged_process_up->GetThreadByID(tid));
- if (!thread_sp) {
+ NativeThreadProtocol *thread = m_debugged_process_up->GetThreadByID(tid);
+ if (!thread) {
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64
" not found",
@@ -2739,8 +2680,8 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) {
// Double check that we have such a thread.
// TODO investigate: on MacOSX we might need to do an UpdateThreads () here.
- NativeThreadProtocolSP thread_sp = m_debugged_process_up->GetThreadByID(tid);
- if (!thread_sp || thread_sp->GetID() != tid)
+ NativeThreadProtocol *thread = m_debugged_process_up->GetThreadByID(tid);
+ if (!thread)
return SendErrorResponse(0x33);
// Create the step action for the given thread.
@@ -2865,8 +2806,8 @@ GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState(
packet.SetFilePos(strlen("QSaveRegisterState"));
// Get the thread to use.
- NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet);
- if (!thread_sp) {
+ NativeThreadProtocol *thread = GetThreadFromSuffix(packet);
+ if (!thread) {
if (m_thread_suffix_supported)
return SendIllFormedResponse(
packet, "No thread specified in QSaveRegisterState packet");
@@ -2876,18 +2817,11 @@ GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState(
}
// Grab the register context for the thread.
- NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
- if (!reg_context_sp) {
- LLDB_LOG(
- log,
- "pid {0} tid {1} failed, no register context available for the thread",
- m_debugged_process_up->GetID(), thread_sp->GetID());
- return SendErrorResponse(0x15);
- }
+ NativeRegisterContext& reg_context = thread->GetRegisterContext();
// Save registers to a buffer.
DataBufferSP register_data_sp;
- Status error = reg_context_sp->ReadAllRegisterValues(register_data_sp);
+ Status error = reg_context.ReadAllRegisterValues(register_data_sp);
if (error.Fail()) {
LLDB_LOG(log, "pid {0} failed to save all register values: {1}",
m_debugged_process_up->GetID(), error);
@@ -2930,8 +2864,8 @@ GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState(
}
// Get the thread to use.
- NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet);
- if (!thread_sp) {
+ NativeThreadProtocol *thread = GetThreadFromSuffix(packet);
+ if (!thread) {
if (m_thread_suffix_supported)
return SendIllFormedResponse(
packet, "No thread specified in QRestoreRegisterState packet");
@@ -2941,14 +2875,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState(
}
// Grab the register context for the thread.
- NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
- if (!reg_context_sp) {
- LLDB_LOG(
- log,
- "pid {0} tid {1} failed, no register context available for the thread",
- m_debugged_process_up->GetID(), thread_sp->GetID());
- return SendErrorResponse(0x15);
- }
+ NativeRegisterContext &reg_context = thread->GetRegisterContext();
// Retrieve register state buffer, then remove from the list.
DataBufferSP register_data_sp;
@@ -2969,7 +2896,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState(
m_saved_registers_map.erase(it);
}
- Status error = reg_context_sp->WriteAllRegisterValues(register_data_sp);
+ Status error = reg_context.WriteAllRegisterValues(register_data_sp);
if (error.Fail()) {
LLDB_LOG(log, "pid {0} failed to restore all register values: {1}",
m_debugged_process_up->GetID(), error);
@@ -3219,14 +3146,12 @@ void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() {
}
}
-NativeThreadProtocolSP GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
+NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
StringExtractorGDBRemote &packet) {
- NativeThreadProtocolSP thread_sp;
-
// We have no thread if we don't have a process.
if (!m_debugged_process_up ||
m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)
- return thread_sp;
+ return nullptr;
// If the client hasn't asked for thread suffix support, there will not be a
// thread suffix.
@@ -3234,7 +3159,7 @@ NativeThreadProtocolSP GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
if (!m_thread_suffix_supported) {
const lldb::tid_t current_tid = GetCurrentThreadID();
if (current_tid == LLDB_INVALID_THREAD_ID)
- return thread_sp;
+ return nullptr;
else if (current_tid == 0) {
// Pick a thread.
return m_debugged_process_up->GetThreadAtIndex(0);
@@ -3251,11 +3176,11 @@ NativeThreadProtocolSP GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
"error: expected ';' prior to start of thread suffix: packet "
"contents = '%s'",
__FUNCTION__, packet.GetStringRef().c_str());
- return thread_sp;
+ return nullptr;
}
if (!packet.GetBytesLeft())
- return thread_sp;
+ return nullptr;
// Parse out thread: portion.
if (strncmp(packet.Peek(), "thread:", strlen("thread:")) != 0) {
@@ -3264,14 +3189,14 @@ NativeThreadProtocolSP GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
"error: expected 'thread:' but not found, packet contents = "
"'%s'",
__FUNCTION__, packet.GetStringRef().c_str());
- return thread_sp;
+ return nullptr;
}
packet.SetFilePos(packet.GetFilePos() + strlen("thread:"));
const lldb::tid_t tid = packet.GetHexMaxU64(false, 0);
if (tid != 0)
return m_debugged_process_up->GetThreadByID(tid);
- return thread_sp;
+ return nullptr;
}
lldb::tid_t GDBRemoteCommunicationServerLLGS::GetCurrentThreadID() const {
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index 71199473bb8ed..5a74d1acaa237 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -43,32 +43,7 @@ public:
MainLoop &mainloop,
const NativeProcessProtocol::Factory &process_factory);
- //------------------------------------------------------------------
- /// Specify the program to launch and its arguments.
- ///
- /// @param[in] args
- /// The command line to launch.
- ///
- /// @param[in] argc
- /// The number of elements in the args array of cstring pointers.
- ///
- /// @return
- /// An Status object indicating the success or failure of making
- /// the setting.
- //------------------------------------------------------------------
- Status SetLaunchArguments(const char *const args[], int argc);
-
- //------------------------------------------------------------------
- /// Specify the launch flags for the process.
- ///
- /// @param[in] launch_flags
- /// The launch flags to use when launching this process.
- ///
- /// @return
- /// An Status object indicating the success or failure of making
- /// the setting.
- //------------------------------------------------------------------
- Status SetLaunchFlags(unsigned int launch_flags);
+ void SetLaunchInfo(const ProcessLaunchInfo &info);
//------------------------------------------------------------------
/// Launch a process with the current launch settings.
@@ -234,7 +209,7 @@ private:
void HandleInferiorState_Stopped(NativeProcessProtocol *process);
- NativeThreadProtocolSP GetThreadFromSuffix(StringExtractorGDBRemote &packet);
+ NativeThreadProtocol *GetThreadFromSuffix(StringExtractorGDBRemote &packet);
uint32_t GetNextSavedRegistersID();
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
index 977c34c2a69b3..04ed9d704e137 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
@@ -128,8 +128,9 @@ Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
llvm::StringRef platform_ip;
int platform_port;
llvm::StringRef platform_path;
- bool ok = UriParser::Parse(GetConnection()->GetURI(), platform_scheme,
- platform_ip, platform_port, platform_path);
+ std::string platform_uri = GetConnection()->GetURI();
+ bool ok = UriParser::Parse(platform_uri, platform_scheme, platform_ip,
+ platform_port, platform_path);
UNUSED_IF_ASSERT_DISABLED(ok);
assert(ok);
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
index 612c7144451e0..e418deee01f3d 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -178,7 +178,7 @@ bool GDBRemoteRegisterContext::GetPrimordialRegister(
const RegisterInfo *reg_info, GDBRemoteCommunicationClient &gdb_comm) {
const uint32_t lldb_reg = reg_info->kinds[eRegisterKindLLDB];
const uint32_t remote_reg = reg_info->kinds[eRegisterKindProcessPlugin];
- StringExtractorGDBRemote response;
+
if (DataBufferSP buffer_sp =
gdb_comm.ReadRegister(m_thread.GetProtocolID(), remote_reg))
return PrivateSetRegisterValue(
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index be11dd9bc7ec7..35d02c15ab85b 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -29,7 +29,6 @@
#include <sstream>
#include "lldb/Breakpoint/Watchpoint.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
@@ -244,7 +243,7 @@ bool ProcessGDBRemote::CanDebug(lldb::TargetSP target_sp,
//----------------------------------------------------------------------
ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
ListenerSP listener_sp)
- : Process(target_sp, listener_sp), m_flags(0), m_gdb_comm(),
+ : Process(target_sp, listener_sp),
m_debugserver_pid(LLDB_INVALID_PROCESS_ID), m_last_stop_packet_mutex(),
m_register_info(),
m_async_broadcaster(NULL, "lldb.process.gdb-remote.async-broadcaster"),
@@ -818,7 +817,7 @@ Status ProcessGDBRemote::DoLaunch(Module *exe_module,
if (object_file) {
error = EstablishConnectionIfNeeded(launch_info);
if (error.Success()) {
- lldb_utility::PseudoTerminal pty;
+ PseudoTerminal pty;
const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
PlatformSP platform_sp(GetTarget().GetPlatform());
@@ -947,8 +946,7 @@ Status ProcessGDBRemote::DoLaunch(Module *exe_module,
SetPrivateState(SetThreadStopInfo(response));
if (!disable_stdio) {
- if (pty.GetMasterFileDescriptor() !=
- lldb_utility::PseudoTerminal::invalid_fd)
+ if (pty.GetMasterFileDescriptor() != PseudoTerminal::invalid_fd)
SetSTDIOFileDescriptor(pty.ReleaseMasterFileDescriptor());
}
}
@@ -3255,7 +3253,6 @@ Status ProcessGDBRemote::DisableWatchpoint(Watchpoint *wp, bool notify) {
}
void ProcessGDBRemote::Clear() {
- m_flags = 0;
m_thread_list_real.Clear();
m_thread_list.Clear();
}
@@ -3289,7 +3286,7 @@ ProcessGDBRemote::EstablishConnectionIfNeeded(const ProcessInfo &process_info) {
}
return error;
}
-#if defined(__APPLE__)
+#if !defined(_WIN32)
#define USE_SOCKETPAIR_FOR_LOCAL_CONNECTION 1
#endif
@@ -3333,8 +3330,8 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver(
lldb_utility::CleanUp<int, int> our_socket(-1, -1, close);
lldb_utility::CleanUp<int, int> gdb_socket(-1, -1, close);
- // Use a socketpair on Apple for now until other platforms can verify it
- // works and is fast enough
+ // 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) {
@@ -4168,7 +4165,6 @@ struct GdbServerTargetInfo {
std::string osabi;
stringVec includes;
RegisterSetMap reg_set_map;
- XMLNode feature_node;
};
bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
@@ -4374,8 +4370,8 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {
XMLNode target_node = xml_document.GetRootElement("target");
if (target_node) {
- XMLNode feature_node;
- target_node.ForEachChildElement([&target_info, &feature_node](
+ std::vector<XMLNode> feature_nodes;
+ target_node.ForEachChildElement([&target_info, &feature_nodes](
const XMLNode &node) -> bool {
llvm::StringRef name = node.GetName();
if (name == "architecture") {
@@ -4387,7 +4383,7 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {
if (!href.empty())
target_info.includes.push_back(href.str());
} else if (name == "feature") {
- feature_node = node;
+ feature_nodes.push_back(node);
} else if (name == "groups") {
node.ForEachChildElementWithName(
"group", [&target_info](const XMLNode &node) -> bool {
@@ -4423,7 +4419,7 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {
// 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);
- if (feature_node) {
+ for (auto &feature_node : feature_nodes) {
ParseRegisters(feature_node, target_info, this->m_register_info,
abi_to_use_sp, cur_reg_num, reg_offset);
}
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 54a472d7332e0..42d1c4ecd6663 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -18,9 +18,6 @@
#include <string>
#include <vector>
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/LoadedModuleInfoList.h"
#include "lldb/Core/ModuleSpec.h"
@@ -28,6 +25,7 @@
#include "lldb/Host/HostThread.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamGDBRemote.h"
@@ -263,7 +261,6 @@ protected:
eBroadcastBitAsyncThreadDidExit = (1 << 2)
};
- Flags m_flags; // Process specific flags (see eFlags enums)
GDBRemoteCommunicationClient m_gdb_comm;
std::atomic<lldb::pid_t> m_debugserver_pid;
std::vector<StringExtractorGDBRemote> m_stop_packet_stack; // The stop packet
@@ -324,10 +321,6 @@ protected:
void Clear();
- Flags &GetFlags() { return m_flags; }
-
- const Flags &GetFlags() const { return m_flags; }
-
bool UpdateThreadList(ThreadList &old_thread_list,
ThreadList &new_thread_list) override;
diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index 5197e8f9adfcc..27dd03bfc7bc5 100644
--- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -10,7 +10,6 @@
#include "ThreadGDBRemote.h"
#include "lldb/Breakpoint/Watchpoint.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/State.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
diff --git a/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/source/Plugins/Process/mach-core/ProcessMachCore.cpp
index a6178500dfc5c..d21651b77ee0c 100644
--- a/source/Plugins/Process/mach-core/ProcessMachCore.cpp
+++ b/source/Plugins/Process/mach-core/ProcessMachCore.cpp
@@ -468,7 +468,7 @@ Status ProcessMachCore::DoLoadCore() {
// 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.SetTriple("i386", GetTarget().GetPlatform().get());
+ arch = Platform::GetAugmentedArchSpec(GetTarget().GetPlatform().get(), "i386");
}
if (arch.IsValid())
GetTarget().SetArchitecture(arch);
diff --git a/source/Plugins/Process/mach-core/ThreadMachCore.cpp b/source/Plugins/Process/mach-core/ThreadMachCore.cpp
index 3917b99bd63d5..2b44105c13b1a 100644
--- a/source/Plugins/Process/mach-core/ThreadMachCore.cpp
+++ b/source/Plugins/Process/mach-core/ThreadMachCore.cpp
@@ -12,7 +12,6 @@
#include "lldb/Utility/SafeMachO.h"
#include "lldb/Breakpoint/Watchpoint.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/State.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Process.h"
@@ -20,6 +19,7 @@
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Unwind.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/StreamString.h"
diff --git a/source/Plugins/Process/minidump/MinidumpParser.h b/source/Plugins/Process/minidump/MinidumpParser.h
index df6deb482afdb..b7329ffc00289 100644
--- a/source/Plugins/Process/minidump/MinidumpParser.h
+++ b/source/Plugins/Process/minidump/MinidumpParser.h
@@ -14,8 +14,7 @@
// Project includes
#include "MinidumpTypes.h"
-// Other libraries and framework includes
-#include "lldb/Core/ArchSpec.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/Status.h"
diff --git a/source/Plugins/Process/minidump/ProcessMinidump.h b/source/Plugins/Process/minidump/ProcessMinidump.h
index d5c46be97352e..4b91d1ba396a4 100644
--- a/source/Plugins/Process/minidump/ProcessMinidump.h
+++ b/source/Plugins/Process/minidump/ProcessMinidump.h
@@ -82,6 +82,14 @@ public:
bool GetProcessInfo(ProcessInstanceInfo &info) override;
+ Status WillResume() override {
+ Status error;
+ error.SetErrorStringWithFormat(
+ "error: %s does not support resuming processes",
+ GetPluginName().GetCString());
+ return error;
+ }
+
MinidumpParser m_minidump_parser;
protected:
diff --git a/source/Plugins/Process/minidump/ThreadMinidump.cpp b/source/Plugins/Process/minidump/ThreadMinidump.cpp
index 9c21cc92376fc..3fafb6134e7f6 100644
--- a/source/Plugins/Process/minidump/ThreadMinidump.cpp
+++ b/source/Plugins/Process/minidump/ThreadMinidump.cpp
@@ -17,8 +17,8 @@
// Other libraries and framework includes
#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
-
#include "Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
@@ -43,8 +43,6 @@ ThreadMinidump::~ThreadMinidump() {}
void ThreadMinidump::RefreshStateAfterStop() {}
-void ThreadMinidump::ClearStackFrames() {}
-
RegisterContextSP ThreadMinidump::GetRegisterContext() {
if (!m_reg_context_sp) {
m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
@@ -76,20 +74,18 @@ ThreadMinidump::CreateRegisterContextForFrame(StackFrame *frame) {
reg_interface = new RegisterContextLinux_i386(arch);
lldb::DataBufferSP buf =
ConvertMinidumpContext_x86_32(m_gpregset_data, reg_interface);
- DataExtractor gpregs(buf, lldb::eByteOrderLittle, 4);
- DataExtractor fpregs;
+ DataExtractor gpregset(buf, lldb::eByteOrderLittle, 4);
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64(
- *this, reg_interface, gpregs, fpregs));
+ *this, reg_interface, gpregset, {}));
break;
}
case llvm::Triple::x86_64: {
reg_interface = new RegisterContextLinux_x86_64(arch);
lldb::DataBufferSP buf =
ConvertMinidumpContext_x86_64(m_gpregset_data, reg_interface);
- DataExtractor gpregs(buf, lldb::eByteOrderLittle, 8);
- DataExtractor fpregs;
+ DataExtractor gpregset(buf, lldb::eByteOrderLittle, 8);
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64(
- *this, reg_interface, gpregs, fpregs));
+ *this, reg_interface, gpregset, {}));
break;
}
default:
diff --git a/source/Plugins/Process/minidump/ThreadMinidump.h b/source/Plugins/Process/minidump/ThreadMinidump.h
index 97db452edfffa..74ac44f74dcf6 100644
--- a/source/Plugins/Process/minidump/ThreadMinidump.h
+++ b/source/Plugins/Process/minidump/ThreadMinidump.h
@@ -37,8 +37,6 @@ public:
lldb::RegisterContextSP
CreateRegisterContextForFrame(StackFrame *frame) override;
- void ClearStackFrames() override;
-
protected:
lldb::RegisterContextSP m_thread_reg_ctx_sp;
llvm::ArrayRef<uint8_t> m_gpregset_data;
diff --git a/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp b/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
index f1450c31b36b9..8424b55ee69cd 100644
--- a/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
+++ b/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
@@ -857,36 +857,6 @@ protected:
*static_cast<StructuredDataDarwinLog *>(plugin_sp.get());
if (m_enable) {
-// To do this next part right, we need to track whether we
-// added the proper environment variable at launch time.
-// It is incorrect to assume that we're enabling after launch,
-// and that therefore if we needed the env var set to properly
-// handle the options, that it is set incorrectly. The env var
-// could have been added if this is a re-enable using different
-// arguments. This is a bit tricky as the point where we
-// have to set the env var, we don't yet have a process or the
-// associated darwin-log plugin instance, and thus don't have a
-// great place to stick this knowledge.
-#if 0
- // Check if we're attempting to disable debug-level or
- // info-level content but we haven't launched with the magic
- // env var that suppresses the "always add" of those. In
- // that scenario, the user is asking *not* to see debug or
- // info level messages, but will see them anyway. Warn and
- // show how to correct it.
- if (!m_options_sp->GetIncludeDebugLevel() &&
- !GetGlobalProperties()->GetUseStrictSources())
- {
- AppendStrictSourcesWarning(result, "debug-level");
- }
-
- if (!m_options_sp->GetIncludeInfoLevel() &&
- !GetGlobalProperties()->GetUseStrictSources())
- {
- AppendStrictSourcesWarning(result, "info-level");
- }
-#endif
-
// 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
@@ -1823,34 +1793,10 @@ StructuredDataDarwinLog::DumpHeader(Stream &output_stream,
if (header_count > 0)
stream.PutChar(',');
-// Switch over to the #if 0 branch once we figure out
-// how we want to present settings for the tri-state of
-// no-activity, activity (most derived only), or activity-chain.
-#if 1
// Display the activity chain, from parent-most to child-most
// activity, separated by a colon (:).
stream.PutCString("activity-chain=");
stream.PutCString(activity_chain);
-#else
- if (GetGlobalProperties()->GetDisplayActivityChain()) {
- // Display the activity chain, from parent-most to child-most
- // activity, separated by a colon (:).
- stream.PutCString("activity-chain=");
- stream.PutCString(activity_chain.c_str());
- } else {
- // We're only displaying the child-most activity.
- stream.PutCString("activity=");
- auto pos = activity_chain.find_last_of(':');
- if (pos == std::string::npos) {
- // The activity chain only has one level, use the whole
- // thing.
- stream.PutCString(activity_chain.c_str());
- } else {
- // Display everything after the final ':'.
- stream.PutCString(activity_chain.substr(pos + 1).c_str());
- }
- }
-#endif
++header_count;
}
}
diff --git a/source/Plugins/SymbolFile/DWARF/CMakeLists.txt b/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
index fb468440f9e03..05d9e66428680 100644
--- a/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
+++ b/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
@@ -30,6 +30,8 @@ add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN
NameToDIE.cpp
SymbolFileDWARF.cpp
SymbolFileDWARFDwo.cpp
+ SymbolFileDWARFDwoDwp.cpp
+ SymbolFileDWARFDwp.cpp
SymbolFileDWARFDebugMap.cpp
UniqueDWARFASTType.cpp
@@ -47,5 +49,6 @@ add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN
lldbPluginCPlusPlusLanguage
lldbPluginExpressionParserClang
LINK_COMPONENTS
+ DebugInfoDWARF
Support
)
diff --git a/source/Plugins/SymbolFile/DWARF/DIERef.cpp b/source/Plugins/SymbolFile/DWARF/DIERef.cpp
index 5ed9c6ab72825..c05444c031e67 100644
--- a/source/Plugins/SymbolFile/DWARF/DIERef.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DIERef.cpp
@@ -65,7 +65,7 @@ lldb::user_id_t DIERef::GetUID(SymbolFileDWARF *dwarf) const {
//
// SymbolFileDWARFDwo sets the ID to the compile unit offset.
//----------------------------------------------------------------------
- if (dwarf)
+ if (dwarf && die_offset != DW_INVALID_OFFSET)
return dwarf->GetID() | die_offset;
else
return LLDB_INVALID_UID;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index f5418763d67be..6ae2b225d8696 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -786,7 +786,17 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
m_ast.ParseClassTemplateDecl(decl_ctx, accessibility,
type_name_cstr, tag_decl_kind,
template_param_infos);
-
+ if (!class_template_decl) {
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" "
+ "clang::ClassTemplateDecl failed to return a decl.",
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), type_name_cstr);
+ }
+ return TypeSP();
+ }
+
clang::ClassTemplateSpecializationDecl
*class_specialization_decl =
m_ast.CreateClassTemplateSpecializationDecl(
@@ -927,6 +937,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
// Set a bit that lets us know that we are currently parsing this
dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
+ bool is_scoped = false;
DWARFFormValue encoding_form;
const size_t num_attributes = die.GetAttributes(attributes);
@@ -963,6 +974,9 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
case DW_AT_declaration:
is_forward_declaration = form_value.Boolean();
break;
+ case DW_AT_enum_class:
+ is_scoped = form_value.Boolean();
+ break;
case DW_AT_allocated:
case DW_AT_associated:
case DW_AT_bit_stride:
@@ -1052,7 +1066,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
clang_type = m_ast.CreateEnumerationType(
type_name_cstr, GetClangDeclContextContainingDIE(die, nullptr),
- decl, enumerator_clang_type);
+ decl, enumerator_clang_type, is_scoped);
} else {
enumerator_clang_type =
m_ast.GetEnumerationIntegerType(clang_type.GetOpaqueQualType());
@@ -2741,8 +2755,6 @@ bool DWARFASTParserClang::ParseChildMembers(
form_value.BlockData() - debug_info_data.GetDataStart();
if (DWARFExpression::Evaluate(
nullptr, // ExecutionContext *
- nullptr, // ClangExpressionVariableList *
- nullptr, // ClangExpressionDeclMap *
nullptr, // RegisterContext *
module_sp, debug_info_data, die.GetCU(), block_offset,
block_length, eRegisterKindDWARF, &initialValue,
@@ -3214,11 +3226,11 @@ bool DWARFASTParserClang::ParseChildMembers(
uint32_t block_length = form_value.Unsigned();
uint32_t block_offset =
form_value.BlockData() - debug_info_data.GetDataStart();
- if (DWARFExpression::Evaluate(
- nullptr, nullptr, nullptr, nullptr, module_sp,
- debug_info_data, die.GetCU(), block_offset,
- block_length, eRegisterKindDWARF, &initialValue,
- nullptr, memberOffset, nullptr)) {
+ if (DWARFExpression::Evaluate(nullptr, nullptr, module_sp,
+ debug_info_data, die.GetCU(),
+ block_offset, block_length,
+ eRegisterKindDWARF, &initialValue,
+ nullptr, memberOffset, nullptr)) {
member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
}
} else {
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
index 2507465750c7f..e04dc76d1dbe0 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
@@ -662,8 +662,6 @@ size_t DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc,
form_value.BlockData() - debug_info_data.GetDataStart();
if (DWARFExpression::Evaluate(
NULL, // ExecutionContext *
- NULL, // ClangExpressionVariableList *
- NULL, // ClangExpressionDeclMap *
NULL, // RegisterContext *
module_sp, debug_info_data, die.GetCU(), block_offset,
block_length, eRegisterKindDWARF, &initialValue, NULL,
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
index 79b2acc4b4f38..5d7b12067263e 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -39,68 +39,48 @@ using namespace std;
extern int g_verbose;
DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF *dwarf2Data)
- : m_dwarf2Data(dwarf2Data), m_abbrevs(NULL), m_user_data(NULL),
- m_die_array(), m_func_aranges_ap(), m_base_addr(0),
- m_offset(DW_INVALID_OFFSET), m_length(0), m_version(0),
- m_addr_size(DWARFCompileUnit::GetDefaultAddressSize()),
- m_producer(eProducerInvalid), m_producer_version_major(0),
- m_producer_version_minor(0), m_producer_version_update(0),
- m_language_type(eLanguageTypeUnknown), m_is_dwarf64(false),
- m_is_optimized(eLazyBoolCalculate), m_addr_base(0),
- m_ranges_base(0), m_base_obj_offset(DW_INVALID_OFFSET) {}
+ : m_dwarf2Data(dwarf2Data) {}
DWARFCompileUnit::~DWARFCompileUnit() {}
-void DWARFCompileUnit::Clear() {
- m_offset = DW_INVALID_OFFSET;
- m_length = 0;
- m_version = 0;
- m_abbrevs = NULL;
- m_addr_size = DWARFCompileUnit::GetDefaultAddressSize();
- m_base_addr = 0;
- m_die_array.clear();
- m_func_aranges_ap.reset();
- m_user_data = NULL;
- m_producer = eProducerInvalid;
- m_language_type = eLanguageTypeUnknown;
- m_is_dwarf64 = false;
- m_is_optimized = eLazyBoolCalculate;
- m_addr_base = 0;
- m_base_obj_offset = DW_INVALID_OFFSET;
-}
+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;
-bool DWARFCompileUnit::Extract(const DWARFDataExtractor &debug_info,
- lldb::offset_t *offset_ptr) {
- Clear();
+ const DWARFDataExtractor &debug_info = dwarf2Data->get_debug_info_data();
- m_offset = *offset_ptr;
+ cu_sp->m_offset = *offset_ptr;
if (debug_info.ValidOffset(*offset_ptr)) {
dw_offset_t abbr_offset;
- const DWARFDebugAbbrev *abbr = m_dwarf2Data->DebugAbbrev();
- m_length = debug_info.GetDWARFInitialLength(offset_ptr);
- m_is_dwarf64 = debug_info.IsDWARF64();
- m_version = debug_info.GetU16(offset_ptr);
+ const DWARFDebugAbbrev *abbr = dwarf2Data->DebugAbbrev();
+ cu_sp->m_length = debug_info.GetDWARFInitialLength(offset_ptr);
+ cu_sp->m_is_dwarf64 = debug_info.IsDWARF64();
+ cu_sp->m_version = debug_info.GetU16(offset_ptr);
abbr_offset = debug_info.GetDWARFOffset(offset_ptr);
- m_addr_size = debug_info.GetU8(offset_ptr);
+ cu_sp->m_addr_size = debug_info.GetU8(offset_ptr);
- bool length_OK = debug_info.ValidOffset(GetNextCompileUnitOffset() - 1);
- bool version_OK = SymbolFileDWARF::SupportedVersion(m_version);
+ bool length_OK =
+ debug_info.ValidOffset(cu_sp->GetNextCompileUnitOffset() - 1);
+ bool version_OK = SymbolFileDWARF::SupportedVersion(cu_sp->m_version);
bool abbr_offset_OK =
- m_dwarf2Data->get_debug_abbrev_data().ValidOffset(abbr_offset);
- bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8));
+ dwarf2Data->get_debug_abbrev_data().ValidOffset(abbr_offset);
+ bool addr_size_OK = (cu_sp->m_addr_size == 4) || (cu_sp->m_addr_size == 8);
if (length_OK && version_OK && addr_size_OK && abbr_offset_OK &&
abbr != NULL) {
- m_abbrevs = abbr->GetAbbreviationDeclarationSet(abbr_offset);
- return true;
+ cu_sp->m_abbrevs = abbr->GetAbbreviationDeclarationSet(abbr_offset);
+ return cu_sp;
}
// reset the offset to where we tried to parse from if anything went wrong
- *offset_ptr = m_offset;
+ *offset_ptr = cu_sp->m_offset;
}
- return false;
+ return nullptr;
}
void DWARFCompileUnit::ClearDIEs(bool keep_compile_unit_die) {
@@ -620,6 +600,10 @@ void DWARFCompileUnit::Index(NameToDIE &func_basenames,
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) {
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
index 430251337575a..8ea0d6465adf4 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -18,6 +18,8 @@ class NameToDIE;
class SymbolFileDWARF;
class SymbolFileDWARFDwo;
+typedef std::shared_ptr<DWARFCompileUnit> DWARFCompileUnitSP;
+
class DWARFCompileUnit {
public:
enum Producer {
@@ -28,39 +30,35 @@ public:
eProcucerOther
};
- DWARFCompileUnit(SymbolFileDWARF *dwarf2Data);
+ static DWARFCompileUnitSP Extract(SymbolFileDWARF *dwarf2Data,
+ lldb::offset_t *offset_ptr);
~DWARFCompileUnit();
- bool Extract(const lldb_private::DWARFDataExtractor &debug_info,
- lldb::offset_t *offset_ptr);
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;
- void Clear();
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;
- uint32_t Size() const {
- return m_is_dwarf64 ? 23
- : 11; /* Size in bytes of the compile unit header */
- }
+ // 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_length + (m_is_dwarf64 ? 12 : 4);
+ 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_length + (m_is_dwarf64 ? 12 : 4) - Size(); /* Size in bytes of the
- .debug_info data
- associated with this
- compile unit. */
+ 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 {
@@ -165,7 +163,7 @@ protected:
SymbolFileDWARF *m_dwarf2Data;
std::unique_ptr<SymbolFileDWARFDwo> m_dwo_symbol_file;
const DWARFAbbreviationDeclarationSet *m_abbrevs;
- void *m_user_data;
+ 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
@@ -174,23 +172,24 @@ protected:
// points to the exact
// DW_TAG_subprogram
// DIEs
- dw_addr_t m_base_addr;
+ 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;
- uint32_t m_producer_version_major;
- uint32_t m_producer_version_minor;
- uint32_t m_producer_version_update;
- lldb::LanguageType m_language_type;
+ 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;
- dw_addr_t m_addr_base; // Value of DW_AT_addr_base
- dw_addr_t m_ranges_base; // Value of DW_AT_ranges_base
- dw_offset_t m_base_obj_offset; // If this is a dwo compile unit this is the
- // offset of the base compile unit in the main
- // object file
+ 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();
@@ -203,6 +202,8 @@ protected:
NameToDIE &globals, NameToDIE &types, NameToDIE &namespaces);
private:
+ DWARFCompileUnit(SymbolFileDWARF *dwarf2Data);
+
const DWARFDebugInfoEntry *GetCompileUnitDIEPtrOnly() {
ExtractDIEsIfNeeded(true);
if (m_die_array.empty())
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index 5222419d3233e..4ef2e772ea5d3 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -392,17 +392,11 @@ lldb::ModuleSP DWARFDIE::GetContainingDWOModule() const {
}
bool DWARFDIE::HasChildren() const {
- if (m_die)
- return m_die->HasChildren();
- else
- return false;
+ return m_die && m_die->HasChildren();
}
bool DWARFDIE::Supports_DW_AT_APPLE_objc_complete_type() const {
- if (IsValid())
- return GetDWARF()->Supports_DW_AT_APPLE_objc_complete_type(m_cu);
- else
- return false;
+ return IsValid() && GetDWARF()->Supports_DW_AT_APPLE_objc_complete_type(m_cu);
}
size_t DWARFDIE::GetAttributes(DWARFAttributes &attributes,
@@ -464,5 +458,5 @@ bool operator==(const DWARFDIE &lhs, const DWARFDIE &rhs) {
}
bool operator!=(const DWARFDIE &lhs, const DWARFDIE &rhs) {
- return lhs.GetDIE() != rhs.GetDIE() || lhs.GetCU() != rhs.GetCU();
+ return !(lhs == rhs);
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
index d681925daeacc..1cf0e7eeeb600 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
@@ -98,6 +98,21 @@ dw_uleb128_t DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential(
}
//----------------------------------------------------------------------
+// DWARFAbbreviationDeclarationSet::GetUnsupportedForms()
+//----------------------------------------------------------------------
+void DWARFAbbreviationDeclarationSet::GetUnsupportedForms(
+ std::set<dw_form_t> &invalid_forms) const {
+ for (const auto &abbr_decl : m_decls) {
+ const size_t num_attrs = abbr_decl.NumAttributes();
+ for (size_t i=0; i<num_attrs; ++i) {
+ dw_form_t form = abbr_decl.GetFormByIndex(i);
+ if (!DWARFFormValue::FormIsSupported(form))
+ invalid_forms.insert(form);
+ }
+ }
+}
+
+//----------------------------------------------------------------------
// Encode
//
// Encode the abbreviation table onto the end of the buffer provided
@@ -175,3 +190,12 @@ DWARFDebugAbbrev::GetAbbreviationDeclarationSet(
return &(pos->second);
return NULL;
}
+
+//----------------------------------------------------------------------
+// DWARFDebugAbbrev::GetUnsupportedForms()
+//----------------------------------------------------------------------
+void DWARFDebugAbbrev::GetUnsupportedForms(
+ std::set<dw_form_t> &invalid_forms) const {
+ for (const auto &pair : m_abbrevCollMap)
+ pair.second.GetUnsupportedForms(invalid_forms);
+}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
index 137c81780513c..2bacb6349b6fc 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
@@ -41,6 +41,7 @@ public:
// void Encode(BinaryStreamBuf& debug_abbrev_buf) const;
dw_uleb128_t
AppendAbbrevDeclSequential(const DWARFAbbreviationDeclaration &abbrevDecl);
+ void GetUnsupportedForms(std::set<dw_form_t> &invalid_forms) const;
const DWARFAbbreviationDeclaration *
GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const;
@@ -65,6 +66,7 @@ public:
GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const;
void Dump(lldb_private::Stream *s) const;
void Parse(const lldb_private::DWARFDataExtractor &data);
+ void GetUnsupportedForms(std::set<dw_form_t> &invalid_forms) const;
protected:
DWARFAbbreviationDeclarationCollMap m_abbrevCollMap;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
index eff9850d435dd..9c0f1d3c89056 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -97,17 +97,8 @@ void DWARFDebugInfo::ParseCompileUnitHeadersIfNeeded() {
if (m_compile_units.empty()) {
if (m_dwarf2Data != NULL) {
lldb::offset_t offset = 0;
- const DWARFDataExtractor &debug_info_data =
- m_dwarf2Data->get_debug_info_data();
- while (debug_info_data.ValidOffset(offset)) {
- DWARFCompileUnitSP cu_sp(new DWARFCompileUnit(m_dwarf2Data));
- // Out of memory?
- if (cu_sp.get() == NULL)
- break;
-
- if (cu_sp->Extract(debug_info_data, &offset) == false)
- break;
-
+ DWARFCompileUnitSP cu_sp;
+ while ((cu_sp = DWARFCompileUnit::Extract(m_dwarf2Data, &offset))) {
m_compile_units.push_back(cu_sp);
offset = cu_sp->GetNextCompileUnitOffset();
@@ -248,12 +239,10 @@ void DWARFDebugInfo::Parse(SymbolFileDWARF *dwarf2Data, Callback callback,
if (dwarf2Data) {
lldb::offset_t offset = 0;
uint32_t depth = 0;
- DWARFCompileUnitSP cu(new DWARFCompileUnit(dwarf2Data));
- if (cu.get() == NULL)
- return;
DWARFDebugInfoEntry die;
- while (cu->Extract(dwarf2Data->get_debug_info_data(), &offset)) {
+ DWARFCompileUnitSP cu;
+ while ((cu = DWARFCompileUnit::Extract(dwarf2Data, &offset))) {
const dw_offset_t next_cu_offset = cu->GetNextCompileUnitOffset();
depth = 0;
@@ -288,12 +277,6 @@ void DWARFDebugInfo::Parse(SymbolFileDWARF *dwarf2Data, Callback callback,
if (!dwarf2Data->get_debug_info_data().ValidOffset(offset))
break;
- // See if during the callback anyone retained a copy of the compile
- // unit other than ourselves and if so, let whomever did own the object
- // and create a new one for our own use!
- if (!cu.unique())
- cu.reset(new DWARFCompileUnit(dwarf2Data));
-
// Make sure we start on a proper
offset = next_cu_offset;
}
@@ -507,80 +490,3 @@ void DWARFDebugInfo::Dump(Stream *s, const uint32_t die_offset,
die.Dump(s, recurse_depth);
}
}
-
-//----------------------------------------------------------------------
-// FindCallbackString
-//
-// 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 will find the die_offset of any items whose DW_AT_name
-// matches the given string
-//----------------------------------------------------------------------
-typedef struct FindCallbackStringInfoTag {
- const char *name;
- bool ignore_case;
- RegularExpression *regex;
- vector<dw_offset_t> &die_offsets;
-} FindCallbackStringInfo;
-
-static dw_offset_t
-FindCallbackString(SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
- DWARFDebugInfoEntry *die, const dw_offset_t next_offset,
- const uint32_t curr_depth, void *userData) {
- FindCallbackStringInfo *info = (FindCallbackStringInfo *)userData;
-
- if (!die)
- return next_offset;
-
- const char *die_name = die->GetName(dwarf2Data, cu);
- if (!die_name)
- return next_offset;
-
- if (info->regex) {
- if (info->regex->Execute(llvm::StringRef(die_name)))
- info->die_offsets.push_back(die->GetOffset());
- } else {
- if ((info->ignore_case ? strcasecmp(die_name, info->name)
- : strcmp(die_name, info->name)) == 0)
- info->die_offsets.push_back(die->GetOffset());
- }
-
- // Just return the current offset to parse the next CU or DIE entry
- return next_offset;
-}
-
-//----------------------------------------------------------------------
-// Find
-//
-// Finds all DIE that have a specific DW_AT_name attribute by manually
-// searching through the debug information (not using the
-// .debug_pubnames section). The string must match the entire name
-// and case sensitive searches are an option.
-//----------------------------------------------------------------------
-bool DWARFDebugInfo::Find(const char *name, bool ignore_case,
- vector<dw_offset_t> &die_offsets) const {
- die_offsets.clear();
- if (name && name[0]) {
- FindCallbackStringInfo info = {name, ignore_case, NULL, die_offsets};
- DWARFDebugInfo::Parse(m_dwarf2Data, FindCallbackString, &info);
- }
- return !die_offsets.empty();
-}
-
-//----------------------------------------------------------------------
-// Find
-//
-// Finds all DIE that have a specific DW_AT_name attribute by manually
-// searching through the debug information (not using the
-// .debug_pubnames section). The string must match the supplied regular
-// expression.
-//----------------------------------------------------------------------
-bool DWARFDebugInfo::Find(RegularExpression &re,
- vector<dw_offset_t> &die_offsets) const {
- die_offsets.clear();
- FindCallbackStringInfo info = {NULL, false, &re, die_offsets};
- DWARFDebugInfo::Parse(m_dwarf2Data, FindCallbackString, &info);
- return !die_offsets.empty();
-}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
index be4e18b12be0b..14c7d767d05b4 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
@@ -50,10 +50,6 @@ public:
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);
- bool Find(const char *name, bool ignore_case,
- std::vector<dw_offset_t> &die_offsets) const;
- bool Find(lldb_private::RegularExpression &re,
- std::vector<dw_offset_t> &die_offsets) const;
enum {
eDumpFlag_Verbose = (1 << 0), // Verbose dumping
@@ -65,8 +61,6 @@ public:
DWARFDebugAranges &GetCompileUnitAranges();
protected:
- typedef std::shared_ptr<DWARFCompileUnit> DWARFCompileUnitSP;
-
static bool OffsetLessThanCompileUnitOffset(dw_offset_t offset,
const DWARFCompileUnitSP &cu_sp);
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index 8d87c201eceb2..f595bd83d8469 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -161,9 +161,9 @@ bool DWARFDebugInfoEntry::FastExtract(
case DW_FORM_strp:
case DW_FORM_sec_offset:
if (cu->IsDWARF64())
- debug_info_data.GetU64(offset_ptr);
+ debug_info_data.GetU64(&offset);
else
- debug_info_data.GetU32(offset_ptr);
+ debug_info_data.GetU32(&offset);
break;
default:
@@ -325,9 +325,9 @@ bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data,
case DW_FORM_strp:
case DW_FORM_sec_offset:
if (cu->IsDWARF64())
- debug_info_data.GetU64(offset_ptr);
+ debug_info_data.GetU64(&offset);
else
- debug_info_data.GetU32(offset_ptr);
+ debug_info_data.GetU32(&offset);
break;
default:
@@ -1314,19 +1314,6 @@ bool DWARFDebugInfoEntry::AppendTypeName(SymbolFileDWARF *dwarf2Data,
return false;
}
-bool DWARFDebugInfoEntry::Contains(const DWARFDebugInfoEntry *die) const {
- if (die) {
- const dw_offset_t die_offset = die->GetOffset();
- if (die_offset > GetOffset()) {
- const DWARFDebugInfoEntry *sibling = GetSibling();
- assert(sibling); // TODO: take this out
- if (sibling)
- return die_offset < sibling->GetOffset();
- }
- }
- return false;
-}
-
//----------------------------------------------------------------------
// BuildAddressRangeTable
//----------------------------------------------------------------------
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
index 15abac77a475d..89450d327adfd 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -60,18 +60,6 @@ public:
m_empty_children(false), m_abbr_idx(0), m_has_children(false),
m_tag(0) {}
- void Clear() {
- m_offset = DW_INVALID_OFFSET;
- m_parent_idx = 0;
- m_sibling_idx = 0;
- m_empty_children = false;
- m_abbr_idx = 0;
- m_has_children = false;
- m_tag = 0;
- }
-
- bool Contains(const DWARFDebugInfoEntry *die) const;
-
void BuildAddressRangeTable(SymbolFileDWARF *dwarf2Data,
const DWARFCompileUnit *cu,
DWARFDebugAranges *debug_aranges) const;
@@ -211,8 +199,6 @@ public:
dw_offset_t GetOffset() const { return m_offset; }
- void SetOffset(dw_offset_t offset) { m_offset = offset; }
-
bool HasChildren() const { return m_has_children; }
void SetHasChildren(bool b) { m_has_children = b; }
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
index 515c083fedb08..a8c48b7f2f849 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
@@ -15,6 +15,18 @@
using namespace lldb_private;
using namespace std;
+static dw_addr_t GetBaseAddressMarker(uint32_t addr_size) {
+ switch(addr_size) {
+ case 2:
+ return 0xffff;
+ case 4:
+ return 0xffffffff;
+ case 8:
+ return 0xffffffffffffffff;
+ }
+ llvm_unreachable("GetBaseAddressMarker unsupported address size.");
+}
+
DWARFDebugRanges::DWARFDebugRanges() : m_range_map() {}
DWARFDebugRanges::~DWARFDebugRanges() {}
@@ -39,38 +51,27 @@ bool DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data,
const DWARFDataExtractor &debug_ranges_data =
dwarf2Data->get_debug_ranges_data();
uint32_t addr_size = debug_ranges_data.GetAddressByteSize();
+ dw_addr_t base_addr = 0;
+ dw_addr_t base_addr_marker = GetBaseAddressMarker(addr_size);
while (
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);
+
if (!begin && !end) {
// End of range list
break;
}
- // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits
- // of ones
- switch (addr_size) {
- case 2:
- if (begin == 0xFFFFull)
- begin = LLDB_INVALID_ADDRESS;
- break;
-
- case 4:
- if (begin == 0xFFFFFFFFull)
- begin = LLDB_INVALID_ADDRESS;
- break;
- case 8:
- break;
-
- default:
- llvm_unreachable("DWARFRangeList::Extract() unsupported address size.");
+ if (begin == base_addr_marker) {
+ base_addr = end;
+ continue;
}
// Filter out empty ranges
if (begin < end)
- range_list.Append(DWARFRangeList::Entry(begin, end - begin));
+ range_list.Append(DWARFRangeList::Entry(begin + base_addr, end - begin));
}
// Make sure we consumed at least something
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
index 0853671ee8749..a21e313c2f811 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -725,3 +725,39 @@ int DWARFFormValue::Compare(const DWARFFormValue &a_value,
}
return -1;
}
+
+bool DWARFFormValue::FormIsSupported(dw_form_t form) {
+ switch (form) {
+ case DW_FORM_addr:
+ case DW_FORM_block2:
+ case DW_FORM_block4:
+ case DW_FORM_data2:
+ case DW_FORM_data4:
+ case DW_FORM_data8:
+ case DW_FORM_string:
+ case DW_FORM_block:
+ case DW_FORM_block1:
+ case DW_FORM_data1:
+ case DW_FORM_flag:
+ case DW_FORM_sdata:
+ case DW_FORM_strp:
+ case DW_FORM_udata:
+ case DW_FORM_ref_addr:
+ case DW_FORM_ref1:
+ case DW_FORM_ref2:
+ case DW_FORM_ref4:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_udata:
+ case DW_FORM_indirect:
+ case DW_FORM_sec_offset:
+ case DW_FORM_exprloc:
+ case DW_FORM_flag_present:
+ case DW_FORM_ref_sig8:
+ case DW_FORM_GNU_str_index:
+ case DW_FORM_GNU_addr_index:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
index 8d6af3d65b331..2aa7460c49109 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
@@ -86,6 +86,7 @@ public:
bool is_dwarf64);
static int Compare(const DWARFFormValue &a, const DWARFFormValue &b);
void Clear();
+ static bool FormIsSupported(dw_form_t form);
protected:
const DWARFCompileUnit *m_cu; // Compile unit for this form
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index ef18c2b5d3bab..f149ec354f08c 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -13,7 +13,6 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/Threading.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
@@ -22,6 +21,7 @@
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/Value.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
@@ -30,6 +30,7 @@
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
+#include "lldb/Host/Symbols.h"
#include "lldb/Interpreter/OptionValueFileSpecList.h"
#include "lldb/Interpreter/OptionValueProperties.h"
@@ -53,7 +54,7 @@
#include "lldb/Target/Language.h"
-#include "lldb/Utility/TaskPool.h"
+#include "lldb/Host/TaskPool.h"
#include "DWARFASTParser.h"
#include "DWARFASTParserClang.h"
@@ -71,6 +72,7 @@
#include "LogChannelDWARF.h"
#include "SymbolFileDWARFDebugMap.h"
#include "SymbolFileDWARFDwo.h"
+#include "SymbolFileDWARFDwp.h"
#include "llvm/Support/FileSystem.h"
@@ -207,6 +209,10 @@ static const char *resolveCompDir(const char *path_from_dwarf) {
return nullptr;
}
+DWARFCompileUnit *SymbolFileDWARF::GetBaseCompileUnit() {
+ return nullptr;
+}
+
void SymbolFileDWARF::Initialize() {
LogChannelDWARF::Initialize();
PluginManager::RegisterPlugin(GetPluginNameStatic(),
@@ -435,13 +441,11 @@ void SymbolFileDWARF::InitializeObject() {
ModuleSP module_sp(m_obj_file->GetModule());
if (module_sp) {
const SectionList *section_list = module_sp->GetSectionList();
- const Section *section =
+ Section *section =
section_list->FindSectionByName(GetDWARFMachOSegmentName()).get();
- // Memory map the DWARF mach-o segment so we have everything mmap'ed
- // to keep our heap memory usage down.
if (section)
- m_obj_file->MemoryMapSectionData(section, m_dwarf_data);
+ m_obj_file->ReadSectionData(section, m_dwarf_data);
}
get_apple_names_data();
@@ -497,6 +501,21 @@ 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.
+ if (section_list->FindSectionByName(ConstString(".debug_types"))) {
+ m_obj_file->GetModule()->ReportWarning(
+ "lldb doesn’t support .debug_types debug info");
+ return 0;
+ }
+
uint64_t debug_abbrev_file_size = 0;
uint64_t debug_info_file_size = 0;
uint64_t debug_line_file_size = 0;
@@ -517,6 +536,20 @@ uint32_t SymbolFileDWARF::CalculateAbilities() {
if (section)
debug_abbrev_file_size = section->GetFileSize();
+ DWARFDebugAbbrev *abbrev = DebugAbbrev();
+ if (abbrev) {
+ std::set<dw_form_t> invalid_forms;
+ abbrev->GetUnsupportedForms(invalid_forms);
+ if (!invalid_forms.empty()) {
+ StreamString error;
+ error.Printf("unsupported DW_FORM value%s:", invalid_forms.size() > 1 ? "s" : "");
+ for (auto form : invalid_forms)
+ error.Printf(" %#x", form);
+ m_obj_file->GetModule()->ReportWarning("%s", error.GetString().str().c_str());
+ return 0;
+ }
+ }
+
section =
section_list->FindSectionByType(eSectionTypeDWARFDebugLine, true)
.get();
@@ -1539,6 +1572,16 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
if (!dwo_name)
return nullptr;
+ SymbolFileDWARFDwp *dwp_symfile = GetDwpSymbolFile();
+ if (dwp_symfile) {
+ uint64_t dwo_id = cu_die.GetAttributeValueAsUnsigned(this, &dwarf_cu,
+ DW_AT_GNU_dwo_id, 0);
+ std::unique_ptr<SymbolFileDWARFDwo> dwo_symfile =
+ dwp_symfile->GetSymbolFileForDwoId(&dwarf_cu, dwo_id);
+ if (dwo_symfile)
+ return dwo_symfile;
+ }
+
FileSpec dwo_file(dwo_name, true);
if (dwo_file.IsRelative()) {
const char *comp_dir = cu_die.GetAttributeValueAsString(
@@ -1600,7 +1643,29 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
}
dwo_module_spec.GetArchitecture() =
m_obj_file->GetModule()->GetArchitecture();
- // printf ("Loading dwo = '%s'\n", dwo_path);
+
+ // 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" &&
+ llvm::StringRef(m_obj_file->GetFileSpec().GetPath())
+ .endswith(dwo_module_spec.GetFileSpec().GetPath())) {
+ continue;
+ }
+
Status error = ModuleList::GetSharedModule(
dwo_module_spec, module_sp, NULL, NULL, NULL);
if (!module_sp) {
@@ -1640,9 +1705,8 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() {
const DWARFExpression &location = var_sp->LocationExpression();
Value location_result;
Status error;
- if (location.Evaluate(nullptr, nullptr, nullptr,
- LLDB_INVALID_ADDRESS, nullptr, nullptr,
- location_result, &error)) {
+ if (location.Evaluate(nullptr, LLDB_INVALID_ADDRESS, nullptr,
+ nullptr, location_result, &error)) {
if (location_result.GetValueType() ==
Value::eValueTypeFileAddress) {
lldb::addr_t file_addr =
@@ -4288,3 +4352,18 @@ DWARFExpression::LocationListFormat
SymbolFileDWARF::GetLocationListFormat() const {
return DWARFExpression::RegularLocationList;
}
+
+SymbolFileDWARFDwp *SymbolFileDWARF::GetDwpSymbolFile() {
+ llvm::call_once(m_dwp_symfile_once_flag, [this]() {
+ ModuleSpec module_spec;
+ module_spec.GetFileSpec() = m_obj_file->GetFileSpec();
+ module_spec.GetSymbolFileSpec() =
+ FileSpec(m_obj_file->GetFileSpec().GetPath() + ".dwp", false);
+ FileSpec dwp_filespec = Symbols::LocateExecutableSymbolFile(module_spec);
+ if (dwp_filespec.Exists()) {
+ m_dwp_symfile = SymbolFileDWARFDwp::Create(GetObjectFile()->GetModule(),
+ dwp_filespec);
+ }
+ });
+ return m_dwp_symfile.get();
+}
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 9b1eb1d76fea9..6902dc0333d2f 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -61,6 +61,7 @@ class DWARFDIECollection;
class DWARFFormValue;
class SymbolFileDWARFDebugMap;
class SymbolFileDWARFDwo;
+class SymbolFileDWARFDwp;
#define DIE_IS_BEING_PARSED ((lldb_private::Type *)1)
@@ -275,8 +276,8 @@ public:
GetCompUnitForDWARFCompUnit(DWARFCompileUnit *dwarf_cu,
uint32_t cu_idx = UINT32_MAX);
- size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name,
- DIEArray &method_die_offsets);
+ virtual size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name,
+ DIEArray &method_die_offsets);
bool Supports_DW_AT_APPLE_objc_complete_type(DWARFCompileUnit *cu);
@@ -298,6 +299,11 @@ public:
GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &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();
+
protected:
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *>
DIEToTypePtr;
@@ -391,14 +397,10 @@ protected:
virtual lldb::TypeSP
FindDefinitionTypeForDWARFDeclContext(const DWARFDeclContext &die_decl_ctx);
- lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(
+ virtual lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(
const DWARFDIE &die, const lldb_private::ConstString &type_name,
bool must_be_implementation);
- lldb::TypeSP
- FindCompleteObjCDefinitionType(const lldb_private::ConstString &type_name,
- bool header_definition_ok);
-
lldb_private::Symbol *
GetObjCClassSymbol(const lldb_private::ConstString &objc_class_name);
@@ -464,8 +466,14 @@ protected:
return m_forward_decl_clang_type_to_die;
}
+ SymbolFileDWARFDwp *GetDwpSymbolFile();
+
lldb::ModuleWP m_debug_map_module_wp;
SymbolFileDWARFDebugMap *m_debug_map_symfile;
+
+ llvm::once_flag m_dwp_symfile_once_flag;
+ std::unique_ptr<SymbolFileDWARFDwp> m_dwp_symfile;
+
lldb_private::DWARFDataExtractor m_dwarf_data;
DWARFDataSegment m_data_debug_abbrev;
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
index c14ebd1628be6..17c188a41a773 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -61,6 +61,14 @@ SymbolFileDWARFDwo::ParseCompileUnit(DWARFCompileUnit *dwarf_cu,
}
DWARFCompileUnit *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))
+ if (auto section_sp =
+ section_list->FindSectionByType(eSectionTypeDWARFDebugInfo, true))
+ if (!section_sp->GetName().GetStringRef().endswith("dwo"))
+ return nullptr;
+
// Only dwo files with 1 compile unit is supported
if (GetNumCompileUnits() == 1)
return DebugInfo()->GetCompileUnitAtIndex(0);
@@ -91,6 +99,12 @@ SymbolFileDWARFDwo::GetForwardDeclClangTypeToDie() {
return GetBaseSymbolFile()->GetForwardDeclClangTypeToDie();
}
+size_t SymbolFileDWARFDwo::GetObjCMethodDIEOffsets(
+ lldb_private::ConstString class_name, DIEArray &method_die_offsets) {
+ return GetBaseSymbolFile()->GetObjCMethodDIEOffsets(
+ class_name, method_die_offsets);
+}
+
UniqueDWARFASTTypeMap &SymbolFileDWARFDwo::GetUniqueDWARFASTTypeMap() {
return GetBaseSymbolFile()->GetUniqueDWARFASTTypeMap();
}
@@ -101,6 +115,17 @@ lldb::TypeSP SymbolFileDWARFDwo::FindDefinitionTypeForDWARFDeclContext(
die_decl_ctx);
}
+lldb::TypeSP SymbolFileDWARFDwo::FindCompleteObjCDefinitionTypeForDIE(
+ const DWARFDIE &die, const lldb_private::ConstString &type_name,
+ bool must_be_implementation) {
+ return GetBaseSymbolFile()->FindCompleteObjCDefinitionTypeForDIE(
+ die, type_name, must_be_implementation);
+}
+
+DWARFCompileUnit *SymbolFileDWARFDwo::GetBaseCompileUnit() {
+ return m_base_dwarf_cu;
+}
+
SymbolFileDWARF *SymbolFileDWARFDwo::GetBaseSymbolFile() {
return m_base_dwarf_cu->GetSymbolFileDWARF();
}
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
index 8cd67a2b24247..b67967aafab26 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -33,6 +33,9 @@ public:
lldb_private::DWARFExpression::LocationListFormat
GetLocationListFormat() const override;
+ size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name,
+ DIEArray &method_die_offsets) override;
+
lldb_private::TypeSystem *
GetTypeSystemForLanguage(lldb::LanguageType language) override;
@@ -45,6 +48,8 @@ public:
return nullptr;
}
+ DWARFCompileUnit *GetBaseCompileUnit() override;
+
protected:
void LoadSectionData(lldb::SectionType sect_type,
lldb_private::DWARFDataExtractor &data) override;
@@ -62,6 +67,10 @@ protected:
lldb::TypeSP FindDefinitionTypeForDWARFDeclContext(
const DWARFDeclContext &die_decl_ctx) override;
+ lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(
+ const DWARFDIE &die, const lldb_private::ConstString &type_name,
+ bool must_be_implementation) override;
+
SymbolFileDWARF *GetBaseSymbolFile();
lldb::ObjectFileSP m_obj_file_sp;
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp
new file mode 100644
index 0000000000000..f6de1818eae08
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp
@@ -0,0 +1,36 @@
+//===-- SymbolFileDWARFDwoDwp.cpp -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SymbolFileDWARFDwoDwp.h"
+
+#include "lldb/Core/Section.h"
+#include "lldb/Expression/DWARFExpression.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/LLDBAssert.h"
+
+#include "DWARFCompileUnit.h"
+#include "DWARFDebugInfo.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+SymbolFileDWARFDwoDwp::SymbolFileDWARFDwoDwp(SymbolFileDWARFDwp *dwp_symfile,
+ ObjectFileSP objfile,
+ DWARFCompileUnit *dwarf_cu,
+ uint64_t dwo_id)
+ : SymbolFileDWARFDwo(objfile, dwarf_cu), m_dwp_symfile(dwp_symfile),
+ m_dwo_id(dwo_id) {}
+
+void SymbolFileDWARFDwoDwp::LoadSectionData(lldb::SectionType sect_type,
+ DWARFDataExtractor &data) {
+ if (m_dwp_symfile->LoadSectionData(m_dwo_id, sect_type, data))
+ return;
+
+ SymbolFileDWARF::LoadSectionData(sect_type, data);
+}
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h
new file mode 100644
index 0000000000000..00ad7aafd96b0
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h
@@ -0,0 +1,34 @@
+//===-- SymbolFileDWARFDwoDwp.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SymbolFileDWARFDwoDwp_SymbolFileDWARFDwoDwp_h_
+#define SymbolFileDWARFDwoDwp_SymbolFileDWARFDwoDwp_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "SymbolFileDWARFDwo.h"
+#include "SymbolFileDWARFDwp.h"
+
+class SymbolFileDWARFDwoDwp : public SymbolFileDWARFDwo {
+public:
+ SymbolFileDWARFDwoDwp(SymbolFileDWARFDwp *dwp_symfile,
+ lldb::ObjectFileSP objfile, DWARFCompileUnit *dwarf_cu,
+ uint64_t dwo_id);
+
+protected:
+ void LoadSectionData(lldb::SectionType sect_type,
+ lldb_private::DWARFDataExtractor &data) override;
+
+ SymbolFileDWARFDwp *m_dwp_symfile;
+ uint64_t m_dwo_id;
+};
+
+#endif // SymbolFileDWARFDwoDwp_SymbolFileDWARFDwoDwp_h_
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
new file mode 100644
index 0000000000000..1dc1dab34a5c4
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
@@ -0,0 +1,142 @@
+//===-- SymbolFileDWARFDwp.cpp ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SymbolFileDWARFDwp.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Section.h"
+#include "lldb/Symbol/ObjectFile.h"
+
+#include "SymbolFileDWARFDwoDwp.h"
+
+static llvm::DWARFSectionKind
+lldbSectTypeToLlvmSectionKind(lldb::SectionType type) {
+ switch (type) {
+ case lldb::eSectionTypeDWARFDebugInfo:
+ return llvm::DW_SECT_INFO;
+ // case lldb::eSectionTypeDWARFDebugTypes:
+ // return llvm::DW_SECT_TYPES;
+ case lldb::eSectionTypeDWARFDebugAbbrev:
+ return llvm::DW_SECT_ABBREV;
+ case lldb::eSectionTypeDWARFDebugLine:
+ return llvm::DW_SECT_LINE;
+ case lldb::eSectionTypeDWARFDebugLoc:
+ return llvm::DW_SECT_LOC;
+ case lldb::eSectionTypeDWARFDebugStrOffsets:
+ return llvm::DW_SECT_STR_OFFSETS;
+ // case lldb::eSectionTypeDWARFDebugMacinfo:
+ // return llvm::DW_SECT_MACINFO;
+ case lldb::eSectionTypeDWARFDebugMacro:
+ return llvm::DW_SECT_MACRO;
+ default:
+ // Note: 0 is an invalid dwarf section kind.
+ return llvm::DWARFSectionKind(0);
+ }
+}
+
+std::unique_ptr<SymbolFileDWARFDwp>
+SymbolFileDWARFDwp::Create(lldb::ModuleSP module_sp,
+ const lldb_private::FileSpec &file_spec) {
+ const lldb::offset_t file_offset = 0;
+ lldb::DataBufferSP file_data_sp;
+ lldb::offset_t file_data_offset = 0;
+ lldb::ObjectFileSP obj_file = lldb_private::ObjectFile::FindPlugin(
+ module_sp, &file_spec, file_offset, file_spec.GetByteSize(), file_data_sp,
+ file_data_offset);
+ if (obj_file == nullptr)
+ return nullptr;
+
+ std::unique_ptr<SymbolFileDWARFDwp> dwp_symfile(
+ new SymbolFileDWARFDwp(module_sp, obj_file));
+
+ lldb_private::DWARFDataExtractor debug_cu_index;
+ if (!dwp_symfile->LoadRawSectionData(lldb::eSectionTypeDWARFDebugCuIndex,
+ debug_cu_index))
+ return nullptr;
+
+ llvm::DataExtractor llvm_debug_cu_index(
+ llvm::StringRef(debug_cu_index.PeekCStr(0), debug_cu_index.GetByteSize()),
+ debug_cu_index.GetByteOrder() == lldb::eByteOrderLittle,
+ debug_cu_index.GetAddressByteSize());
+ if (!dwp_symfile->m_debug_cu_index.parse(llvm_debug_cu_index))
+ return nullptr;
+ dwp_symfile->InitDebugCUIndexMap();
+ return dwp_symfile;
+}
+
+void SymbolFileDWARFDwp::InitDebugCUIndexMap() {
+ m_debug_cu_index_map.clear();
+ for (const auto &entry : m_debug_cu_index.getRows())
+ m_debug_cu_index_map.emplace(entry.getSignature(), &entry);
+}
+
+SymbolFileDWARFDwp::SymbolFileDWARFDwp(lldb::ModuleSP module_sp,
+ lldb::ObjectFileSP obj_file)
+ : m_obj_file(std::move(obj_file)), m_debug_cu_index(llvm::DW_SECT_INFO)
+{}
+
+std::unique_ptr<SymbolFileDWARFDwo>
+SymbolFileDWARFDwp::GetSymbolFileForDwoId(DWARFCompileUnit *dwarf_cu,
+ uint64_t dwo_id) {
+ return std::unique_ptr<SymbolFileDWARFDwo>(
+ new SymbolFileDWARFDwoDwp(this, m_obj_file, dwarf_cu, dwo_id));
+}
+
+bool SymbolFileDWARFDwp::LoadSectionData(
+ uint64_t dwo_id, lldb::SectionType sect_type,
+ lldb_private::DWARFDataExtractor &data) {
+ lldb_private::DWARFDataExtractor section_data;
+ if (!LoadRawSectionData(sect_type, section_data))
+ return false;
+
+ auto it = m_debug_cu_index_map.find(dwo_id);
+ if (it == m_debug_cu_index_map.end())
+ return false;
+
+ auto *offsets =
+ it->second->getOffset(lldbSectTypeToLlvmSectionKind(sect_type));
+ if (offsets) {
+ data.SetData(section_data, offsets->Offset, offsets->Length);
+ } else {
+ data.SetData(section_data, 0, section_data.GetByteSize());
+ }
+ return true;
+}
+
+bool SymbolFileDWARFDwp::LoadRawSectionData(
+ lldb::SectionType sect_type, lldb_private::DWARFDataExtractor &data) {
+ std::lock_guard<std::mutex> lock(m_sections_mutex);
+
+ auto it = m_sections.find(sect_type);
+ if (it != m_sections.end()) {
+ if (it->second.GetByteSize() == 0)
+ return false;
+
+ data = it->second;
+ return true;
+ }
+
+ const lldb_private::SectionList *section_list =
+ m_obj_file->GetSectionList(false /* update_module_section_list */);
+ if (section_list) {
+ lldb::SectionSP section_sp(
+ section_list->FindSectionByType(sect_type, true));
+ if (section_sp) {
+ if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0) {
+ m_sections[sect_type] = data;
+ return true;
+ }
+ }
+ }
+ m_sections[sect_type].Clear();
+ return false;
+}
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h
new file mode 100644
index 0000000000000..a7372b9358b16
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h
@@ -0,0 +1,55 @@
+//===-- SymbolFileDWARFDwp.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SymbolFileDWARFDwp_SymbolFileDWARFDwp_h_
+#define SymbolFileDWARFDwp_SymbolFileDWARFDwp_h_
+
+// C Includes
+// C++ Includes
+#include <memory>
+
+// Other libraries and framework includes
+#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
+
+// Project includes
+#include "lldb/Core/Module.h"
+
+#include "DWARFDataExtractor.h"
+#include "SymbolFileDWARFDwo.h"
+
+class SymbolFileDWARFDwp {
+public:
+ static std::unique_ptr<SymbolFileDWARFDwp>
+ Create(lldb::ModuleSP module_sp, const lldb_private::FileSpec &file_spec);
+
+ std::unique_ptr<SymbolFileDWARFDwo>
+ GetSymbolFileForDwoId(DWARFCompileUnit *dwarf_cu, uint64_t dwo_id);
+
+ bool LoadSectionData(uint64_t dwo_id, lldb::SectionType sect_type,
+ lldb_private::DWARFDataExtractor &data);
+
+private:
+ explicit SymbolFileDWARFDwp(lldb::ModuleSP module_sp,
+ lldb::ObjectFileSP obj_file);
+
+ bool LoadRawSectionData(lldb::SectionType sect_type,
+ lldb_private::DWARFDataExtractor &data);
+
+ void InitDebugCUIndexMap();
+
+ lldb::ObjectFileSP m_obj_file;
+
+ std::mutex m_sections_mutex;
+ std::map<lldb::SectionType, lldb_private::DWARFDataExtractor> m_sections;
+
+ llvm::DWARFUnitIndex m_debug_cu_index;
+ std::map<uint64_t, const llvm::DWARFUnitIndex::Entry *> m_debug_cu_index_map;
+};
+
+#endif // SymbolFileDWARFDwp_SymbolFileDWARFDwp_h_
diff --git a/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
index b48de2e591e32..9b98ebe112a24 100644
--- a/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
+++ b/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -95,11 +95,11 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
- return std::make_shared<Type>(type.getSymIndexId(), m_ast.GetSymbolFile(),
- ConstString(udt->getName()), udt->getLength(),
- nullptr, LLDB_INVALID_UID,
- Type::eEncodingIsUID, decl, clang_type,
- Type::eResolveStateForward);
+ return std::make_shared<lldb_private::Type>(
+ type.getSymIndexId(), m_ast.GetSymbolFile(),
+ 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();
lldb::Encoding encoding =
@@ -109,7 +109,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
m_ast.GetBuiltinTypeForEncodingAndBitSize(encoding, bytes * 8);
CompilerType ast_enum = m_ast.CreateEnumerationType(
- name.c_str(), tu_decl_ctx, decl, builtin_type);
+ name.c_str(), tu_decl_ctx, decl, builtin_type, false);
auto enum_values = enum_type->findAllChildren<PDBSymbolData>();
while (auto enum_value = enum_values->getNext()) {
if (enum_value->getDataKind() != PDB_DataKind::Constant)
@@ -117,12 +117,12 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
AddEnumValue(ast_enum, *enum_value);
}
- return std::make_shared<Type>(type.getSymIndexId(), m_ast.GetSymbolFile(),
- ConstString(name), bytes, nullptr,
- LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
- ast_enum, Type::eResolveStateFull);
+ 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)) {
- Type *target_type =
+ lldb_private::Type *target_type =
m_ast.GetSymbolFile()->ResolveTypeUID(type_def->getTypeId());
std::string name = type_def->getName();
uint64_t bytes = type_def->getLength();
@@ -133,16 +133,17 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
m_ast.GetSymbolFile()->GetDeclContextForUID(target_type->GetID());
CompilerType ast_typedef =
m_ast.CreateTypedefType(target_ast_type, name.c_str(), target_decl_ctx);
- return std::make_shared<Type>(
+ return std::make_shared<lldb_private::Type>(
type_def->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name),
- bytes, nullptr, target_type->GetID(), Type::eEncodingIsTypedefUID, decl,
- ast_typedef, Type::eResolveStateFull);
+ 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)) {
auto arg_enum = func_sig->getArguments();
uint32_t num_args = arg_enum->getChildCount();
std::vector<CompilerType> arg_list(num_args);
while (auto arg = arg_enum->getNext()) {
- Type *arg_type =
+ 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
// function signature, bail.
@@ -152,7 +153,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
arg_list.push_back(arg_ast_type);
}
auto pdb_return_type = func_sig->getReturnType();
- Type *return_type =
+ lldb_private::Type *return_type =
m_ast.GetSymbolFile()->ResolveTypeUID(pdb_return_type->getSymIndexId());
// If there's some error looking up one of the dependent types of this
// function signature, bail.
@@ -167,23 +168,24 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
CompilerType func_sig_ast_type = m_ast.CreateFunctionType(
return_ast_type, &arg_list[0], num_args, false, type_quals);
- return std::make_shared<Type>(
+ return std::make_shared<lldb_private::Type>(
func_sig->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(), 0,
- nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
- func_sig_ast_type, Type::eResolveStateFull);
+ 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)) {
uint32_t num_elements = array_type->getCount();
uint32_t element_uid = array_type->getElementType()->getSymIndexId();
uint32_t bytes = array_type->getLength();
- Type *element_type = m_ast.GetSymbolFile()->ResolveTypeUID(element_uid);
+ lldb_private::Type *element_type =
+ m_ast.GetSymbolFile()->ResolveTypeUID(element_uid);
CompilerType element_ast_type = element_type->GetFullCompilerType();
CompilerType array_ast_type =
m_ast.CreateArrayType(element_ast_type, num_elements, false);
- return std::make_shared<Type>(
+ return std::make_shared<lldb_private::Type>(
array_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(),
- bytes, nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
- array_ast_type, Type::eResolveStateFull);
+ bytes, nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID,
+ decl, array_ast_type, lldb_private::Type::eResolveStateFull);
}
return nullptr;
}
diff --git a/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp b/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
index f952696ab21dd..a25119684c288 100644
--- a/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
+++ b/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
@@ -127,13 +127,14 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList();
static const SectionType g_sections[] = {
- eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr,
- eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugFrame,
- eSectionTypeDWARFDebugInfo, eSectionTypeDWARFDebugLine,
- eSectionTypeDWARFDebugLoc, eSectionTypeDWARFDebugMacInfo,
- eSectionTypeDWARFDebugPubNames, eSectionTypeDWARFDebugPubTypes,
- eSectionTypeDWARFDebugRanges, eSectionTypeDWARFDebugStr,
- eSectionTypeDWARFDebugStrOffsets, eSectionTypeELFSymbolTable,
+ eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr,
+ eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugCuIndex,
+ eSectionTypeDWARFDebugFrame, eSectionTypeDWARFDebugInfo,
+ eSectionTypeDWARFDebugLine, eSectionTypeDWARFDebugLoc,
+ eSectionTypeDWARFDebugMacInfo, eSectionTypeDWARFDebugPubNames,
+ eSectionTypeDWARFDebugPubTypes, eSectionTypeDWARFDebugRanges,
+ eSectionTypeDWARFDebugStr, eSectionTypeDWARFDebugStrOffsets,
+ eSectionTypeELFSymbolTable,
};
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 6d6abd62dad2a..b3fb05e652d96 100644
--- a/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
+++ b/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
@@ -220,6 +220,7 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
// the original
// gloal DBGSourcePath string.
bool new_style_source_remapping_dictionary = false;
+ bool do_truncate_remapping_names = false;
std::string original_DBGSourcePath_value =
DBGSourcePath;
if (plist_sp->GetAsDictionary()->HasKey("DBGVersion")) {
@@ -233,6 +234,9 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
if (version_number > 1) {
new_style_source_remapping_dictionary = true;
}
+ if (version_number == 2) {
+ do_truncate_remapping_names = true;
+ }
}
}
@@ -242,7 +246,7 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
->GetAsDictionary();
remappings_dict->ForEach(
[&module_sp, new_style_source_remapping_dictionary,
- original_DBGSourcePath_value](
+ original_DBGSourcePath_value, do_truncate_remapping_names](
ConstString key,
StructuredData::Object *object) -> bool {
if (object && object->GetAsString()) {
@@ -264,6 +268,21 @@ 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.
+ if (do_truncate_remapping_names) {
+ FileSpec build_path(key.AsCString(), false);
+ FileSpec source_path(DBGSourcePath.c_str(), false);
+ build_path.RemoveLastPathComponent();
+ build_path.RemoveLastPathComponent();
+ source_path.RemoveLastPathComponent();
+ source_path.RemoveLastPathComponent();
+ module_sp->GetSourceMappingList().Append(
+ ConstString(build_path.GetPath().c_str()),
+ ConstString(source_path.GetPath().c_str()), true);
+ }
}
return true;
});
diff --git a/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp b/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
index 3976f40dd8d17..f8aca4d1283b2 100644
--- a/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
+++ b/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
@@ -10,7 +10,6 @@
#include "UnwindAssemblyInstEmulation.h"
#include "lldb/Core/Address.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/DumpDataExtractor.h"
#include "lldb/Core/FormatEntity.h"
@@ -19,6 +18,7 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Log.h"
diff --git a/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp b/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
index c171f0f4d2a00..b8dcd99a53e75 100644
--- a/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
+++ b/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
@@ -15,7 +15,6 @@
#include "llvm/Support/TargetSelect.h"
#include "lldb/Core/Address.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/ABI.h"
@@ -26,6 +25,7 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/UnwindAssembly.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/Status.h"
using namespace lldb;
diff --git a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
index 97441d3629730..cec9803c8a494 100644
--- a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
+++ b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
@@ -12,13 +12,12 @@
#include "llvm-c/Disassembler.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/ConstString.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-forward.h"
#include "lldb/lldb-private.h"
-#include "lldb/Core/ArchSpec.h"
-#include "lldb/Utility/ConstString.h"
-
#include <map>
#include <vector>
diff --git a/source/Symbol/ArmUnwindInfo.cpp b/source/Symbol/ArmUnwindInfo.cpp
index 742c057e10e39..4da307bf0c326 100644
--- a/source/Symbol/ArmUnwindInfo.cpp
+++ b/source/Symbol/ArmUnwindInfo.cpp
@@ -46,7 +46,7 @@ bool ArmUnwindInfo::ArmExidxEntry::operator<(const ArmExidxEntry &other) const {
return address < other.address;
}
-ArmUnwindInfo::ArmUnwindInfo(const ObjectFile &objfile, SectionSP &arm_exidx,
+ArmUnwindInfo::ArmUnwindInfo(ObjectFile &objfile, SectionSP &arm_exidx,
SectionSP &arm_extab)
: m_byte_order(objfile.GetByteOrder()), m_arm_exidx_sp(arm_exidx),
m_arm_extab_sp(arm_extab) {
diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp
index c8738e6e55026..673124cc0de5f 100644
--- a/source/Symbol/ClangASTContext.cpp
+++ b/source/Symbol/ClangASTContext.cpp
@@ -70,7 +70,7 @@
#include "Plugins/ExpressionParser/Clang/ClangFunctionCaller.h"
#include "Plugins/ExpressionParser/Clang/ClangUserExpression.h"
#include "Plugins/ExpressionParser/Clang/ClangUtilityFunction.h"
-#include "lldb/Core/ArchSpec.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/Flags.h"
#include "lldb/Core/DumpDataExtractor.h"
@@ -435,75 +435,12 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) {
// OpenCL and C++ both have bool, true, false keywords.
Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
- // if (Opts.CPlusPlus)
- // Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
- //
- // if (Args.hasArg(OPT_fobjc_gc_only))
- // Opts.setGCMode(LangOptions::GCOnly);
- // else if (Args.hasArg(OPT_fobjc_gc))
- // Opts.setGCMode(LangOptions::HybridGC);
- //
- // if (Args.hasArg(OPT_print_ivar_layout))
- // Opts.ObjCGCBitmapPrint = 1;
- //
- // if (Args.hasArg(OPT_faltivec))
- // Opts.AltiVec = 1;
- //
- // if (Args.hasArg(OPT_pthread))
- // Opts.POSIXThreads = 1;
- //
- // llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
- // "default");
- // if (Vis == "default")
Opts.setValueVisibilityMode(DefaultVisibility);
- // else if (Vis == "hidden")
- // Opts.setVisibilityMode(LangOptions::Hidden);
- // else if (Vis == "protected")
- // Opts.setVisibilityMode(LangOptions::Protected);
- // else
- // Diags.Report(diag::err_drv_invalid_value)
- // << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
-
- // Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
// Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
// is specified, or -std is set to a conforming mode.
Opts.Trigraphs = !Opts.GNUMode;
- // if (Args.hasArg(OPT_trigraphs))
- // Opts.Trigraphs = 1;
- //
- // Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
- // OPT_fno_dollars_in_identifiers,
- // !Opts.AsmPreprocessor);
- // Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
- // Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
- // Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
- // if (Args.hasArg(OPT_fno_lax_vector_conversions))
- // Opts.LaxVectorConversions = 0;
- // Opts.Exceptions = Args.hasArg(OPT_fexceptions);
- // Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
- // Opts.Blocks = Args.hasArg(OPT_fblocks);
Opts.CharIsSigned = ArchSpec(triple).CharIsSignedByDefault();
- // Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
- // Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
- // Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
- // Opts.AssumeSaneOperatorNew =
- // !Args.hasArg(OPT_fno_assume_sane_operator_new);
- // Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
- // Opts.AccessControl = Args.hasArg(OPT_faccess_control);
- // Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
- // Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
- // Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth,
- // 99,
- // Diags);
- // Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
- // Opts.ObjCConstantStringClass = getLastArgValue(Args,
- // OPT_fconstant_string_class);
- // Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
- // Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
- // Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
- // Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
- // Opts.Static = Args.hasArg(OPT_static_define);
Opts.OptimizeSize = 0;
// FIXME: Eliminate this dependency.
@@ -518,18 +455,6 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) {
//
// FIXME: This is affected by other options (-fno-inline).
Opts.NoInlineDefine = !Opt;
-
- // unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
- // switch (SSP) {
- // default:
- // Diags.Report(diag::err_drv_invalid_value)
- // << Args.getLastArg(OPT_stack_protector)->getAsString(Args) <<
- // SSP;
- // break;
- // case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
- // case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break;
- // case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
- // }
}
ClangASTContext::ClangASTContext(const char *target_triple)
@@ -596,8 +521,9 @@ lldb::TypeSystemSP ClangASTContext::CreateInstance(lldb::LanguageType language,
ast_sp->SetArchitecture(fixed_arch);
ast_sp->m_scratch_ast_source_ap.reset(
new ClangASTSource(target->shared_from_this()));
+ lldbassert(ast_sp->getFileManager());
ast_sp->m_scratch_ast_source_ap->InstallASTContext(
- ast_sp->getASTContext());
+ *ast_sp->getASTContext(), *ast_sp->getFileManager(), true);
llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(
ast_sp->m_scratch_ast_source_ap->CreateProxy());
ast_sp->SetExternalSource(proxy_ast_source);
@@ -1430,7 +1356,7 @@ static TemplateParameterList *CreateTemplateParameterList(
is_typename, parameter_pack));
}
}
-
+
if (template_param_infos.packed_args &&
template_param_infos.packed_args->args.size()) {
IdentifierInfo *identifier_info = nullptr;
@@ -2168,21 +2094,21 @@ CompilerType ClangASTContext::GetOrCreateStructForIdentifier(
CompilerType
ClangASTContext::CreateEnumerationType(const char *name, DeclContext *decl_ctx,
const Declaration &decl,
- const CompilerType &integer_clang_type) {
+ const CompilerType &integer_clang_type,
+ bool is_scoped) {
// TODO: Do something intelligent with the Declaration object passed in
// like maybe filling in the SourceLocation with it...
ASTContext *ast = getASTContext();
// TODO: ask about these...
- // const bool IsScoped = false;
// const bool IsFixed = false;
EnumDecl *enum_decl = EnumDecl::Create(
*ast, decl_ctx, SourceLocation(), SourceLocation(),
name && name[0] ? &ast->Idents.get(name) : nullptr, nullptr,
- false, // IsScoped
- false, // IsScopedUsingClassTag
- false); // IsFixed
+ is_scoped, // IsScoped
+ is_scoped, // IsScopedUsingClassTag
+ false); // IsFixed
if (enum_decl) {
// TODO: check if we should be setting the promotion type too?
@@ -4350,6 +4276,9 @@ ClangASTContext::GetTypeClass(lldb::opaque_compiler_type_t type) {
break;
case clang::Type::ObjCTypeParam:
break;
+
+ case clang::Type::DependentAddressSpace:
+ break;
}
// We don't know hot to display this type...
return lldb::eTypeClassOther;
@@ -5009,6 +4938,7 @@ lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
case clang::BuiltinType::Half:
case clang::BuiltinType::Float:
+ case clang::BuiltinType::Float16:
case clang::BuiltinType::Float128:
case clang::BuiltinType::Double:
case clang::BuiltinType::LongDouble:
@@ -5159,6 +5089,9 @@ lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
break;
case clang::Type::ObjCTypeParam:
break;
+
+ case clang::Type::DependentAddressSpace:
+ break;
}
count = 0;
return lldb::eEncodingInvalid;
@@ -5309,6 +5242,9 @@ lldb::Format ClangASTContext::GetFormat(lldb::opaque_compiler_type_t type) {
break;
case clang::Type::ObjCTypeParam:
break;
+
+ case clang::Type::DependentAddressSpace:
+ break;
}
// We don't know hot to display this type...
return lldb::eFormatBytes;
@@ -7538,99 +7474,122 @@ ClangASTContext::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) {
return 0;
}
-CompilerType
-ClangASTContext::GetTemplateArgument(lldb::opaque_compiler_type_t type,
- size_t arg_idx,
- lldb::TemplateArgumentKind &kind) {
+const clang::ClassTemplateSpecializationDecl *
+ClangASTContext::GetAsTemplateSpecialization(
+ lldb::opaque_compiler_type_t type) {
if (!type)
- return CompilerType();
+ return nullptr;
clang::QualType qual_type(GetCanonicalQualType(type));
const clang::Type::TypeClass type_class = qual_type->getTypeClass();
switch (type_class) {
- case clang::Type::Record:
- if (GetCompleteType(type)) {
- const clang::CXXRecordDecl *cxx_record_decl =
- qual_type->getAsCXXRecordDecl();
- if (cxx_record_decl) {
- const clang::ClassTemplateSpecializationDecl *template_decl =
- llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(
- cxx_record_decl);
- if (template_decl &&
- arg_idx < template_decl->getTemplateArgs().size()) {
- const clang::TemplateArgument &template_arg =
- template_decl->getTemplateArgs()[arg_idx];
- switch (template_arg.getKind()) {
- case clang::TemplateArgument::Null:
- kind = eTemplateArgumentKindNull;
- return CompilerType();
-
- case clang::TemplateArgument::Type:
- kind = eTemplateArgumentKindType;
- return CompilerType(getASTContext(), template_arg.getAsType());
-
- case clang::TemplateArgument::Declaration:
- kind = eTemplateArgumentKindDeclaration;
- return CompilerType();
-
- case clang::TemplateArgument::Integral:
- kind = eTemplateArgumentKindIntegral;
- return CompilerType(getASTContext(),
- template_arg.getIntegralType());
-
- case clang::TemplateArgument::Template:
- kind = eTemplateArgumentKindTemplate;
- return CompilerType();
-
- case clang::TemplateArgument::TemplateExpansion:
- kind = eTemplateArgumentKindTemplateExpansion;
- return CompilerType();
-
- case clang::TemplateArgument::Expression:
- kind = eTemplateArgumentKindExpression;
- return CompilerType();
-
- case clang::TemplateArgument::Pack:
- kind = eTemplateArgumentKindPack;
- return CompilerType();
-
- default:
- llvm_unreachable("Unhandled clang::TemplateArgument::ArgKind");
- }
- }
- }
- }
- break;
+ case clang::Type::Record: {
+ if (! GetCompleteType(type))
+ return nullptr;
+ const clang::CXXRecordDecl *cxx_record_decl =
+ qual_type->getAsCXXRecordDecl();
+ if (!cxx_record_decl)
+ return nullptr;
+ return llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(
+ cxx_record_decl);
+ }
case clang::Type::Typedef:
- return (CompilerType(getASTContext(),
- llvm::cast<clang::TypedefType>(qual_type)
- ->getDecl()
- ->getUnderlyingType()))
- .GetTemplateArgument(arg_idx, kind);
+ return GetAsTemplateSpecialization(llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr());
case clang::Type::Auto:
- return (CompilerType(
- getASTContext(),
- llvm::cast<clang::AutoType>(qual_type)->getDeducedType()))
- .GetTemplateArgument(arg_idx, kind);
+ return GetAsTemplateSpecialization(llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr());
case clang::Type::Elaborated:
- return (CompilerType(
- getASTContext(),
- llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()))
- .GetTemplateArgument(arg_idx, kind);
+ return GetAsTemplateSpecialization(
+ llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr());
case clang::Type::Paren:
- return (CompilerType(getASTContext(),
- llvm::cast<clang::ParenType>(qual_type)->desugar()))
- .GetTemplateArgument(arg_idx, kind);
+ return GetAsTemplateSpecialization(
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
default:
- break;
+ return nullptr;
}
- kind = eTemplateArgumentKindNull;
- return CompilerType();
+}
+
+lldb::TemplateArgumentKind
+ClangASTContext::GetTemplateArgumentKind(lldb::opaque_compiler_type_t type,
+ size_t arg_idx) {
+ const clang::ClassTemplateSpecializationDecl *template_decl =
+ GetAsTemplateSpecialization(type);
+ if (! template_decl || arg_idx >= template_decl->getTemplateArgs().size())
+ return eTemplateArgumentKindNull;
+
+ switch (template_decl->getTemplateArgs()[arg_idx].getKind()) {
+ case clang::TemplateArgument::Null:
+ return eTemplateArgumentKindNull;
+
+ case clang::TemplateArgument::NullPtr:
+ return eTemplateArgumentKindNullPtr;
+
+ case clang::TemplateArgument::Type:
+ return eTemplateArgumentKindType;
+
+ case clang::TemplateArgument::Declaration:
+ return eTemplateArgumentKindDeclaration;
+
+ case clang::TemplateArgument::Integral:
+ return eTemplateArgumentKindIntegral;
+
+ case clang::TemplateArgument::Template:
+ return eTemplateArgumentKindTemplate;
+
+ case clang::TemplateArgument::TemplateExpansion:
+ return eTemplateArgumentKindTemplateExpansion;
+
+ case clang::TemplateArgument::Expression:
+ return eTemplateArgumentKindExpression;
+
+ case clang::TemplateArgument::Pack:
+ return eTemplateArgumentKindPack;
+ }
+ llvm_unreachable("Unhandled clang::TemplateArgument::ArgKind");
+}
+
+CompilerType
+ClangASTContext::GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
+ size_t idx) {
+ const clang::ClassTemplateSpecializationDecl *template_decl =
+ GetAsTemplateSpecialization(type);
+ if (!template_decl || idx >= template_decl->getTemplateArgs().size())
+ return CompilerType();
+
+ const clang::TemplateArgument &template_arg =
+ template_decl->getTemplateArgs()[idx];
+ if (template_arg.getKind() != clang::TemplateArgument::Type)
+ return CompilerType();
+
+ return CompilerType(getASTContext(), template_arg.getAsType());
+}
+
+llvm::Optional<CompilerType::IntegralTemplateArgument>
+ClangASTContext::GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type,
+ size_t idx) {
+ const clang::ClassTemplateSpecializationDecl *template_decl =
+ GetAsTemplateSpecialization(type);
+ if (! template_decl || idx >= template_decl->getTemplateArgs().size())
+ return llvm::None;
+
+ const clang::TemplateArgument &template_arg =
+ template_decl->getTemplateArgs()[idx];
+ if (template_arg.getKind() != clang::TemplateArgument::Integral)
+ return llvm::None;
+
+ return {{template_arg.getAsIntegral(),
+ CompilerType(getASTContext(), template_arg.getIntegralType())}};
}
CompilerType ClangASTContext::GetTypeForFormatters(void *type) {
@@ -10121,3 +10080,10 @@ PersistentExpressionState *
ClangASTContextForExpressions::GetPersistentExpressionState() {
return m_persistent_variables.get();
}
+
+clang::ExternalASTMerger &
+ClangASTContextForExpressions::GetMergerUnchecked() {
+ lldbassert(m_scratch_ast_source_ap != nullptr);
+ return m_scratch_ast_source_ap->GetMergerUnchecked();
+}
+
diff --git a/source/Symbol/ClangExternalASTSourceCommon.cpp b/source/Symbol/ClangExternalASTSourceCommon.cpp
index 7a1a0f23a7ce0..992a76352d927 100644
--- a/source/Symbol/ClangExternalASTSourceCommon.cpp
+++ b/source/Symbol/ClangExternalASTSourceCommon.cpp
@@ -10,6 +10,8 @@
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Utility/Stream.h"
+#include <mutex>
+
using namespace lldb_private;
uint64_t g_TotalSizeOfMetadata = 0;
@@ -18,15 +20,19 @@ typedef llvm::DenseMap<clang::ExternalASTSource *,
ClangExternalASTSourceCommon *>
ASTSourceMap;
-static ASTSourceMap &GetSourceMap() {
+static ASTSourceMap &GetSourceMap(std::unique_lock<std::mutex> &guard) {
// Intentionally leaked to avoid problems with global destructors.
static ASTSourceMap *s_source_map = new ASTSourceMap;
+ static std::mutex s_mutex;
+ std::unique_lock<std::mutex> locked_guard(s_mutex);
+ guard.swap(locked_guard);
return *s_source_map;
}
ClangExternalASTSourceCommon *
ClangExternalASTSourceCommon::Lookup(clang::ExternalASTSource *source) {
- ASTSourceMap &source_map = GetSourceMap();
+ std::unique_lock<std::mutex> guard;
+ ASTSourceMap &source_map = GetSourceMap(guard);
ASTSourceMap::iterator iter = source_map.find(source);
@@ -40,11 +46,13 @@ ClangExternalASTSourceCommon::Lookup(clang::ExternalASTSource *source) {
ClangExternalASTSourceCommon::ClangExternalASTSourceCommon()
: clang::ExternalASTSource() {
g_TotalSizeOfMetadata += m_metadata.size();
- GetSourceMap()[this] = this;
+ std::unique_lock<std::mutex> guard;
+ GetSourceMap(guard)[this] = this;
}
ClangExternalASTSourceCommon::~ClangExternalASTSourceCommon() {
- GetSourceMap().erase(this);
+ std::unique_lock<std::mutex> guard;
+ GetSourceMap(guard).erase(this);
g_TotalSizeOfMetadata -= m_metadata.size();
}
diff --git a/source/Symbol/CompactUnwindInfo.cpp b/source/Symbol/CompactUnwindInfo.cpp
index bc367496003e8..df71b17c09d0c 100644
--- a/source/Symbol/CompactUnwindInfo.cpp
+++ b/source/Symbol/CompactUnwindInfo.cpp
@@ -7,22 +7,18 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-#include <algorithm>
-
-#include "lldb/Core/ArchSpec.h"
+#include "lldb/Symbol/CompactUnwindInfo.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
-#include "lldb/Core/Section.h"
-#include "lldb/Symbol/CompactUnwindInfo.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"
+#include <algorithm>
#include "llvm/Support/MathExtras.h"
diff --git a/source/Symbol/CompilerType.cpp b/source/Symbol/CompilerType.cpp
index e3880af27f22e..5d845361b03ce 100644
--- a/source/Symbol/CompilerType.cpp
+++ b/source/Symbol/CompilerType.cpp
@@ -690,15 +690,26 @@ size_t CompilerType::GetNumTemplateArguments() const {
return 0;
}
-CompilerType
-CompilerType::GetTemplateArgument(size_t idx,
- lldb::TemplateArgumentKind &kind) const {
+TemplateArgumentKind CompilerType::GetTemplateArgumentKind(size_t idx) const {
+ if (IsValid())
+ return m_type_system->GetTemplateArgumentKind(m_type, idx);
+ return eTemplateArgumentKindNull;
+}
+
+CompilerType CompilerType::GetTypeTemplateArgument(size_t idx) const {
if (IsValid()) {
- return m_type_system->GetTemplateArgument(m_type, idx, kind);
+ return m_type_system->GetTypeTemplateArgument(m_type, idx);
}
return CompilerType();
}
+llvm::Optional<CompilerType::IntegralTemplateArgument>
+CompilerType::GetIntegralTemplateArgument(size_t idx) const {
+ if (IsValid())
+ return m_type_system->GetIntegralTemplateArgument(m_type, idx);
+ return llvm::None;
+}
+
CompilerType CompilerType::GetTypeForFormatters() const {
if (IsValid())
return m_type_system->GetTypeForFormatters(m_type);
@@ -997,7 +1008,7 @@ bool CompilerType::ReadFromMemory(lldb_private::ExecutionContext *exe_ctx,
if (addr == 0)
return false;
// The address is an address in this process, so just copy it
- memcpy(dst, (uint8_t *)nullptr + addr, byte_size);
+ memcpy(dst, reinterpret_cast<uint8_t *>(addr), byte_size);
return true;
} else {
Process *process = nullptr;
diff --git a/source/Symbol/DWARFCallFrameInfo.cpp b/source/Symbol/DWARFCallFrameInfo.cpp
index 9b1f8c694ccfe..572648d05f09b 100644
--- a/source/Symbol/DWARFCallFrameInfo.cpp
+++ b/source/Symbol/DWARFCallFrameInfo.cpp
@@ -7,22 +7,19 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-#include <list>
-
-#include "lldb/Core/ArchSpec.h"
+#include "lldb/Symbol/DWARFCallFrameInfo.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/dwarf.h"
#include "lldb/Host/Host.h"
-#include "lldb/Symbol/DWARFCallFrameInfo.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Timer.h"
+#include <list>
using namespace lldb;
using namespace lldb_private;
diff --git a/source/Symbol/JavaASTContext.cpp b/source/Symbol/JavaASTContext.cpp
index ae4e9d5134b56..ff317eb19e97c 100644
--- a/source/Symbol/JavaASTContext.cpp
+++ b/source/Symbol/JavaASTContext.cpp
@@ -7,9 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#include <sstream>
-
-#include "lldb/Core/ArchSpec.h"
+#include "lldb/Symbol/JavaASTContext.h"
#include "lldb/Core/DumpDataExtractor.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
@@ -17,11 +15,12 @@
#include "lldb/Core/ValueObject.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Symbol/CompilerType.h"
-#include "lldb/Symbol/JavaASTContext.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/Stream.h"
+#include <sstream>
#include "Plugins/SymbolFile/DWARF/DWARFASTParserJava.h"
@@ -134,9 +133,9 @@ public:
obj_load_address.SetValueType(Value::eValueTypeLoadAddress);
Value result;
- if (m_dynamic_type_id.Evaluate(exe_ctx->GetBestExecutionContextScope(),
- nullptr, nullptr, 0, &obj_load_address,
- nullptr, result, nullptr)) {
+ if (m_dynamic_type_id.Evaluate(exe_ctx->GetBestExecutionContextScope(), 0,
+ &obj_load_address, nullptr, result,
+ nullptr)) {
Status error;
lldb::addr_t type_id_addr = result.GetScalar().UInt();
@@ -315,9 +314,8 @@ public:
ExecutionContextScope *exec_ctx_scope = value_obj->GetExecutionContextRef()
.Lock(true)
.GetBestExecutionContextScope();
- if (m_length_expression.Evaluate(exec_ctx_scope, nullptr, nullptr, 0,
- nullptr, &obj_load_address, result,
- nullptr))
+ if (m_length_expression.Evaluate(exec_ctx_scope, 0, nullptr,
+ &obj_load_address, result, nullptr))
return result.GetScalar().UInt();
return UINT32_MAX;
@@ -885,13 +883,6 @@ JavaASTContext::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) {
return 0;
}
-CompilerType
-JavaASTContext::GetTemplateArgument(lldb::opaque_compiler_type_t type,
- size_t idx,
- lldb::TemplateArgumentKind &kind) {
- return CompilerType();
-}
-
uint32_t JavaASTContext::GetNumFields(lldb::opaque_compiler_type_t type) {
if (JavaObjectType *obj =
llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type))) {
diff --git a/source/Symbol/ObjectFile.cpp b/source/Symbol/ObjectFile.cpp
index fd4180862c15b..7d73cb19d5083 100644
--- a/source/Symbol/ObjectFile.cpp
+++ b/source/Symbol/ObjectFile.cpp
@@ -348,6 +348,7 @@ AddressClass ObjectFile::GetAddressClass(addr_t file_addr) {
case eSectionTypeDWARFDebugAbbrev:
case eSectionTypeDWARFDebugAddr:
case eSectionTypeDWARFDebugAranges:
+ case eSectionTypeDWARFDebugCuIndex:
case eSectionTypeDWARFDebugFrame:
case eSectionTypeDWARFDebugInfo:
case eSectionTypeDWARFDebugLine:
@@ -482,9 +483,9 @@ size_t ObjectFile::CopyData(lldb::offset_t offset, size_t length,
return m_data.CopyData(offset, length, dst);
}
-size_t ObjectFile::ReadSectionData(const Section *section,
+size_t ObjectFile::ReadSectionData(Section *section,
lldb::offset_t section_offset, void *dst,
- size_t dst_len) const {
+ size_t dst_len) {
assert(section);
section_offset *= section->GetTargetByteSize();
@@ -504,6 +505,9 @@ size_t ObjectFile::ReadSectionData(const Section *section,
dst_len, error);
}
} else {
+ if (!section->IsRelocated())
+ RelocateSection(section);
+
const lldb::offset_t section_file_size = section->GetFileSize();
if (section_offset < section_file_size) {
const size_t section_bytes_left = section_file_size - section_offset;
@@ -530,8 +534,8 @@ size_t ObjectFile::ReadSectionData(const Section *section,
//----------------------------------------------------------------------
// Get the section data the file on disk
//----------------------------------------------------------------------
-size_t ObjectFile::ReadSectionData(const Section *section,
- DataExtractor &section_data) const {
+size_t ObjectFile::ReadSectionData(Section *section,
+ DataExtractor &section_data) {
// If some other objectfile owns this data, pass this to them.
if (section->GetObjectFile() != this)
return section->GetObjectFile()->ReadSectionData(section, section_data);
@@ -557,22 +561,9 @@ size_t ObjectFile::ReadSectionData(const Section *section,
} else {
// The object file now contains a full mmap'ed copy of the object file data,
// so just use this
- return MemoryMapSectionData(section, section_data);
- }
-}
-
-size_t ObjectFile::MemoryMapSectionData(const Section *section,
- DataExtractor &section_data) const {
- // If some other objectfile owns this data, pass this to them.
- if (section->GetObjectFile() != this)
- return section->GetObjectFile()->MemoryMapSectionData(section,
- section_data);
+ if (!section->IsRelocated())
+ RelocateSection(section);
- if (IsInMemory()) {
- return ReadSectionData(section, section_data);
- } else {
- // The object file now contains a full mmap'ed copy of the object file data,
- // so just use this
return GetData(section->GetFileOffset(), section->GetFileSize(),
section_data);
}
@@ -693,3 +684,7 @@ Status ObjectFile::LoadInMemory(Target &target, bool set_pc) {
}
return error;
}
+
+void ObjectFile::RelocateSection(lldb_private::Section *section)
+{
+}
diff --git a/source/Symbol/Symtab.cpp b/source/Symbol/Symtab.cpp
index 3e2c965509d3c..4ac30649110fc 100644
--- a/source/Symbol/Symtab.cpp
+++ b/source/Symbol/Symtab.cpp
@@ -399,29 +399,6 @@ void Symtab::InitNameIndexes() {
m_basename_to_index.SizeToFit();
m_method_to_index.Sort();
m_method_to_index.SizeToFit();
-
- // static StreamFile a ("/tmp/a.txt");
- //
- // count = m_basename_to_index.GetSize();
- // if (count)
- // {
- // for (size_t i=0; i<count; ++i)
- // {
- // if (m_basename_to_index.GetValueAtIndex(i, entry.value))
- // a.Printf ("%s BASENAME\n",
- // m_symbols[entry.value].GetMangled().GetName().GetCString());
- // }
- // }
- // count = m_method_to_index.GetSize();
- // if (count)
- // {
- // for (size_t i=0; i<count; ++i)
- // {
- // if (m_method_to_index.GetValueAtIndex(i, entry.value))
- // a.Printf ("%s METHOD\n",
- // m_symbols[entry.value].GetMangled().GetName().GetCString());
- // }
- // }
}
}
@@ -616,8 +593,10 @@ void Symtab::SortSymbolIndexesByValue(std::vector<uint32_t> &indexes,
std::stable_sort(indexes.begin(), indexes.end(), comparator);
// Remove any duplicates if requested
- if (remove_duplicates)
- std::unique(indexes.begin(), indexes.end());
+ if (remove_duplicates) {
+ auto last = std::unique(indexes.begin(), indexes.end());
+ indexes.erase(last, indexes.end());
+ }
}
uint32_t Symtab::AppendSymbolIndexesWithName(const ConstString &symbol_name,
diff --git a/source/Symbol/Type.cpp b/source/Symbol/Type.cpp
index 53d9c5cc96a92..53bf3e8500558 100644
--- a/source/Symbol/Type.cpp
+++ b/source/Symbol/Type.cpp
@@ -404,7 +404,7 @@ bool Type::ReadFromMemory(ExecutionContext *exe_ctx, lldb::addr_t addr,
// The address is an address in this process, so just copy it
if (addr == 0)
return false;
- memcpy(dst, (uint8_t *)nullptr + addr, byte_size);
+ memcpy(dst, reinterpret_cast<uint8_t *>(addr), byte_size);
return true;
} else {
if (exe_ctx) {
diff --git a/source/Symbol/TypeSystem.cpp b/source/Symbol/TypeSystem.cpp
index fa5e0bc7da6ed..b99f21e1e3471 100644
--- a/source/Symbol/TypeSystem.cpp
+++ b/source/Symbol/TypeSystem.cpp
@@ -23,19 +23,20 @@
#include "lldb/Symbol/CompilerType.h"
using namespace lldb_private;
+using namespace lldb;
TypeSystem::TypeSystem(LLVMCastKind kind) : m_kind(kind), m_sym_file(nullptr) {}
TypeSystem::~TypeSystem() {}
-lldb::TypeSystemSP TypeSystem::CreateInstance(lldb::LanguageType language,
- Module *module) {
+static lldb::TypeSystemSP CreateInstanceHelper(lldb::LanguageType language,
+ Module *module, Target *target) {
uint32_t i = 0;
TypeSystemCreateInstance create_callback;
while ((create_callback = PluginManager::GetTypeSystemCreateCallbackAtIndex(
i++)) != nullptr) {
lldb::TypeSystemSP type_system_sp =
- create_callback(language, module, nullptr);
+ create_callback(language, module, target);
if (type_system_sp)
return type_system_sp;
}
@@ -44,18 +45,13 @@ lldb::TypeSystemSP TypeSystem::CreateInstance(lldb::LanguageType language,
}
lldb::TypeSystemSP TypeSystem::CreateInstance(lldb::LanguageType language,
- Target *target) {
- uint32_t i = 0;
- TypeSystemCreateInstance create_callback;
- while ((create_callback = PluginManager::GetTypeSystemCreateCallbackAtIndex(
- i++)) != nullptr) {
- lldb::TypeSystemSP type_system_sp =
- create_callback(language, nullptr, target);
- if (type_system_sp)
- return type_system_sp;
- }
+ Module *module) {
+ return CreateInstanceHelper(language, module, nullptr);
+}
- return lldb::TypeSystemSP();
+lldb::TypeSystemSP TypeSystem::CreateInstance(lldb::LanguageType language,
+ Target *target) {
+ return CreateInstanceHelper(language, nullptr, target);
}
bool TypeSystem::IsAnonymousType(lldb::opaque_compiler_type_t type) {
@@ -105,6 +101,22 @@ CompilerType TypeSystem::GetTypeForFormatters(void *type) {
return CompilerType(this, type);
}
+TemplateArgumentKind
+TypeSystem::GetTemplateArgumentKind(opaque_compiler_type_t type, size_t idx) {
+ return eTemplateArgumentKindNull;
+}
+
+CompilerType TypeSystem::GetTypeTemplateArgument(opaque_compiler_type_t type,
+ size_t idx) {
+ return CompilerType();
+}
+
+llvm::Optional<CompilerType::IntegralTemplateArgument>
+TypeSystem::GetIntegralTemplateArgument(opaque_compiler_type_t type,
+ size_t idx) {
+ return llvm::None;
+}
+
LazyBool TypeSystem::ShouldPrintAsOneLiner(void *type, ValueObject *valobj) {
return eLazyBoolCalculate;
}
diff --git a/source/Symbol/Variable.cpp b/source/Symbol/Variable.cpp
index ff32aa7314657..1957bcef1f3a0 100644
--- a/source/Symbol/Variable.cpp
+++ b/source/Symbol/Variable.cpp
@@ -425,14 +425,8 @@ Status Variable::GetValuesForVariableExpressionPath(
llvm::StringRef variable_sub_expr_path =
variable_expr_path.drop_front(variable_name.size());
if (!variable_sub_expr_path.empty()) {
- ValueObject::ExpressionPathScanEndReason reason_to_stop;
- ValueObject::ExpressionPathEndResultType final_value_type;
- ValueObject::GetValueForExpressionPathOptions options;
- ValueObject::ExpressionPathAftermath final_task_on_target;
-
valobj_sp = variable_valobj_sp->GetValueForExpressionPath(
- variable_sub_expr_path, &reason_to_stop, &final_value_type, options,
- &final_task_on_target);
+ variable_sub_expr_path);
if (!valobj_sp) {
error.SetErrorStringWithFormat(
"invalid expression path '%s' for variable '%s'",
diff --git a/source/Target/PathMappingList.cpp b/source/Target/PathMappingList.cpp
index b834a3600d0b1..782c6e49623c5 100644
--- a/source/Target/PathMappingList.cpp
+++ b/source/Target/PathMappingList.cpp
@@ -85,7 +85,6 @@ void PathMappingList::Insert(const ConstString &path,
bool PathMappingList::Replace(const ConstString &path,
const ConstString &replacement, uint32_t index,
bool notify) {
- iterator insert_iter;
if (index >= m_pairs.size())
return false;
++m_mod_id;
diff --git a/source/Target/Platform.cpp b/source/Target/Platform.cpp
index 498facf8e0d02..5d60bb7915559 100644
--- a/source/Target/Platform.cpp
+++ b/source/Target/Platform.cpp
@@ -356,6 +356,12 @@ PlatformSP Platform::Create(const ArchSpec &arch, ArchSpec *platform_arch_ptr,
return platform_sp;
}
+ArchSpec Platform::GetAugmentedArchSpec(Platform *platform, llvm::StringRef triple) {
+ if (platform)
+ return platform->GetAugmentedArchSpec(triple);
+ return HostInfo::GetAugmentedArchSpec(triple);
+}
+
//------------------------------------------------------------------
/// Default Constructor
//------------------------------------------------------------------
@@ -963,6 +969,34 @@ const ArchSpec &Platform::GetSystemArchitecture() {
return m_system_arch;
}
+ArchSpec Platform::GetAugmentedArchSpec(llvm::StringRef triple) {
+ if (triple.empty())
+ return ArchSpec();
+ llvm::Triple normalized_triple(llvm::Triple::normalize(triple));
+ if (!ArchSpec::ContainsOnlyArch(normalized_triple))
+ return ArchSpec(triple);
+
+ if (auto kind = HostInfo::ParseArchitectureKind(triple))
+ return HostInfo::GetArchitecture(*kind);
+
+ ArchSpec compatible_arch;
+ ArchSpec raw_arch(triple);
+ if (!IsCompatibleArchitecture(raw_arch, false, &compatible_arch))
+ return raw_arch;
+
+ if (!compatible_arch.IsValid())
+ return ArchSpec(normalized_triple);
+
+ const llvm::Triple &compatible_triple = compatible_arch.GetTriple();
+ if (normalized_triple.getVendorName().empty())
+ normalized_triple.setVendor(compatible_triple.getVendor());
+ if (normalized_triple.getOSName().empty())
+ normalized_triple.setOS(compatible_triple.getOS());
+ if (normalized_triple.getEnvironmentName().empty())
+ normalized_triple.setEnvironment(compatible_triple.getEnvironment());
+ return ArchSpec(normalized_triple);
+}
+
Status Platform::ConnectRemote(Args &args) {
Status error;
if (IsHost())
@@ -1162,7 +1196,7 @@ Platform::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
// 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 != lldb_utility::PseudoTerminal::invalid_fd) {
+ if (pty_fd != PseudoTerminal::invalid_fd) {
process_sp->SetSTDIOFileDescriptor(pty_fd);
}
} else {
@@ -1316,14 +1350,18 @@ Status Platform::Unlink(const FileSpec &path) {
return error;
}
-uint64_t Platform::ConvertMmapFlagsToPlatform(const ArchSpec &arch,
- unsigned flags) {
+MmapArgList Platform::GetMmapArgumentList(const ArchSpec &arch, addr_t addr,
+ addr_t length, unsigned prot,
+ unsigned flags, addr_t fd,
+ addr_t offset) {
uint64_t flags_platform = 0;
if (flags & eMmapFlagsPrivate)
flags_platform |= MAP_PRIVATE;
if (flags & eMmapFlagsAnon)
flags_platform |= MAP_ANON;
- return flags_platform;
+
+ MmapArgList args({addr, length, prot, flags_platform, fd, offset});
+ return args;
}
lldb_private::Status Platform::RunShellCommand(
@@ -1874,6 +1912,12 @@ size_t Platform::GetSoftwareBreakpointTrapOpcode(Target &target,
trap_opcode_size = sizeof(g_ppc_opcode);
} break;
+ case llvm::Triple::ppc64le: {
+ static const uint8_t g_ppc64le_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap
+ trap_opcode = g_ppc64le_opcode;
+ trap_opcode_size = sizeof(g_ppc64le_opcode);
+ } break;
+
case llvm::Triple::x86:
case llvm::Triple::x86_64: {
static const uint8_t g_i386_opcode[] = {0xCC};
diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp
index 6cbe289ef26be..8fb149fab0633 100644
--- a/source/Target/Process.cpp
+++ b/source/Target/Process.cpp
@@ -144,6 +144,9 @@ static PropertyDefinition g_properties[] = {
{"optimization-warnings", OptionValue::eTypeBoolean, false, true, nullptr,
nullptr, "If true, warn when stopped in code that is optimized where "
"stepping and variable availability may not behave as expected."},
+ {"stop-on-exec", OptionValue::eTypeBoolean, true, true,
+ nullptr, nullptr,
+ "If true, stop when a shared library is loaded or unloaded."},
{nullptr, OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr}};
enum {
@@ -155,7 +158,8 @@ enum {
ePropertyStopOnSharedLibraryEvents,
ePropertyDetachKeepsStopped,
ePropertyMemCacheLineSize,
- ePropertyWarningOptimization
+ ePropertyWarningOptimization,
+ ePropertyStopOnExec
};
ProcessProperties::ProcessProperties(lldb_private::Process *process)
@@ -272,6 +276,12 @@ bool ProcessProperties::GetWarningsOptimization() const {
nullptr, idx, g_properties[idx].default_uint_value != 0);
}
+bool ProcessProperties::GetStopOnExec() const {
+ const uint32_t idx = ePropertyStopOnExec;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_properties[idx].default_uint_value != 0);
+}
+
void ProcessInstanceInfo::Dump(Stream &s, Platform *platform) const {
const char *cstr;
if (m_pid != LLDB_INVALID_PROCESS_ID)
@@ -480,8 +490,8 @@ Status ProcessLaunchCommandOptions::SetOptionValue(
execution_context ? execution_context->GetTargetSP() : TargetSP();
PlatformSP platform_sp =
target_sp ? target_sp->GetPlatform() : PlatformSP();
- if (!launch_info.GetArchitecture().SetTriple(option_arg, platform_sp.get()))
- launch_info.GetArchitecture().SetTriple(option_arg);
+ launch_info.GetArchitecture() =
+ Platform::GetAugmentedArchSpec(platform_sp.get(), option_arg);
} break;
case 'A': // Disable ASLR.
@@ -743,8 +753,7 @@ Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp,
m_profile_data_comm_mutex(), m_profile_data(), m_iohandler_sync(0),
m_memory_cache(*this), m_allocated_memory_cache(*this),
m_should_detach(false), m_next_event_action_ap(), m_public_run_lock(),
- m_private_run_lock(), m_stop_info_override_callback(nullptr),
- m_finalizing(false), m_finalize_called(false),
+ m_private_run_lock(), m_finalizing(false), m_finalize_called(false),
m_clear_thread_plans_on_stop(false), m_force_next_event_delivery(false),
m_last_broadcast_state(eStateInvalid), m_destroy_in_process(false),
m_can_interpret_function_calls(false), m_warnings_issued(),
@@ -871,7 +880,6 @@ void Process::Finalize() {
m_language_runtimes.clear();
m_instrumentation_runtimes.clear();
m_next_event_action_ap.reset();
- m_stop_info_override_callback = nullptr;
// Clear the last natural stop ID since it has a strong
// reference to this process
m_mod_id.SetStopEventForLastNaturalStopID(EventSP());
@@ -1562,7 +1570,6 @@ uint32_t Process::AssignIndexIDToThread(uint64_t thread_id) {
}
StateType Process::GetState() {
- // If any other threads access this we will need a mutex for it
return m_public_state.GetValue();
}
@@ -1621,7 +1628,12 @@ Status Process::Resume() {
log->Printf("Process::Resume: -- TrySetRunning failed, not resuming.");
return error;
}
- return PrivateResume();
+ Status error = PrivateResume();
+ if (!error.Success()) {
+ // Undo running state change
+ m_public_run_lock.SetStopped();
+ }
+ return error;
}
Status Process::ResumeSynchronous(Stream *stream) {
@@ -1650,6 +1662,9 @@ Status Process::ResumeSynchronous(Stream *stream) {
error.SetErrorStringWithFormat(
"process not in stopped state after synchronous resume: %s",
StateAsCString(state));
+ } else {
+ // Undo running state change
+ m_public_run_lock.SetStopped();
}
// Undo the hijacking of process events...
@@ -2712,7 +2727,6 @@ Status Process::Launch(ProcessLaunchInfo &launch_info) {
m_system_runtime_ap.reset();
m_os_ap.reset();
m_process_input_reader.reset();
- m_stop_info_override_callback = nullptr;
Module *exe_module = GetTarget().GetExecutableModulePointer();
if (exe_module) {
@@ -2800,9 +2814,6 @@ Status Process::Launch(ProcessLaunchInfo &launch_info) {
else
StartPrivateStateThread();
- m_stop_info_override_callback =
- GetTarget().GetArchitecture().GetStopInfoOverrideCallback();
-
// Target was stopped at entry as was intended. Need to notify the
// listeners
// about it.
@@ -2986,7 +2997,6 @@ Status Process::Attach(ProcessAttachInfo &attach_info) {
m_jit_loaders_ap.reset();
m_system_runtime_ap.reset();
m_os_ap.reset();
- m_stop_info_override_callback = nullptr;
lldb::pid_t attach_pid = attach_info.GetProcessID();
Status error;
@@ -3219,8 +3229,6 @@ void Process::CompleteAttach() {
: "<none>");
}
}
-
- m_stop_info_override_callback = process_arch.GetStopInfoOverrideCallback();
}
Status Process::ConnectRemote(Stream *strm, llvm::StringRef remote_url) {
@@ -5849,7 +5857,6 @@ void Process::DidExec() {
m_instrumentation_runtimes.clear();
m_thread_list.DiscardThreadPlans();
m_memory_cache.Clear(true);
- m_stop_info_override_callback = nullptr;
DoDidExec();
CompleteAttach();
// Flush the process (threads and all stack frames) after running
diff --git a/source/Target/ProcessLaunchInfo.cpp b/source/Target/ProcessLaunchInfo.cpp
index 3fa40dcc5cab2..284df9fd8b58c 100644
--- a/source/Target/ProcessLaunchInfo.cpp
+++ b/source/Target/ProcessLaunchInfo.cpp
@@ -39,10 +39,9 @@ using namespace lldb_private;
ProcessLaunchInfo::ProcessLaunchInfo()
: ProcessInfo(), m_working_dir(), m_plugin_name(), m_flags(0),
- m_file_actions(), m_pty(new lldb_utility::PseudoTerminal),
- m_resume_count(0), m_monitor_callback(nullptr),
- m_monitor_callback_baton(nullptr), m_monitor_signals(false),
- m_listener_sp(), m_hijack_listener_sp() {}
+ m_file_actions(), m_pty(new PseudoTerminal), m_resume_count(0),
+ m_monitor_callback(nullptr), m_monitor_callback_baton(nullptr),
+ m_monitor_signals(false), m_listener_sp(), m_hijack_listener_sp() {}
ProcessLaunchInfo::ProcessLaunchInfo(const FileSpec &stdin_file_spec,
const FileSpec &stdout_file_spec,
@@ -50,10 +49,9 @@ ProcessLaunchInfo::ProcessLaunchInfo(const FileSpec &stdin_file_spec,
const FileSpec &working_directory,
uint32_t launch_flags)
: ProcessInfo(), m_working_dir(), m_plugin_name(), m_flags(launch_flags),
- m_file_actions(), m_pty(new lldb_utility::PseudoTerminal),
- m_resume_count(0), m_monitor_callback(nullptr),
- m_monitor_callback_baton(nullptr), m_monitor_signals(false),
- m_listener_sp(), m_hijack_listener_sp() {
+ m_file_actions(), m_pty(new PseudoTerminal), m_resume_count(0),
+ m_monitor_callback(nullptr), m_monitor_callback_baton(nullptr),
+ m_monitor_signals(false), m_listener_sp(), m_hijack_listener_sp() {
if (stdin_file_spec) {
FileAction file_action;
const bool read = true;
diff --git a/source/Target/RegisterContext.cpp b/source/Target/RegisterContext.cpp
index 66164c175e416..28beb7bcb5e88 100644
--- a/source/Target/RegisterContext.cpp
+++ b/source/Target/RegisterContext.cpp
@@ -93,10 +93,9 @@ RegisterContext::UpdateDynamicRegisterSize(const lldb_private::ArchSpec &arch,
Value result;
Status error;
const lldb::offset_t offset = 0;
- if (dwarf_expr.Evaluate(&exe_ctx, nullptr, nullptr, this, opcode_ctx,
- dwarf_data, nullptr, offset, dwarf_opcode_len,
- eRegisterKindDWARF, nullptr, nullptr, result,
- &error)) {
+ if (dwarf_expr.Evaluate(&exe_ctx, this, opcode_ctx, dwarf_data, nullptr,
+ offset, dwarf_opcode_len, eRegisterKindDWARF, nullptr,
+ nullptr, result, &error)) {
expr_result = result.GetScalar().SInt(-1);
switch (expr_result) {
case 0:
@@ -457,132 +456,3 @@ bool RegisterContext::ConvertBetweenRegisterKinds(lldb::RegisterKind source_rk,
}
return false;
}
-
-// bool
-// RegisterContext::ReadRegisterValue (uint32_t reg, Scalar &value)
-//{
-// DataExtractor data;
-// if (!ReadRegisterBytes (reg, data))
-// return false;
-//
-// const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg);
-// uint32_t offset = 0;
-// switch (reg_info->encoding)
-// {
-// case eEncodingInvalid:
-// case eEncodingVector:
-// break;
-//
-// case eEncodingUint:
-// switch (reg_info->byte_size)
-// {
-// case 1:
-// {
-// value = data.GetU8 (&offset);
-// return true;
-// }
-// case 2:
-// {
-// value = data.GetU16 (&offset);
-// return true;
-// }
-// case 4:
-// {
-// value = data.GetU32 (&offset);
-// return true;
-// }
-// case 8:
-// {
-// value = data.GetU64 (&offset);
-// return true;
-// }
-// }
-// break;
-// case eEncodingSint:
-// switch (reg_info->byte_size)
-// {
-// case 1:
-// {
-// int8_t v;
-// if (data.ExtractBytes (0, sizeof (int8_t),
-// endian::InlHostByteOrder(), &v) != sizeof (int8_t))
-// return false;
-// value = v;
-// return true;
-// }
-// case 2:
-// {
-// int16_t v;
-// if (data.ExtractBytes (0, sizeof (int16_t),
-// endian::InlHostByteOrder(), &v) != sizeof (int16_t))
-// return false;
-// value = v;
-// return true;
-// }
-// case 4:
-// {
-// int32_t v;
-// if (data.ExtractBytes (0, sizeof (int32_t),
-// endian::InlHostByteOrder(), &v) != sizeof (int32_t))
-// return false;
-// value = v;
-// return true;
-// }
-// case 8:
-// {
-// int64_t v;
-// if (data.ExtractBytes (0, sizeof (int64_t),
-// endian::InlHostByteOrder(), &v) != sizeof (int64_t))
-// return false;
-// value = v;
-// return true;
-// }
-// }
-// break;
-// case eEncodingIEEE754:
-// switch (reg_info->byte_size)
-// {
-// case sizeof (float):
-// {
-// float v;
-// if (data.ExtractBytes (0, sizeof (float),
-// endian::InlHostByteOrder(), &v) != sizeof (float))
-// return false;
-// value = v;
-// return true;
-// }
-// case sizeof (double):
-// {
-// double v;
-// if (data.ExtractBytes (0, sizeof (double),
-// endian::InlHostByteOrder(), &v) != sizeof (double))
-// return false;
-// value = v;
-// return true;
-// }
-// case sizeof (long double):
-// {
-// double v;
-// if (data.ExtractBytes (0, sizeof (long double),
-// endian::InlHostByteOrder(), &v) != sizeof (long double))
-// return false;
-// value = v;
-// return true;
-// }
-// }
-// break;
-// }
-// return false;
-//}
-//
-// bool
-// RegisterContext::WriteRegisterValue (uint32_t reg, const Scalar &value)
-//{
-// DataExtractor data;
-// if (!value.IsValid())
-// return false;
-// if (!value.GetData (data))
-// return false;
-//
-// return WriteRegisterBytes (reg, data);
-//}
diff --git a/source/Target/StackFrame.cpp b/source/Target/StackFrame.cpp
index 30fceb11c11f3..dd44eac8e50c2 100644
--- a/source/Target/StackFrame.cpp
+++ b/source/Target/StackFrame.cpp
@@ -1089,8 +1089,8 @@ bool StackFrame::GetFrameBaseValue(Scalar &frame_base, Status *error_ptr) {
exe_ctx.GetTargetPtr());
if (m_sc.function->GetFrameBaseExpression().Evaluate(
- &exe_ctx, nullptr, nullptr, nullptr, loclist_base_addr, nullptr,
- nullptr, expr_value, &m_frame_base_error) == false) {
+ &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.
if (m_frame_base_error.Success())
diff --git a/source/Target/StopInfo.cpp b/source/Target/StopInfo.cpp
index 6af5ce1b2ebf9..652ad8a054457 100644
--- a/source/Target/StopInfo.cpp
+++ b/source/Target/StopInfo.cpp
@@ -393,7 +393,10 @@ protected:
for (size_t j = 0; j < num_owners; j++) {
lldb::BreakpointLocationSP bp_loc_sp = site_locations.GetByIndex(j);
-
+ StreamString loc_desc;
+ if (log) {
+ bp_loc_sp->GetDescription(&loc_desc, eDescriptionLevelBrief);
+ }
// If another action disabled this breakpoint or its location, then
// don't run the actions.
if (!bp_loc_sp->IsEnabled() ||
@@ -405,16 +408,16 @@ protected:
// this thread. Skip the ones that aren't:
if (!bp_loc_sp->ValidForThisThread(thread_sp.get())) {
if (log) {
- StreamString s;
- bp_loc_sp->GetDescription(&s, eDescriptionLevelBrief);
log->Printf("Breakpoint %s hit on thread 0x%llx but it was not "
"for this thread, continuing.",
- s.GetData(), static_cast<unsigned long long>(
+ loc_desc.GetData(), static_cast<unsigned long long>(
thread_sp->GetID()));
}
continue;
}
+ internal_breakpoint = bp_loc_sp->GetBreakpoint().IsInternal();
+
// First run the precondition, but since the precondition is per
// breakpoint, only run it once
// per breakpoint.
@@ -458,11 +461,10 @@ protected:
error_sp->Flush();
} else {
if (log) {
- StreamString s;
- bp_loc_sp->GetDescription(&s, eDescriptionLevelBrief);
log->Printf("Condition evaluated for breakpoint %s on thread "
"0x%llx conditon_says_stop: %i.",
- s.GetData(), static_cast<unsigned long long>(
+ loc_desc.GetData(),
+ static_cast<unsigned long long>(
thread_sp->GetID()),
condition_says_stop);
}
@@ -477,7 +479,26 @@ protected:
}
}
- bool callback_says_stop;
+ // Check the auto-continue bit on the location, do this before the
+ // callback since it may change this, but that would be for the
+ // NEXT hit. Note, you might think you could check auto-continue
+ // before the condition, and not evaluate the condition if it says
+ // to continue. But failing the condition means the breakpoint was
+ // effectively NOT HIT. So these two states are different.
+ bool auto_continue_says_stop = true;
+ if (bp_loc_sp->IsAutoContinue())
+ {
+ if (log)
+ log->Printf("Continuing breakpoint %s as AutoContinue was set.",
+ loc_desc.GetData());
+ // We want this stop reported, so you will know we auto-continued
+ // but only for external breakpoints:
+ if (!internal_breakpoint)
+ thread_sp->SetShouldReportStop(eVoteYes);
+ auto_continue_says_stop = false;
+ }
+
+ bool callback_says_stop = true;
// FIXME: For now the callbacks have to run in async mode - the
// first time we restart we need
@@ -493,11 +514,8 @@ protected:
debugger.SetAsyncExecution(old_async);
- if (callback_says_stop)
+ if (callback_says_stop && auto_continue_says_stop)
m_should_stop = true;
-
- if (m_should_stop && !bp_loc_sp->GetBreakpoint().IsInternal())
- internal_breakpoint = false;
// If we are going to stop for this breakpoint, then remove the
// breakpoint.
@@ -506,7 +524,6 @@ 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
// here.
@@ -1071,6 +1088,10 @@ private:
ExpressionVariableSP m_expression_variable_sp;
};
+//----------------------------------------------------------------------
+// StopInfoExec
+//----------------------------------------------------------------------
+
class StopInfoExec : public StopInfo {
public:
StopInfoExec(Thread &thread)
@@ -1078,6 +1099,13 @@ public:
~StopInfoExec() override = default;
+ bool ShouldStop(Event *event_ptr) override {
+ ThreadSP thread_sp(m_thread_wp.lock());
+ if (thread_sp)
+ return thread_sp->GetProcess()->GetStopOnExec();
+ return false;
+ }
+
StopReason GetStopReason() const override { return eStopReasonExec; }
const char *GetDescription() override { return "exec"; }
diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp
index d97f651ca08b4..903f50887fec0 100644
--- a/source/Target/Target.cpp
+++ b/source/Target/Target.cpp
@@ -26,6 +26,7 @@
#include "lldb/Core/Event.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/SourceManager.h"
#include "lldb/Core/State.h"
@@ -65,6 +66,16 @@ using namespace lldb_private;
constexpr std::chrono::milliseconds EvaluateExpressionOptions::default_timeout;
+Target::Arch::Arch(const ArchSpec &spec)
+ : m_spec(spec),
+ m_plugin_up(PluginManager::CreateArchitectureInstance(spec)) {}
+
+const Target::Arch& Target::Arch::operator=(const ArchSpec &spec) {
+ m_spec = spec;
+ m_plugin_up = PluginManager::CreateArchitectureInstance(spec);
+ return *this;
+}
+
ConstString &Target::GetStaticBroadcasterClass() {
static ConstString class_name("lldb.target");
return class_name;
@@ -76,12 +87,12 @@ 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_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)
{
@@ -96,10 +107,11 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch,
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
if (log)
log->Printf("%p Target::Target()", static_cast<void *>(this));
- if (m_arch.IsValid()) {
- LogIfAnyCategoriesSet(
- LIBLLDB_LOG_TARGET, "Target::Target created with architecture %s (%s)",
- m_arch.GetArchitectureName(), m_arch.GetTriple().getTriple().c_str());
+ if (target_arch.IsValid()) {
+ LogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET,
+ "Target::Target created with architecture %s (%s)",
+ target_arch.GetArchitectureName(),
+ target_arch.GetTriple().getTriple().c_str());
}
}
@@ -123,6 +135,13 @@ void Target::PrimeFromDummyTarget(Target *target) {
BreakpointSP new_bp(new Breakpoint(*this, *breakpoint_sp.get()));
AddBreakpoint(new_bp, false);
}
+
+ for (auto bp_name_entry : target->m_breakpoint_names)
+ {
+
+ BreakpointName *new_bp_name = new BreakpointName(*bp_name_entry.second);
+ AddBreakpointName(new_bp_name);
+ }
}
void Target::Dump(Stream *s, lldb::DescriptionLevel description_level) {
@@ -243,7 +262,7 @@ void Target::Destroy() {
m_valid = false;
DeleteCurrentProcess();
m_platform_sp.reset();
- m_arch.Clear();
+ m_arch = ArchSpec();
ClearModules(true);
m_section_load_history.Clear();
const bool notify = false;
@@ -601,6 +620,112 @@ void Target::AddBreakpoint(lldb::BreakpointSP bp_sp, bool internal) {
}
}
+void Target::AddNameToBreakpoint(BreakpointID &id,
+ const char *name,
+ Status &error)
+ {
+ BreakpointSP bp_sp
+ = m_breakpoint_list.FindBreakpointByID(id.GetBreakpointID());
+ if (!bp_sp)
+ {
+ StreamString s;
+ id.GetDescription(&s, eDescriptionLevelBrief);
+ error.SetErrorStringWithFormat("Could not find breakpoint %s",
+ s.GetData());
+ return;
+ }
+ AddNameToBreakpoint(bp_sp, name, error);
+ }
+
+void Target::AddNameToBreakpoint(BreakpointSP &bp_sp,
+ const char *name,
+ Status &error)
+ {
+ if (!bp_sp)
+ return;
+
+ BreakpointName *bp_name = FindBreakpointName(ConstString(name), true, error);
+ if (!bp_name)
+ return;
+
+ bp_name->ConfigureBreakpoint(bp_sp);
+ bp_sp->AddName(name);
+ }
+
+void Target::AddBreakpointName(BreakpointName *bp_name) {
+ m_breakpoint_names.insert(std::make_pair(bp_name->GetName(), bp_name));
+}
+
+BreakpointName *Target::FindBreakpointName(const ConstString &name,
+ bool can_create,
+ Status &error)
+{
+ BreakpointID::StringIsBreakpointName(name.GetStringRef(), error);
+ if (!error.Success())
+ return nullptr;
+
+ BreakpointNameList::iterator iter = m_breakpoint_names.find(name);
+ if (iter == m_breakpoint_names.end()) {
+ if (!can_create)
+ {
+ error.SetErrorStringWithFormat("Breakpoint name \"%s\" doesn't exist and "
+ "can_create is false.", name.AsCString());
+ return nullptr;
+ }
+
+ iter = m_breakpoint_names.insert(std::make_pair(name,
+ new BreakpointName(name)))
+ .first;
+ }
+ return (iter->second);
+}
+
+void
+Target::DeleteBreakpointName(const ConstString &name)
+{
+ BreakpointNameList::iterator iter = m_breakpoint_names.find(name);
+
+ if (iter != m_breakpoint_names.end()) {
+ const char *name_cstr = name.AsCString();
+ m_breakpoint_names.erase(iter);
+ for (auto bp_sp : m_breakpoint_list.Breakpoints())
+ bp_sp->RemoveName(name_cstr);
+ }
+}
+
+void Target::RemoveNameFromBreakpoint(lldb::BreakpointSP &bp_sp,
+ const ConstString &name)
+{
+ bp_sp->RemoveName(name.AsCString());
+}
+
+void Target::ConfigureBreakpointName(BreakpointName &bp_name,
+ const BreakpointOptions &new_options,
+ const BreakpointName::Permissions &new_permissions)
+{
+ bp_name.GetOptions().CopyOverSetOptions(new_options);
+ bp_name.GetPermissions().MergeInto(new_permissions);
+ ApplyNameToBreakpoints(bp_name);
+}
+
+void Target::ApplyNameToBreakpoints(BreakpointName &bp_name) {
+ BreakpointList bkpts_with_name(false);
+ m_breakpoint_list.FindBreakpointsByName(bp_name.GetName().AsCString(),
+ bkpts_with_name);
+
+ for (auto bp_sp : bkpts_with_name.Breakpoints())
+ bp_name.ConfigureBreakpoint(bp_sp);
+}
+
+void Target::GetBreakpointNames(std::vector<std::string> &names)
+{
+ names.clear();
+ for (auto bp_name : m_breakpoint_names) {
+ names.push_back(bp_name.first.AsCString());
+ }
+ std::sort(names.begin(), names.end());
+}
+
bool Target::ProcessIsValid() {
return (m_process_sp && m_process_sp->IsAlive());
}
@@ -703,6 +828,17 @@ WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size,
return wp_sp;
}
+void Target::RemoveAllowedBreakpoints ()
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf("Target::%s \n", __FUNCTION__);
+
+ m_breakpoint_list.RemoveAllowed(true);
+
+ m_last_created_breakpoint.reset();
+}
+
void Target::RemoveAllBreakpoints(bool internal_also) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
if (log)
@@ -727,6 +863,14 @@ void Target::DisableAllBreakpoints(bool internal_also) {
m_internal_breakpoint_list.SetEnabledAll(false);
}
+void Target::DisableAllowedBreakpoints() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf("Target::%s", __FUNCTION__);
+
+ m_breakpoint_list.SetEnabledAllowed(false);
+}
+
void Target::EnableAllBreakpoints(bool internal_also) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
if (log)
@@ -738,6 +882,14 @@ void Target::EnableAllBreakpoints(bool internal_also) {
m_internal_breakpoint_list.SetEnabledAll(true);
}
+void Target::EnableAllowedBreakpoints() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf("Target::%s", __FUNCTION__);
+
+ m_breakpoint_list.SetEnabledAllowed(true);
+}
+
bool Target::RemoveBreakpointByID(break_id_t break_id) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
if (log)
@@ -1226,8 +1378,8 @@ void Target::ClearModules(bool delete_locations) {
void Target::DidExec() {
// When a process exec's we need to know about it so we can do some cleanup.
- m_breakpoint_list.RemoveInvalidLocations(m_arch);
- m_internal_breakpoint_list.RemoveInvalidLocations(m_arch);
+ m_breakpoint_list.RemoveInvalidLocations(m_arch.GetSpec());
+ m_internal_breakpoint_list.RemoveInvalidLocations(m_arch.GetSpec());
}
void Target::SetExecutableModule(ModuleSP &executable_sp,
@@ -1245,13 +1397,12 @@ void Target::SetExecutableModule(ModuleSP &executable_sp,
// If we haven't set an architecture yet, reset our architecture based on
// what we found in the executable module.
- if (!m_arch.IsValid()) {
+ if (!m_arch.GetSpec().IsValid()) {
m_arch = executable_sp->GetArchitecture();
- if (log)
- log->Printf("Target::SetExecutableModule setting architecture to %s "
- "(%s) based on executable file",
- m_arch.GetArchitectureName(),
- m_arch.GetTriple().getTriple().c_str());
+ LLDB_LOG(log,
+ "setting architecture to {0} ({1}) based on executable file",
+ m_arch.GetSpec().GetArchitectureName(),
+ m_arch.GetSpec().GetTriple().getTriple());
}
FileSpecList dependent_files;
@@ -1269,7 +1420,7 @@ void Target::SetExecutableModule(ModuleSP &executable_sp,
else
platform_dependent_file_spec = dependent_file_spec;
- ModuleSpec module_spec(platform_dependent_file_spec, m_arch);
+ ModuleSpec module_spec(platform_dependent_file_spec, m_arch.GetSpec());
ModuleSP image_module_sp(GetSharedModule(module_spec));
if (image_module_sp) {
ObjectFile *objfile = image_module_sp->GetObjectFile();
@@ -1283,21 +1434,21 @@ void Target::SetExecutableModule(ModuleSP &executable_sp,
bool Target::SetArchitecture(const ArchSpec &arch_spec) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET));
- bool missing_local_arch = !m_arch.IsValid();
+ bool missing_local_arch = !m_arch.GetSpec().IsValid();
bool replace_local_arch = true;
bool compatible_local_arch = false;
ArchSpec other(arch_spec);
if (!missing_local_arch) {
- if (m_arch.IsCompatibleMatch(arch_spec)) {
- other.MergeFrom(m_arch);
+ if (m_arch.GetSpec().IsCompatibleMatch(arch_spec)) {
+ other.MergeFrom(m_arch.GetSpec());
- if (m_arch.IsCompatibleMatch(other)) {
+ if (m_arch.GetSpec().IsCompatibleMatch(other)) {
compatible_local_arch = true;
bool arch_changed, vendor_changed, os_changed, os_ver_changed,
env_changed;
- m_arch.PiecewiseTripleCompare(other, arch_changed, vendor_changed,
+ m_arch.GetSpec().PiecewiseTripleCompare(other, arch_changed, vendor_changed,
os_changed, os_ver_changed, env_changed);
if (!arch_changed && !vendor_changed && !os_changed && !env_changed)
@@ -1311,10 +1462,9 @@ bool Target::SetArchitecture(const ArchSpec &arch_spec) {
// update the architecture, unless the one we already have is more specified
if (replace_local_arch)
m_arch = other;
- if (log)
- log->Printf("Target::SetArchitecture set architecture to %s (%s)",
- m_arch.GetArchitectureName(),
- m_arch.GetTriple().getTriple().c_str());
+ LLDB_LOG(log, "set architecture to {0} ({1})",
+ m_arch.GetSpec().GetArchitectureName(),
+ m_arch.GetSpec().GetTriple().getTriple());
return true;
}
@@ -1351,12 +1501,12 @@ bool Target::SetArchitecture(const ArchSpec &arch_spec) {
bool Target::MergeArchitecture(const ArchSpec &arch_spec) {
if (arch_spec.IsValid()) {
- if (m_arch.IsCompatibleMatch(arch_spec)) {
+ 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"
// Merge bits from arch_spec into "merged_arch" and set our architecture
- ArchSpec merged_arch(m_arch);
+ ArchSpec merged_arch(m_arch.GetSpec());
merged_arch.MergeFrom(arch_spec);
return SetArchitecture(merged_arch);
} else {
@@ -1684,8 +1834,8 @@ size_t Target::ReadScalarIntegerFromMemory(const Address &addr,
size_t bytes_read =
ReadMemory(addr, prefer_file_cache, &uval, byte_size, error);
if (bytes_read == byte_size) {
- DataExtractor data(&uval, sizeof(uval), m_arch.GetByteOrder(),
- m_arch.GetAddressByteSize());
+ DataExtractor data(&uval, sizeof(uval), m_arch.GetSpec().GetByteOrder(),
+ m_arch.GetSpec().GetAddressByteSize());
lldb::offset_t offset = 0;
if (byte_size <= 4)
scalar = data.GetMaxU32(&offset, byte_size);
@@ -1719,7 +1869,7 @@ bool Target::ReadPointerFromMemory(const Address &addr, bool prefer_file_cache,
Status &error, Address &pointer_addr) {
Scalar scalar;
if (ReadScalarIntegerFromMemory(addr, prefer_file_cache,
- m_arch.GetAddressByteSize(), false, scalar,
+ m_arch.GetSpec().GetAddressByteSize(), false, scalar,
error)) {
addr_t pointer_vm_addr = scalar.ULongLong(LLDB_INVALID_ADDRESS);
if (pointer_vm_addr != LLDB_INVALID_ADDRESS) {
@@ -2212,7 +2362,7 @@ lldb::addr_t Target::GetPersistentSymbol(const ConstString &name) {
lldb::addr_t Target::GetCallableLoadAddress(lldb::addr_t load_addr,
AddressClass addr_class) const {
addr_t code_addr = load_addr;
- switch (m_arch.GetMachine()) {
+ switch (m_arch.GetSpec().GetMachine()) {
case llvm::Triple::mips:
case llvm::Triple::mipsel:
case llvm::Triple::mips64:
@@ -2271,7 +2421,7 @@ lldb::addr_t Target::GetCallableLoadAddress(lldb::addr_t load_addr,
lldb::addr_t Target::GetOpcodeLoadAddress(lldb::addr_t load_addr,
AddressClass addr_class) const {
addr_t opcode_addr = load_addr;
- switch (m_arch.GetMachine()) {
+ switch (m_arch.GetSpec().GetMachine()) {
case llvm::Triple::mips:
case llvm::Triple::mipsel:
case llvm::Triple::mips64:
@@ -2303,7 +2453,7 @@ lldb::addr_t Target::GetBreakableLoadAddress(lldb::addr_t addr) {
addr_t breakable_addr = addr;
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- switch (m_arch.GetMachine()) {
+ switch (m_arch.GetSpec().GetMachine()) {
default:
break;
case llvm::Triple::mips:
@@ -2314,7 +2464,7 @@ lldb::addr_t Target::GetBreakableLoadAddress(lldb::addr_t addr) {
addr_t current_offset = 0;
uint32_t loop_count = 0;
Address resolved_addr;
- uint32_t arch_flags = m_arch.GetFlags();
+ uint32_t arch_flags = m_arch.GetSpec().GetFlags();
bool IsMips16 = arch_flags & ArchSpec::eMIPSAse_mips16;
bool IsMicromips = arch_flags & ArchSpec::eMIPSAse_micromips;
SectionLoadList &section_load_list = GetSectionLoadList();
@@ -2367,7 +2517,7 @@ lldb::addr_t Target::GetBreakableLoadAddress(lldb::addr_t addr) {
// Create Disassembler Instance
lldb::DisassemblerSP disasm_sp(
- Disassembler::FindPlugin(m_arch, nullptr, nullptr));
+ Disassembler::FindPlugin(m_arch.GetSpec(), nullptr, nullptr));
ExecutionContext exe_ctx;
CalculateExecutionContext(exe_ctx);
@@ -2529,6 +2679,10 @@ void Target::RunStopHooks() {
if (!m_process_sp)
return;
+
+ // Somebody might have restarted the process:
+ if (m_process_sp->GetState() != eStateStopped)
+ return;
// <rdar://problem/12027563> make sure we check that we are not stopped
// because of us running a user expression
@@ -2634,9 +2788,12 @@ void Target::RunStopHooks() {
// running the stop hooks.
if ((result.GetStatus() == eReturnStatusSuccessContinuingNoResult) ||
(result.GetStatus() == eReturnStatusSuccessContinuingResult)) {
- result.AppendMessageWithFormat("Aborting stop hooks, hook %" PRIu64
- " set the program running.",
- cur_hook_sp->GetID());
+ // But only complain if there were more stop hooks to do:
+ StopHookCollection::iterator tmp = pos;
+ if (++tmp != end)
+ result.AppendMessageWithFormat("\nAborting stop hooks, hook %" PRIu64
+ " set the program running.\n",
+ cur_hook_sp->GetID());
keep_going = false;
}
}
@@ -3505,9 +3662,11 @@ static PropertyDefinition g_experimental_properties[]{
"This will fix symbol resolution when there are name collisions between "
"ivars and local variables. "
"But it can make expressions run much more slowly."},
+ {"use-modern-type-lookup", OptionValue::eTypeBoolean, true, false, nullptr,
+ nullptr, "If true, use Clang's modern type lookup infrastructure."},
{nullptr, OptionValue::eTypeInvalid, true, 0, nullptr, nullptr, nullptr}};
-enum { ePropertyInjectLocalVars = 0 };
+enum { ePropertyInjectLocalVars = 0, ePropertyUseModernTypeLookup };
class TargetExperimentalOptionValueProperties : public OptionValueProperties {
public:
@@ -3618,6 +3777,18 @@ void TargetProperties::SetInjectLocalVariables(ExecutionContext *exe_ctx,
true);
}
+bool TargetProperties::GetUseModernTypeLookup() const {
+ const Property *exp_property = m_collection_sp->GetPropertyAtIndex(
+ nullptr, false, ePropertyExperimental);
+ OptionValueProperties *exp_values =
+ exp_property->GetValue()->GetAsProperties();
+ if (exp_values)
+ return exp_values->GetPropertyAtIndexAsBoolean(
+ nullptr, ePropertyUseModernTypeLookup, true);
+ else
+ return true;
+}
+
ArchSpec TargetProperties::GetDefaultArchitecture() const {
OptionValueArch *value = m_collection_sp->GetPropertyAtIndexAsOptionValueArch(
nullptr, ePropertyDefaultArch);
diff --git a/source/Target/Thread.cpp b/source/Target/Thread.cpp
index 505d14012d65b..217cbccedf6e5 100644
--- a/source/Target/Thread.cpp
+++ b/source/Target/Thread.cpp
@@ -442,10 +442,9 @@ lldb::StopInfoSP Thread::GetPrivateStopInfo() {
if (m_stop_info_override_stop_id != process_stop_id) {
m_stop_info_override_stop_id = process_stop_id;
if (m_stop_info_sp) {
- ArchSpec::StopInfoOverrideCallbackType callback =
- GetProcess()->GetStopInfoOverrideCallback();
- if (callback)
- callback(*this);
+ if (Architecture *arch =
+ process_sp->GetTarget().GetArchitecturePlugin())
+ arch->OverrideStopInfo(*this);
}
}
}
@@ -2075,6 +2074,7 @@ Unwind *Thread::GetUnwinder() {
case llvm::Triple::mips64el:
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
+ case llvm::Triple::ppc64le:
case llvm::Triple::systemz:
case llvm::Triple::hexagon:
m_unwinder_ap.reset(new UnwindLLDB(*this));
diff --git a/source/Target/ThreadPlanStepInRange.cpp b/source/Target/ThreadPlanStepInRange.cpp
index caaaffea8e8ad..6c5a9954f23f4 100644
--- a/source/Target/ThreadPlanStepInRange.cpp
+++ b/source/Target/ThreadPlanStepInRange.cpp
@@ -191,8 +191,12 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) {
if (!m_sub_plan_sp) {
// Otherwise check the ShouldStopHere for step out:
m_sub_plan_sp = CheckShouldStopHereAndQueueStepOut(frame_order);
- if (log)
- log->Printf("ShouldStopHere says we should step out of this frame.");
+ if (log) {
+ if (m_sub_plan_sp)
+ log->Printf("ShouldStopHere found plan to step out of this frame.");
+ else
+ log->Printf("ShouldStopHere no plan to step out of this frame.");
+ }
} else if (log) {
log->Printf(
"Thought I stepped out, but in fact arrived at a trampoline.");
diff --git a/source/Target/ThreadPlanTracer.cpp b/source/Target/ThreadPlanTracer.cpp
index 014c7fd27975c..5057ca0a711bb 100644
--- a/source/Target/ThreadPlanTracer.cpp
+++ b/source/Target/ThreadPlanTracer.cpp
@@ -11,9 +11,6 @@
// C++ Includes
#include <cstring>
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Module.h"
diff --git a/source/Target/UnixSignals.cpp b/source/Target/UnixSignals.cpp
index a4ec32bd00759..150c6619859ff 100644
--- a/source/Target/UnixSignals.cpp
+++ b/source/Target/UnixSignals.cpp
@@ -16,8 +16,8 @@
#include "Plugins/Process/Utility/LinuxSignals.h"
#include "Plugins/Process/Utility/MipsLinuxSignals.h"
#include "Plugins/Process/Utility/NetBSDSignals.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Host/StringConvert.h"
+#include "lldb/Utility/ArchSpec.h"
using namespace lldb_private;
diff --git a/source/Core/ArchSpec.cpp b/source/Utility/ArchSpec.cpp
index bfe9750f70f05..a10fe78260bb3 100644
--- a/source/Core/ArchSpec.cpp
+++ b/source/Utility/ArchSpec.cpp
@@ -7,21 +7,12 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Core/ArchSpec.h"
+#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Target/Platform.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/Thread.h"
#include "lldb/Utility/NameMatches.h"
#include "lldb/Utility/Stream.h" // for Stream
#include "lldb/Utility/StringList.h"
#include "lldb/lldb-defines.h" // for LLDB_INVALID_C...
-#include "lldb/lldb-forward.h" // for RegisterContextSP
-
-#include "Plugins/Process/Utility/ARMDefines.h"
-#include "Plugins/Process/Utility/InstructionUtils.h"
-
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Twine.h" // for Twine
#include "llvm/BinaryFormat/COFF.h"
@@ -30,10 +21,6 @@
#include "llvm/Support/Compiler.h" // for LLVM_FALLTHROUGH
#include "llvm/Support/Host.h"
-#include <memory> // for shared_ptr
-#include <string>
-#include <tuple> // for tie, tuple
-
using namespace lldb;
using namespace lldb_private;
@@ -188,6 +175,8 @@ static const CoreDefinition g_core_definitions[] = {
{eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc970,
"ppc970"},
+ {eByteOrderLittle, 8, 4, 4, llvm::Triple::ppc64le,
+ ArchSpec::eCore_ppc64le_generic, "powerpc64le"},
{eByteOrderBig, 8, 4, 4, llvm::Triple::ppc64, ArchSpec::eCore_ppc64_generic,
"powerpc64"},
{eByteOrderBig, 8, 4, 4, llvm::Triple::ppc64,
@@ -372,6 +361,8 @@ static const ArchDefinitionEntry g_macho_arch_entries[] = {
SUBTYPE_MASK},
{ArchSpec::eCore_ppc64_generic, llvm::MachO::CPU_TYPE_POWERPC64, 0,
UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc64le_generic, llvm::MachO::CPU_TYPE_POWERPC64, CPU_ANY,
+ UINT32_MAX, SUBTYPE_MASK},
{ArchSpec::eCore_ppc64_ppc970_64, llvm::MachO::CPU_TYPE_POWERPC64, 100,
UINT32_MAX, SUBTYPE_MASK},
{ArchSpec::eCore_x86_32_i386, llvm::MachO::CPU_TYPE_I386, 3, UINT32_MAX,
@@ -414,6 +405,8 @@ static const ArchDefinitionEntry g_elf_arch_entries[] = {
0xFFFFFFFFu, 0xFFFFFFFFu}, // Intel MCU // FIXME: is this correct?
{ArchSpec::eCore_ppc_generic, llvm::ELF::EM_PPC, LLDB_INVALID_CPUTYPE,
0xFFFFFFFFu, 0xFFFFFFFFu}, // PowerPC
+ {ArchSpec::eCore_ppc64le_generic, llvm::ELF::EM_PPC64, LLDB_INVALID_CPUTYPE,
+ 0xFFFFFFFFu, 0xFFFFFFFFu}, // PowerPC64le
{ArchSpec::eCore_ppc64_generic, llvm::ELF::EM_PPC64, LLDB_INVALID_CPUTYPE,
0xFFFFFFFFu, 0xFFFFFFFFu}, // PowerPC64
{ArchSpec::eCore_arm_generic, llvm::ELF::EM_ARM, LLDB_INVALID_CPUTYPE,
@@ -461,7 +454,9 @@ static const ArchDefinitionEntry g_elf_arch_entries[] = {
};
static const ArchDefinition g_elf_arch_def = {
- eArchTypeELF, llvm::array_lengthof(g_elf_arch_entries), g_elf_arch_entries,
+ eArchTypeELF,
+ llvm::array_lengthof(g_elf_arch_entries),
+ g_elf_arch_entries,
"elf",
};
@@ -483,8 +478,10 @@ static const ArchDefinitionEntry g_coff_arch_entries[] = {
};
static const ArchDefinition g_coff_arch_def = {
- eArchTypeCOFF, llvm::array_lengthof(g_coff_arch_entries),
- g_coff_arch_entries, "pe-coff",
+ eArchTypeCOFF,
+ llvm::array_lengthof(g_coff_arch_entries),
+ g_coff_arch_entries,
+ "pe-coff",
};
//===----------------------------------------------------------------------===//
@@ -518,7 +515,7 @@ static const CoreDefinition *FindCoreDefinition(llvm::StringRef name) {
}
static inline const CoreDefinition *FindCoreDefinition(ArchSpec::Core core) {
- if (core >= 0 && core < llvm::array_lengthof(g_core_definitions))
+ if (core < llvm::array_lengthof(g_core_definitions))
return &g_core_definitions[core];
return nullptr;
}
@@ -556,15 +553,6 @@ FindArchDefinitionEntry(const ArchDefinition *def, ArchSpec::Core core) {
ArchSpec::ArchSpec() {}
-ArchSpec::ArchSpec(const char *triple_cstr, Platform *platform) {
- if (triple_cstr)
- SetTriple(triple_cstr, platform);
-}
-
-ArchSpec::ArchSpec(llvm::StringRef triple_str, Platform *platform) {
- SetTriple(triple_str, platform);
-}
-
ArchSpec::ArchSpec(const char *triple_cstr) {
if (triple_cstr)
SetTriple(triple_cstr);
@@ -874,16 +862,6 @@ bool lldb_private::ParseMachCPUDashSubtypeTriple(llvm::StringRef triple_str,
return true;
}
-bool ArchSpec::SetTriple(const char *triple_cstr) {
- llvm::StringRef str(triple_cstr ? triple_cstr : "");
- return SetTriple(str);
-}
-
-bool ArchSpec::SetTriple(const char *triple_cstr, Platform *platform) {
- llvm::StringRef str(triple_cstr ? triple_cstr : "");
- return SetTriple(str, platform);
-}
-
bool ArchSpec::SetTriple(llvm::StringRef triple) {
if (triple.empty()) {
Clear();
@@ -893,87 +871,15 @@ bool ArchSpec::SetTriple(llvm::StringRef triple) {
if (ParseMachCPUDashSubtypeTriple(triple, *this))
return true;
- if (triple.startswith(LLDB_ARCH_DEFAULT)) {
- // Special case for the current host default architectures...
- if (triple.equals(LLDB_ARCH_DEFAULT_32BIT))
- *this = HostInfo::GetArchitecture(HostInfo::eArchKind32);
- else if (triple.equals(LLDB_ARCH_DEFAULT_64BIT))
- *this = HostInfo::GetArchitecture(HostInfo::eArchKind64);
- else if (triple.equals(LLDB_ARCH_DEFAULT))
- *this = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
- } else {
- SetTriple(llvm::Triple(llvm::Triple::normalize(triple)));
- }
+ SetTriple(llvm::Triple(llvm::Triple::normalize(triple)));
return IsValid();
}
-bool ArchSpec::SetTriple(llvm::StringRef triple, Platform *platform) {
- if (triple.empty()) {
- Clear();
- return false;
- }
- if (ParseMachCPUDashSubtypeTriple(triple, *this))
- return true;
-
- if (triple.startswith(LLDB_ARCH_DEFAULT)) {
- // Special case for the current host default architectures...
- if (triple.equals(LLDB_ARCH_DEFAULT_32BIT))
- *this = HostInfo::GetArchitecture(HostInfo::eArchKind32);
- else if (triple.equals(LLDB_ARCH_DEFAULT_64BIT))
- *this = HostInfo::GetArchitecture(HostInfo::eArchKind64);
- else if (triple.equals(LLDB_ARCH_DEFAULT))
- *this = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
- return IsValid();
- }
-
- ArchSpec raw_arch(triple);
-
- llvm::Triple normalized_triple(llvm::Triple::normalize(triple));
-
- const bool os_specified = !normalized_triple.getOSName().empty();
- const bool vendor_specified = !normalized_triple.getVendorName().empty();
- const bool env_specified = !normalized_triple.getEnvironmentName().empty();
-
- if (os_specified || vendor_specified || env_specified) {
- SetTriple(normalized_triple);
- return IsValid();
- }
-
- // We got an arch only. If there is no platform, fallback to the host system
- // for defaults.
- if (!platform) {
- llvm::Triple host_triple(llvm::sys::getDefaultTargetTriple());
- if (!vendor_specified)
- normalized_triple.setVendor(host_triple.getVendor());
- if (!vendor_specified)
- normalized_triple.setOS(host_triple.getOS());
- if (!env_specified && host_triple.getEnvironmentName().size())
- normalized_triple.setEnvironment(host_triple.getEnvironment());
- SetTriple(normalized_triple);
- return IsValid();
- }
-
- // If we were given a platform, use the platform's system architecture. If
- // this is not available (might not be connected) use the first supported
- // architecture.
- ArchSpec compatible_arch;
- if (!platform->IsCompatibleArchitecture(raw_arch, false, &compatible_arch)) {
- *this = raw_arch;
- return IsValid();
- }
-
- if (compatible_arch.IsValid()) {
- const llvm::Triple &compatible_triple = compatible_arch.GetTriple();
- if (!vendor_specified)
- normalized_triple.setVendor(compatible_triple.getVendor());
- if (!os_specified)
- normalized_triple.setOS(compatible_triple.getOS());
- if (!env_specified && compatible_triple.hasEnvironment())
- normalized_triple.setEnvironment(compatible_triple.getEnvironment());
- }
-
- SetTriple(normalized_triple);
- return IsValid();
+bool ArchSpec::ContainsOnlyArch(const llvm::Triple &normalized_triple) {
+ return !normalized_triple.getArchName().empty() &&
+ normalized_triple.getOSName().empty() &&
+ normalized_triple.getVendorName().empty() &&
+ normalized_triple.getEnvironmentName().empty();
}
void ArchSpec::MergeFrom(const ArchSpec &other) {
@@ -1002,6 +908,9 @@ void ArchSpec::MergeFrom(const ArchSpec &other) {
m_core = other.GetCore();
CoreUpdated(true);
}
+ if (GetFlags() == 0) {
+ SetFlags(other.GetFlags());
+ }
}
bool ArchSpec::SetArchitecture(ArchitectureType arch_type, uint32_t cpu,
@@ -1502,102 +1411,6 @@ bool lldb_private::operator<(const ArchSpec &lhs, const ArchSpec &rhs) {
return lhs_core < rhs_core;
}
-static void StopInfoOverrideCallbackTypeARM(lldb_private::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.
- //
- // 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
- // 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.
- //
- // 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).
-
- RegisterContextSP reg_ctx_sp(thread.GetRegisterContext());
- if (reg_ctx_sp) {
- const uint32_t cpsr = reg_ctx_sp->GetFlags(0);
- if (cpsr != 0) {
- // Read the J and T bits to get the ISETSTATE
- const uint32_t J = Bit32(cpsr, 24);
- const uint32_t T = Bit32(cpsr, 5);
- 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.
-// I will check with the lldb-dev list first before I enable this.
-#if 0
- // ARM mode: check for condition on intsruction
- 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.
- const uint64_t opcode = thread.GetProcess()->ReadUnsignedIntegerFromMemory(pc, 4, UINT64_MAX, error);
- if (opcode <= UINT32_MAX)
- {
- const uint32_t condition = Bits32((uint32_t)opcode, 31, 28);
- 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
- thread.SetStopInfo (StopInfoSP());
- }
- }
-#endif
- } else if (ISETSTATE == 1) {
- // Thumb mode
- const uint32_t ITSTATE =
- Bits32(cpsr, 15, 10) << 2 | Bits32(cpsr, 26, 25);
- if (ITSTATE != 0) {
- const uint32_t condition = Bits32(ITSTATE, 7, 4);
- if (!ARMConditionPassed(condition, cpsr)) {
- // We ARE stopped in a Thumb IT instruction on an instruction whose
- // condition doesn't pass so this instruction won't get executed.
- // Regardless of why it stopped, we need to clear the stop info
- thread.SetStopInfo(StopInfoSP());
- }
- }
- }
- }
- }
-}
-
-ArchSpec::StopInfoOverrideCallbackType
-ArchSpec::GetStopInfoOverrideCallback() const {
- const llvm::Triple::ArchType machine = GetMachine();
- if (machine == llvm::Triple::arm)
- return StopInfoOverrideCallbackTypeARM;
- return nullptr;
-}
-
bool ArchSpec::IsFullySpecifiedTriple() const {
const auto &user_specified_triple = GetTriple();
@@ -1619,7 +1432,7 @@ bool ArchSpec::IsFullySpecifiedTriple() const {
void ArchSpec::PiecewiseTripleCompare(
const ArchSpec &other, bool &arch_different, bool &vendor_different,
- bool &os_different, bool &os_version_different, bool &env_different) {
+ bool &os_different, bool &os_version_different, bool &env_different) const {
const llvm::Triple &me(GetTriple());
const llvm::Triple &them(other.GetTriple());
diff --git a/source/Utility/CMakeLists.txt b/source/Utility/CMakeLists.txt
index 78598562692bb..1a0fb6f86c574 100644
--- a/source/Utility/CMakeLists.txt
+++ b/source/Utility/CMakeLists.txt
@@ -1,4 +1,46 @@
+set(LLDB_SYSTEM_LIBS)
+
+# Windows-only libraries
+if ( CMAKE_SYSTEM_NAME MATCHES "Windows" )
+ list(APPEND LLDB_SYSTEM_LIBS
+ ws2_32
+ rpcrt4
+ )
+endif ()
+
+if (NOT LLDB_DISABLE_LIBEDIT)
+ list(APPEND LLDB_SYSTEM_LIBS edit)
+endif()
+if (NOT LLDB_DISABLE_CURSES)
+ list(APPEND LLDB_SYSTEM_LIBS ${CURSES_LIBRARIES})
+ if(LLVM_ENABLE_TERMINFO AND HAVE_TERMINFO)
+ list(APPEND LLDB_SYSTEM_LIBS ${TERMINFO_LIBS})
+ endif()
+endif()
+
+if (NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB )
+ list(APPEND LLDB_SYSTEM_LIBS atomic)
+endif()
+
+list(APPEND LLDB_SYSTEM_LIBS ${Backtrace_LIBRARY})
+
+if (NOT LLDB_DISABLE_PYTHON AND NOT LLVM_BUILD_STATIC)
+ list(APPEND LLDB_SYSTEM_LIBS ${PYTHON_LIBRARIES})
+endif()
+
+list(APPEND LLDB_SYSTEM_LIBS ${system_libs})
+
+if (LLVM_BUILD_STATIC)
+ if (NOT LLDB_DISABLE_PYTHON)
+ list(APPEND LLDB_SYSTEM_LIBS python2.7 util)
+ endif()
+ if (NOT LLDB_DISABLE_CURSES)
+ list(APPEND LLDB_SYSTEM_LIBS gpm)
+ endif()
+endif()
+
add_lldb_library(lldbUtility
+ ArchSpec.cpp
Baton.cpp
Connection.cpp
ConstString.cpp
@@ -29,7 +71,6 @@ add_lldb_library(lldbUtility
StringLexer.cpp
StringList.cpp
StructuredData.cpp
- TaskPool.cpp
TildeExpressionResolver.cpp
Timer.cpp
UserID.cpp
@@ -39,7 +80,8 @@ add_lldb_library(lldbUtility
VMRange.cpp
LINK_LIBS
- # lldbUtility cannot have any dependencies
+ ${LLDB_SYSTEM_LIBS}
+ # lldbUtility does not depend on other LLDB libraries
LINK_COMPONENTS
BinaryFormat
diff --git a/source/Utility/DataEncoder.cpp b/source/Utility/DataEncoder.cpp
index f7ce46889d2f4..433a15bc95230 100644
--- a/source/Utility/DataEncoder.cpp
+++ b/source/Utility/DataEncoder.cpp
@@ -12,6 +12,7 @@
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/Endian.h"
+#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorHandling.h" // for llvm_unreachable
#include "llvm/Support/MathExtras.h"
@@ -22,36 +23,7 @@
using namespace lldb;
using namespace lldb_private;
-
-static inline void WriteInt16(unsigned char *ptr, unsigned offset,
- uint16_t value) {
- *(uint16_t *)(ptr + offset) = value;
-}
-
-static inline void WriteInt32(unsigned char *ptr, unsigned offset,
- uint32_t value) {
- *(uint32_t *)(ptr + offset) = value;
-}
-
-static inline void WriteInt64(unsigned char *ptr, unsigned offset,
- uint64_t value) {
- *(uint64_t *)(ptr + offset) = value;
-}
-
-static inline void WriteSwappedInt16(unsigned char *ptr, unsigned offset,
- uint16_t value) {
- *(uint16_t *)(ptr + offset) = llvm::ByteSwap_16(value);
-}
-
-static inline void WriteSwappedInt32(unsigned char *ptr, unsigned offset,
- uint32_t value) {
- *(uint32_t *)(ptr + offset) = llvm::ByteSwap_32(value);
-}
-
-static inline void WriteSwappedInt64(unsigned char *ptr, unsigned offset,
- uint64_t value) {
- *(uint64_t *)(ptr + offset) = llvm::ByteSwap_64(value);
-}
+using namespace llvm::support::endian;
//----------------------------------------------------------------------
// Default constructor.
@@ -202,9 +174,9 @@ uint32_t DataEncoder::PutU8(uint32_t offset, uint8_t value) {
uint32_t DataEncoder::PutU16(uint32_t offset, uint16_t value) {
if (ValidOffsetForDataOfSize(offset, sizeof(value))) {
if (m_byte_order != endian::InlHostByteOrder())
- WriteSwappedInt16(m_start, offset, value);
+ write16be(m_start + offset, value);
else
- WriteInt16(m_start, offset, value);
+ write16le(m_start + offset, value);
return offset + sizeof(value);
}
@@ -214,9 +186,9 @@ uint32_t DataEncoder::PutU16(uint32_t offset, uint16_t value) {
uint32_t DataEncoder::PutU32(uint32_t offset, uint32_t value) {
if (ValidOffsetForDataOfSize(offset, sizeof(value))) {
if (m_byte_order != endian::InlHostByteOrder())
- WriteSwappedInt32(m_start, offset, value);
+ write32be(m_start + offset, value);
else
- WriteInt32(m_start, offset, value);
+ write32le(m_start + offset, value);
return offset + sizeof(value);
}
@@ -226,9 +198,9 @@ uint32_t DataEncoder::PutU32(uint32_t offset, uint32_t value) {
uint32_t DataEncoder::PutU64(uint32_t offset, uint64_t value) {
if (ValidOffsetForDataOfSize(offset, sizeof(value))) {
if (m_byte_order != endian::InlHostByteOrder())
- WriteSwappedInt64(m_start, offset, value);
+ write64be(m_start + offset, value);
else
- WriteInt64(m_start, offset, value);
+ write64le(m_start + offset, value);
return offset + sizeof(value);
}
diff --git a/source/Utility/DataExtractor.cpp b/source/Utility/DataExtractor.cpp
index 008aff220945b..84c5f81915212 100644
--- a/source/Utility/DataExtractor.cpp
+++ b/source/Utility/DataExtractor.cpp
@@ -17,6 +17,7 @@
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Endian.h"
+#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StreamString.h"
@@ -105,6 +106,20 @@ static inline uint64_t ReadSwapInt64(const void *ptr) {
return llvm::ByteSwap_64(value);
}
+static inline uint64_t ReadMaxInt64(const uint8_t *data, size_t byte_size,
+ ByteOrder byte_order) {
+ uint64_t res = 0;
+ if (byte_order == eByteOrderBig)
+ for (size_t i = 0; i < byte_size; ++i)
+ res = (res << 8) | data[i];
+ else {
+ assert(byte_order == eByteOrderLittle);
+ for (size_t i = 0; i < byte_size; ++i)
+ res = (res << 8) | data[byte_size - 1 - i];
+ }
+ return res;
+}
+
DataExtractor::DataExtractor()
: m_start(nullptr), m_end(nullptr),
m_byte_order(endian::InlHostByteOrder()), m_addr_size(sizeof(void *)),
@@ -551,107 +566,59 @@ void *DataExtractor::GetU64(offset_t *offset_ptr, void *void_dst,
return nullptr;
}
-//----------------------------------------------------------------------
-// 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 between 1 and 4 since the return value is only 32 bits
-// wide. Any "byte_size" values less than 1 or greater than 4 will
-// result in nothing being extracted, and zero being returned.
-//
-// RETURNS the integer value that was extracted, or zero on failure.
-//----------------------------------------------------------------------
uint32_t DataExtractor::GetMaxU32(offset_t *offset_ptr,
size_t byte_size) const {
- switch (byte_size) {
- case 1:
- return GetU8(offset_ptr);
- break;
- case 2:
- return GetU16(offset_ptr);
- break;
- case 4:
- return GetU32(offset_ptr);
- break;
- default:
- assert(false && "GetMaxU32 unhandled case!");
- break;
- }
- return 0;
+ lldbassert(byte_size > 0 && byte_size <= 4 && "GetMaxU32 invalid byte_size!");
+ return GetMaxU64(offset_ptr, byte_size);
}
-//----------------------------------------------------------------------
-// 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.
-//----------------------------------------------------------------------
-uint64_t DataExtractor::GetMaxU64(offset_t *offset_ptr, size_t size) const {
- switch (size) {
+uint64_t DataExtractor::GetMaxU64(offset_t *offset_ptr,
+ size_t byte_size) const {
+ lldbassert(byte_size > 0 && byte_size <= 8 && "GetMaxU64 invalid byte_size!");
+ switch (byte_size) {
case 1:
return GetU8(offset_ptr);
- break;
case 2:
return GetU16(offset_ptr);
- break;
case 4:
return GetU32(offset_ptr);
- break;
case 8:
return GetU64(offset_ptr);
- break;
- default:
- assert(false && "GetMax64 unhandled case!");
- break;
+ default: {
+ // General case.
+ const uint8_t *data =
+ static_cast<const uint8_t *>(GetData(offset_ptr, byte_size));
+ if (data == nullptr)
+ return 0;
+ return ReadMaxInt64(data, byte_size, m_byte_order);
+ }
}
return 0;
}
uint64_t DataExtractor::GetMaxU64_unchecked(offset_t *offset_ptr,
- size_t size) const {
- switch (size) {
+ size_t byte_size) const {
+ switch (byte_size) {
case 1:
return GetU8_unchecked(offset_ptr);
- break;
case 2:
return GetU16_unchecked(offset_ptr);
- break;
case 4:
return GetU32_unchecked(offset_ptr);
- break;
case 8:
return GetU64_unchecked(offset_ptr);
- break;
- default:
- assert(false && "GetMax64 unhandled case!");
- break;
+ default: {
+ uint64_t res = ReadMaxInt64(&m_start[*offset_ptr], byte_size, m_byte_order);
+ *offset_ptr += byte_size;
+ return res;
+ }
}
return 0;
}
-int64_t DataExtractor::GetMaxS64(offset_t *offset_ptr, size_t size) const {
- switch (size) {
- case 1:
- return (int8_t)GetU8(offset_ptr);
- break;
- case 2:
- return (int16_t)GetU16(offset_ptr);
- break;
- case 4:
- return (int32_t)GetU32(offset_ptr);
- break;
- case 8:
- return (int64_t)GetU64(offset_ptr);
- break;
- default:
- assert(false && "GetMax64 unhandled case!");
- break;
- }
- return 0;
+int64_t DataExtractor::GetMaxS64(offset_t *offset_ptr, size_t byte_size) const {
+ uint64_t u64 = GetMaxU64(offset_ptr, byte_size);
+ return llvm::SignExtend64(u64, 8 * byte_size);
}
uint64_t DataExtractor::GetMaxU64Bitfield(offset_t *offset_ptr, size_t size,
diff --git a/source/Utility/FileSpec.cpp b/source/Utility/FileSpec.cpp
index 3c4e3407ddf65..72f86917b813b 100644
--- a/source/Utility/FileSpec.cpp
+++ b/source/Utility/FileSpec.cpp
@@ -700,18 +700,18 @@ void FileSpec::EnumerateDirectory(llvm::StringRef dir_path,
fs::recursive_directory_iterator End;
for (; Iter != End && !EC; Iter.increment(EC)) {
const auto &Item = *Iter;
- fs::file_status Status;
- if ((EC = Item.status(Status)))
+ llvm::ErrorOr<fs::basic_file_status> Status = Item.status();
+ if (!Status)
break;
- if (!find_files && fs::is_regular_file(Status))
+ if (!find_files && fs::is_regular_file(*Status))
continue;
- if (!find_directories && fs::is_directory(Status))
+ if (!find_directories && fs::is_directory(*Status))
continue;
- if (!find_other && fs::is_other(Status))
+ if (!find_other && fs::is_other(*Status))
continue;
FileSpec Spec(Item.path(), false);
- auto Result = callback(callback_baton, Status.type(), Spec);
+ auto Result = callback(callback_baton, Status->type(), Spec);
if (Result == eEnumerateDirectoryResultQuit)
return;
if (Result == eEnumerateDirectoryResultNext) {
diff --git a/source/Utility/JSON.cpp b/source/Utility/JSON.cpp
index 1520bc7c47ec7..9049f596ab9a5 100644
--- a/source/Utility/JSON.cpp
+++ b/source/Utility/JSON.cpp
@@ -22,7 +22,7 @@
using namespace lldb_private;
std::string JSONString::json_string_quote_metachars(const std::string &s) {
- if (s.find('"') == std::string::npos)
+ if (s.find_first_of("\\\n\"") == std::string::npos)
return s;
std::string output;
@@ -30,8 +30,9 @@ std::string JSONString::json_string_quote_metachars(const std::string &s) {
const char *s_chars = s.c_str();
for (size_t i = 0; i < s_size; i++) {
unsigned char ch = *(s_chars + i);
- if (ch == '"') {
+ if (ch == '"' || ch == '\\' || ch == '\n') {
output.push_back('\\');
+ if (ch == '\n') ch = 'n';
}
output.push_back(ch);
}
diff --git a/source/Utility/Log.cpp b/source/Utility/Log.cpp
index a80b106838bc5..f247124f8d632 100644
--- a/source/Utility/Log.cpp
+++ b/source/Utility/Log.cpp
@@ -32,6 +32,7 @@
#include <process.h> // for getpid
#else
#include <unistd.h>
+#include <pthread.h>
#endif
using namespace lldb_private;
@@ -181,6 +182,13 @@ void Log::Warning(const char *format, ...) {
Printf("warning: %s", Content.c_str());
}
+void Log::Initialize() {
+#ifdef LLVM_ON_UNIX
+ pthread_atfork(nullptr, nullptr, &Log::DisableLoggingChild);
+#endif
+ InitializeLldbChannel();
+}
+
void Log::Register(llvm::StringRef name, Channel &channel) {
auto iter = g_channel_map->try_emplace(name, channel);
assert(iter.second == true);
@@ -279,8 +287,7 @@ 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);
- if (!thread_name.empty())
- OS << thread_name;
+ OS << llvm::formatv("{0,-16} ", thread_name);
}
if (options.Test(LLDB_LOG_OPTION_BACKTRACE))
@@ -321,3 +328,11 @@ void Log::Format(llvm::StringRef file, llvm::StringRef function,
message << payload << "\n";
WriteMessage(message.str());
}
+
+void Log::DisableLoggingChild() {
+ // Disable logging by clearing out the atomic variable after forking -- if we
+ // forked while another thread held the channel mutex, we would deadlock when
+ // trying to write to the log.
+ for (auto &c: *g_channel_map)
+ c.second.m_channel.log_ptr.store(nullptr, std::memory_order_relaxed);
+}
diff --git a/source/Utility/Logging.cpp b/source/Utility/Logging.cpp
index 0bd6d6692e37d..c9a6ef1bd1eae 100644
--- a/source/Utility/Logging.cpp
+++ b/source/Utility/Logging.cpp
@@ -51,7 +51,7 @@ static constexpr Log::Category g_categories[] = {
static Log::Channel g_log_channel(g_categories, LIBLLDB_LOG_DEFAULT);
-void lldb_private::InitializeLog() {
+void lldb_private::InitializeLldbChannel() {
Log::Register("lldb", g_log_channel);
}
diff --git a/source/Utility/PPC64LE_DWARF_Registers.h b/source/Utility/PPC64LE_DWARF_Registers.h
new file mode 100644
index 0000000000000..1a7503790e5da
--- /dev/null
+++ b/source/Utility/PPC64LE_DWARF_Registers.h
@@ -0,0 +1,194 @@
+//===-- PPC64LE_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_PPC64LE_DWARF_Registers_h_
+#define utility_PPC64LE_DWARF_Registers_h_
+
+#include "lldb/lldb-private.h"
+
+namespace ppc64le_dwarf {
+
+enum {
+ dwarf_r0_ppc64le = 0,
+ dwarf_r1_ppc64le,
+ dwarf_r2_ppc64le,
+ dwarf_r3_ppc64le,
+ dwarf_r4_ppc64le,
+ dwarf_r5_ppc64le,
+ dwarf_r6_ppc64le,
+ dwarf_r7_ppc64le,
+ dwarf_r8_ppc64le,
+ dwarf_r9_ppc64le,
+ dwarf_r10_ppc64le,
+ dwarf_r11_ppc64le,
+ dwarf_r12_ppc64le,
+ dwarf_r13_ppc64le,
+ dwarf_r14_ppc64le,
+ dwarf_r15_ppc64le,
+ dwarf_r16_ppc64le,
+ dwarf_r17_ppc64le,
+ dwarf_r18_ppc64le,
+ dwarf_r19_ppc64le,
+ dwarf_r20_ppc64le,
+ dwarf_r21_ppc64le,
+ dwarf_r22_ppc64le,
+ dwarf_r23_ppc64le,
+ dwarf_r24_ppc64le,
+ dwarf_r25_ppc64le,
+ dwarf_r26_ppc64le,
+ dwarf_r27_ppc64le,
+ dwarf_r28_ppc64le,
+ dwarf_r29_ppc64le,
+ dwarf_r30_ppc64le,
+ dwarf_r31_ppc64le,
+ dwarf_f0_ppc64le,
+ dwarf_f1_ppc64le,
+ dwarf_f2_ppc64le,
+ dwarf_f3_ppc64le,
+ dwarf_f4_ppc64le,
+ dwarf_f5_ppc64le,
+ dwarf_f6_ppc64le,
+ dwarf_f7_ppc64le,
+ dwarf_f8_ppc64le,
+ dwarf_f9_ppc64le,
+ dwarf_f10_ppc64le,
+ dwarf_f11_ppc64le,
+ dwarf_f12_ppc64le,
+ dwarf_f13_ppc64le,
+ dwarf_f14_ppc64le,
+ dwarf_f15_ppc64le,
+ dwarf_f16_ppc64le,
+ dwarf_f17_ppc64le,
+ dwarf_f18_ppc64le,
+ dwarf_f19_ppc64le,
+ dwarf_f20_ppc64le,
+ dwarf_f21_ppc64le,
+ dwarf_f22_ppc64le,
+ dwarf_f23_ppc64le,
+ dwarf_f24_ppc64le,
+ dwarf_f25_ppc64le,
+ dwarf_f26_ppc64le,
+ dwarf_f27_ppc64le,
+ dwarf_f28_ppc64le,
+ dwarf_f29_ppc64le,
+ dwarf_f30_ppc64le,
+ dwarf_f31_ppc64le,
+ dwarf_lr_ppc64le = 65,
+ dwarf_ctr_ppc64le,
+ dwarf_cr_ppc64le = 68,
+ dwarf_xer_ppc64le = 76,
+ dwarf_vr0_ppc64le,
+ dwarf_vr1_ppc64le,
+ dwarf_vr2_ppc64le,
+ dwarf_vr3_ppc64le,
+ dwarf_vr4_ppc64le,
+ dwarf_vr5_ppc64le,
+ dwarf_vr6_ppc64le,
+ dwarf_vr7_ppc64le,
+ dwarf_vr8_ppc64le,
+ dwarf_vr9_ppc64le,
+ dwarf_vr10_ppc64le,
+ dwarf_vr11_ppc64le,
+ dwarf_vr12_ppc64le,
+ dwarf_vr13_ppc64le,
+ dwarf_vr14_ppc64le,
+ dwarf_vr15_ppc64le,
+ dwarf_vr16_ppc64le,
+ dwarf_vr17_ppc64le,
+ dwarf_vr18_ppc64le,
+ dwarf_vr19_ppc64le,
+ dwarf_vr20_ppc64le,
+ dwarf_vr21_ppc64le,
+ dwarf_vr22_ppc64le,
+ dwarf_vr23_ppc64le,
+ dwarf_vr24_ppc64le,
+ dwarf_vr25_ppc64le,
+ dwarf_vr26_ppc64le,
+ dwarf_vr27_ppc64le,
+ dwarf_vr28_ppc64le,
+ dwarf_vr29_ppc64le,
+ dwarf_vr30_ppc64le,
+ dwarf_vr31_ppc64le,
+ dwarf_vscr_ppc64le = 110,
+ dwarf_vrsave_ppc64le = 117,
+ dwarf_pc_ppc64le,
+ dwarf_softe_ppc64le,
+ dwarf_trap_ppc64le,
+ dwarf_origr3_ppc64le,
+ dwarf_fpscr_ppc64le,
+ dwarf_msr_ppc64le,
+ dwarf_vs0_ppc64le,
+ dwarf_vs1_ppc64le,
+ dwarf_vs2_ppc64le,
+ dwarf_vs3_ppc64le,
+ dwarf_vs4_ppc64le,
+ dwarf_vs5_ppc64le,
+ dwarf_vs6_ppc64le,
+ dwarf_vs7_ppc64le,
+ dwarf_vs8_ppc64le,
+ dwarf_vs9_ppc64le,
+ dwarf_vs10_ppc64le,
+ dwarf_vs11_ppc64le,
+ dwarf_vs12_ppc64le,
+ dwarf_vs13_ppc64le,
+ dwarf_vs14_ppc64le,
+ dwarf_vs15_ppc64le,
+ dwarf_vs16_ppc64le,
+ dwarf_vs17_ppc64le,
+ dwarf_vs18_ppc64le,
+ dwarf_vs19_ppc64le,
+ dwarf_vs20_ppc64le,
+ dwarf_vs21_ppc64le,
+ dwarf_vs22_ppc64le,
+ dwarf_vs23_ppc64le,
+ dwarf_vs24_ppc64le,
+ dwarf_vs25_ppc64le,
+ dwarf_vs26_ppc64le,
+ dwarf_vs27_ppc64le,
+ dwarf_vs28_ppc64le,
+ dwarf_vs29_ppc64le,
+ dwarf_vs30_ppc64le,
+ dwarf_vs31_ppc64le,
+ dwarf_vs32_ppc64le,
+ dwarf_vs33_ppc64le,
+ dwarf_vs34_ppc64le,
+ dwarf_vs35_ppc64le,
+ dwarf_vs36_ppc64le,
+ dwarf_vs37_ppc64le,
+ dwarf_vs38_ppc64le,
+ dwarf_vs39_ppc64le,
+ dwarf_vs40_ppc64le,
+ dwarf_vs41_ppc64le,
+ dwarf_vs42_ppc64le,
+ dwarf_vs43_ppc64le,
+ dwarf_vs44_ppc64le,
+ dwarf_vs45_ppc64le,
+ dwarf_vs46_ppc64le,
+ dwarf_vs47_ppc64le,
+ dwarf_vs48_ppc64le,
+ dwarf_vs49_ppc64le,
+ dwarf_vs50_ppc64le,
+ dwarf_vs51_ppc64le,
+ dwarf_vs52_ppc64le,
+ dwarf_vs53_ppc64le,
+ dwarf_vs54_ppc64le,
+ dwarf_vs55_ppc64le,
+ dwarf_vs56_ppc64le,
+ dwarf_vs57_ppc64le,
+ dwarf_vs58_ppc64le,
+ dwarf_vs59_ppc64le,
+ dwarf_vs60_ppc64le,
+ dwarf_vs61_ppc64le,
+ dwarf_vs62_ppc64le,
+ dwarf_vs63_ppc64le,
+};
+
+} // namespace ppc64le_dwarf
+
+#endif // utility_PPC64LE_DWARF_Registers_h_
diff --git a/source/Utility/PPC64LE_ehframe_Registers.h b/source/Utility/PPC64LE_ehframe_Registers.h
new file mode 100644
index 0000000000000..c5763b3047117
--- /dev/null
+++ b/source/Utility/PPC64LE_ehframe_Registers.h
@@ -0,0 +1,194 @@
+//===-- PPC64LE_ehframe_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_PPC64LE_ehframe_Registers_h_
+#define utility_PPC64LE_ehframe_Registers_h_
+
+// The register numbers used in the eh_frame unwind information.
+// Should be the same as DWARF register numbers.
+
+namespace ppc64le_ehframe {
+
+enum {
+ r0 = 0,
+ r1,
+ r2,
+ r3,
+ r4,
+ r5,
+ r6,
+ r7,
+ r8,
+ r9,
+ r10,
+ r11,
+ r12,
+ r13,
+ r14,
+ r15,
+ r16,
+ r17,
+ r18,
+ r19,
+ r20,
+ r21,
+ r22,
+ r23,
+ r24,
+ r25,
+ r26,
+ r27,
+ r28,
+ r29,
+ r30,
+ r31,
+ f0,
+ f1,
+ f2,
+ f3,
+ f4,
+ f5,
+ f6,
+ f7,
+ f8,
+ f9,
+ f10,
+ f11,
+ f12,
+ f13,
+ f14,
+ f15,
+ f16,
+ f17,
+ f18,
+ f19,
+ f20,
+ f21,
+ f22,
+ f23,
+ f24,
+ f25,
+ f26,
+ f27,
+ f28,
+ f29,
+ f30,
+ f31,
+ lr = 65,
+ ctr,
+ cr = 68,
+ xer = 76,
+ vr0,
+ vr1,
+ vr2,
+ vr3,
+ vr4,
+ vr5,
+ vr6,
+ vr7,
+ vr8,
+ vr9,
+ vr10,
+ vr11,
+ vr12,
+ vr13,
+ vr14,
+ vr15,
+ vr16,
+ vr17,
+ vr18,
+ vr19,
+ vr20,
+ vr21,
+ vr22,
+ vr23,
+ vr24,
+ vr25,
+ vr26,
+ vr27,
+ vr28,
+ vr29,
+ vr30,
+ vr31,
+ vscr = 110,
+ vrsave = 117,
+ pc,
+ softe,
+ trap,
+ origr3,
+ fpscr,
+ msr,
+ vs0,
+ vs1,
+ vs2,
+ vs3,
+ vs4,
+ vs5,
+ vs6,
+ vs7,
+ vs8,
+ vs9,
+ vs10,
+ vs11,
+ vs12,
+ vs13,
+ vs14,
+ vs15,
+ vs16,
+ vs17,
+ vs18,
+ vs19,
+ vs20,
+ vs21,
+ vs22,
+ vs23,
+ vs24,
+ vs25,
+ vs26,
+ vs27,
+ vs28,
+ vs29,
+ vs30,
+ vs31,
+ vs32,
+ vs33,
+ vs34,
+ vs35,
+ vs36,
+ vs37,
+ vs38,
+ vs39,
+ vs40,
+ vs41,
+ vs42,
+ vs43,
+ vs44,
+ vs45,
+ vs46,
+ vs47,
+ vs48,
+ vs49,
+ vs50,
+ vs51,
+ vs52,
+ vs53,
+ vs54,
+ vs55,
+ vs56,
+ vs57,
+ vs58,
+ vs59,
+ vs60,
+ vs61,
+ vs62,
+ vs63,
+};
+}
+
+#endif // utility_PPC64LE_ehframe_Registers_h_
diff --git a/source/Utility/SelectHelper.cpp b/source/Utility/SelectHelper.cpp
index a46213f8bfcb8..200b2ae42759b 100644
--- a/source/Utility/SelectHelper.cpp
+++ b/source/Utility/SelectHelper.cpp
@@ -32,6 +32,7 @@
#define NOMINMAX
#include <winsock2.h>
#else
+#include <sys/time.h>
#include <sys/select.h>
#endif
diff --git a/source/Utility/Status.cpp b/source/Utility/Status.cpp
index b11a3db64e6d2..a6a889a71e548 100644
--- a/source/Utility/Status.cpp
+++ b/source/Utility/Status.cpp
@@ -104,16 +104,6 @@ const Status &Status::operator=(const Status &rhs) {
return *this;
}
-//----------------------------------------------------------------------
-// Assignment operator
-//----------------------------------------------------------------------
-const Status &Status::operator=(uint32_t err) {
- m_code = err;
- m_type = eErrorTypeMachKernel;
- m_string.clear();
- return *this;
-}
-
Status::~Status() = default;
//----------------------------------------------------------------------
diff --git a/source/Utility/StringExtractorGDBRemote.cpp b/source/Utility/StringExtractorGDBRemote.cpp
index 8e50c0106a487..818347a42a2cb 100644
--- a/source/Utility/StringExtractorGDBRemote.cpp
+++ b/source/Utility/StringExtractorGDBRemote.cpp
@@ -103,6 +103,7 @@ StringExtractorGDBRemote::GetServerPacketType() const {
case 'P':
if (PACKET_STARTS_WITH("QPassSignals:"))
return eServerPacketType_QPassSignals;
+ break;
case 'S':
if (PACKET_MATCHES("QStartNoAckMode"))
diff --git a/source/Utility/StructuredData.cpp b/source/Utility/StructuredData.cpp
index 9fc05354cfd3f..492fc585ad07f 100644
--- a/source/Utility/StructuredData.cpp
+++ b/source/Utility/StructuredData.cpp
@@ -15,6 +15,7 @@
#include "lldb/Utility/Stream.h" // for Stream
#include "lldb/Utility/StreamString.h"
#include "llvm/ADT/STLExtras.h" // for make_unique
+#include "llvm/Support/MemoryBuffer.h"
#include <cerrno>
#include <cstdlib>
#include <inttypes.h>
diff --git a/source/Utility/UUID.cpp b/source/Utility/UUID.cpp
index b47f8b52f1c24..98d4c30cc7f11 100644
--- a/source/Utility/UUID.cpp
+++ b/source/Utility/UUID.cpp
@@ -21,11 +21,10 @@
namespace lldb_private {
-UUID::UUID() : m_num_uuid_bytes(16) { ::memset(m_uuid, 0, sizeof(m_uuid)); }
+UUID::UUID() { Clear(); }
UUID::UUID(const UUID &rhs) {
- m_num_uuid_bytes = rhs.m_num_uuid_bytes;
- ::memcpy(m_uuid, rhs.m_uuid, sizeof(m_uuid));
+ SetBytes(rhs.m_uuid, rhs.m_num_uuid_bytes);
}
UUID::UUID(const void *uuid_bytes, uint32_t num_uuid_bytes) {
@@ -74,14 +73,7 @@ std::string UUID::GetAsString(const char *separator) const {
}
void UUID::Dump(Stream *s) const {
- const uint8_t *u = (const uint8_t *)GetBytes();
- s->Printf("%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",
- 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]);
- if (m_num_uuid_bytes == 20) {
- s->Printf("-%2.2X%2.2X%2.2X%2.2X", u[16], u[17], u[18], u[19]);
- }
+ s->PutCString(GetAsString().c_str());
}
bool UUID::SetBytes(const void *uuid_bytes, uint32_t num_uuid_bytes) {
@@ -109,7 +101,7 @@ bool UUID::SetBytes(const void *uuid_bytes, uint32_t num_uuid_bytes) {
return false;
}
-size_t UUID::GetByteSize() { return m_num_uuid_bytes; }
+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] ||
@@ -198,8 +190,7 @@ bool lldb_private::operator==(const lldb_private::UUID &lhs,
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;
+ return !(lhs == rhs);
}
bool lldb_private::operator<(const lldb_private::UUID &lhs,
@@ -210,18 +201,15 @@ bool lldb_private::operator<(const lldb_private::UUID &lhs,
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;
+ 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;
+ return rhs < lhs;
}
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;
+ return !(lhs < rhs);
}
diff --git a/source/Utility/UriParser.cpp b/source/Utility/UriParser.cpp
index bb57211af4687..a6d81e7a2c8b8 100644
--- a/source/Utility/UriParser.cpp
+++ b/source/Utility/UriParser.cpp
@@ -22,7 +22,7 @@ using namespace lldb_private;
bool UriParser::Parse(llvm::StringRef uri, llvm::StringRef &scheme,
llvm::StringRef &hostname, int &port,
llvm::StringRef &path) {
- llvm::StringRef tmp_scheme, tmp_hostname, tmp_port, tmp_path;
+ llvm::StringRef tmp_scheme, tmp_hostname, tmp_path;
const llvm::StringRef kSchemeSep("://");
auto pos = uri.find(kSchemeSep);
@@ -43,7 +43,7 @@ bool UriParser::Parse(llvm::StringRef uri, llvm::StringRef &scheme,
((path_pos != std::string::npos) ? path_pos : uri.size()) - host_pos);
// Extract hostname
- if (host_port[0] == '[') {
+ if (!host_port.empty() && host_port[0] == '[') {
// hostname is enclosed with square brackets.
pos = host_port.find(']');
if (pos == std::string::npos)
diff --git a/source/lldb.cpp b/source/lldb.cpp
index efdcef8f0527a..1be0461977700 100644
--- a/source/lldb.cpp
+++ b/source/lldb.cpp
@@ -15,11 +15,11 @@ using namespace lldb_private;
#include "clang/Basic/Version.h"
#ifdef HAVE_SVN_VERSION_INC
-# include "SVNVersion.inc"
+#include "SVNVersion.inc"
#endif
#ifdef HAVE_APPLE_VERSION_INC
-# include "AppleVersion.inc"
+#include "AppleVersion.inc"
#endif
static const char *GetLLDBRevision() {
@@ -38,7 +38,6 @@ static const char *GetLLDBRepository() {
#endif
}
-
#define QUOTE(str) #str
#define EXPAND_AND_QUOTE(str) QUOTE(str)
@@ -47,13 +46,9 @@ const char *lldb_private::GetVersion() {
// as the clang tool.
static std::string g_version_str;
if (g_version_str.empty()) {
-
-#ifdef LLDB_VERSION_STRING
- g_version_str += EXPAND_AND_QUOTE(LLDB_VERSION_STRING);
-#else
g_version_str += "lldb version ";
g_version_str += CLANG_VERSION_STRING;
-#endif
+
const char *lldb_repo = GetLLDBRepository();
const char *lldb_rev = GetLLDBRevision();
if (lldb_repo || lldb_rev) {
@@ -77,7 +72,6 @@ const char *lldb_private::GetVersion() {
g_version_str += "\n llvm revision ";
g_version_str += llvm_rev;
}
-
}
return g_version_str.c_str();
}